-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathSharedPreferenceProperty.kt
49 lines (42 loc) · 1.74 KB
/
SharedPreferenceProperty.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package net.aquadc.persistence.android.pref
import android.content.SharedPreferences
import net.aquadc.persistence.type.DataType
import net.aquadc.properties.TransactionalProperty
import net.aquadc.properties.internal.`Notifier-1AtomicRef`
/**
* Wraps a value from [SharedPreferences].
* Note that [SharedPreferences.OnSharedPreferenceChangeListener.onSharedPreferenceChanged] is called on main thread
*/
class SharedPreferenceProperty<T>(
private val prefs: SharedPreferences,
private val key: String,
private val defaultValue: T,
private val type: DataType<T>
) : `Notifier-1AtomicRef`<T, T>(
concurrent = true,
initialRef = type.get(prefs, key, defaultValue)
), TransactionalProperty<SharedPreferences.Editor, T> {
// we need a strong reference because shared prefs holding a weak one
private val changeListener = SharedPreferences.OnSharedPreferenceChangeListener { _, key -> changed(key) }
init {
prefs.registerOnSharedPreferenceChangeListener(changeListener)
}
@Suppress("MemberVisibilityCanBePrivate") // internal — to avoid synthetic accessors
internal fun changed(key: String) {
if (this.key == key) {
val new = type.get(prefs, this.key, defaultValue)
val old = refUpdater().getAndSet(this, new)
valueChanged(old, new, null)
}
}
override var value: T
get() = ref
set(newValue) {
val ed = prefs.edit()
type.put(ed, key, newValue)
ed.apply() // and wait until onSharedPreferenceChanged comes
}
override fun setValue(transaction: SharedPreferences.Editor, value: T) {
type.put(transaction, key, value) // and pray that this one is ours...
}
}