This is the Kotlin Flow version of rx-preferences. It follows pretty much the same API and should feel familiar to anyone with experience there. But instead of RxJava, we have Coroutines -- mainly Flows.
repositories {
mavenCentral()
}
dependencies {
implementation 'com.fredporciuncula:flow-preferences:1.8.0'
}
Start with the regular SharedPreferences
:
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
Create an instance of FlowSharedPreferences
from that:
val flowSharedPreferences = FlowSharedPreferences(sharedPreferences)
Get a preference:
val myPref = flowSharedPreferences.getInt("key", defaultValue = 10)
Go with the Flow:
myPref.asFlow().onEach { print(it) }.launchIn(scope)
Preferences expose the regular get()
and put()
(named as set()
) functions from SharedPreferences
.
But in addition to that, they also expose the suspend
setAndCommit()
function that puts the value and performs a
commit in case you must ensure the preference is persisted right away. There's also a deleteAndCommit()
.
You can call asCollector()
to ask a
FlowCollector
from a preference. You can then persist values from a Flow directly to the preference:
val flow = flow { emit(1) }
scope.launch {
myPref.asCollector().emitAll(flow)
}
You can use asSyncCollector()
if you want to put and commit the value (like setAndCommit()
) on each emission.
Enum classes work out of the box and are persisted as strings based on their name
value (so make sure you @Keep
them
if you're using R8):
enum class MyEnum { A, B, C }
val myPref = flowSharedPreferences.getEnum("key", defaultValue = MyEnum.A)
Arbitrary objects are also supported as long as an instance of ObjectPreference.Serializer
is provided:
class TestObject(val id: Int)
val serializer =
object : ObjectPreference.Serializer<TestObject> {
override fun deserialize(serialized: String) = TestObject(serialized.toInt())
override fun serialize(value: TestObject) = value.id.toString()
}
val myPref = flowSharedPreferences.getObject("key", serializer, defaultValue = TestObject(0))
By default, strings, objects, enums and sets can never be null
, so consumers don't ever have to worry about
null
checks. If you want to support nullable values, you can explicitly opt in by asking for the
nullable-friendly preference types:
val nullableStringPreference = flowSharedPreferences.getNullableString("key", defaultValue = null)