Introduction
You may come across a requirement in your app to store some configuration (not that big to use Room).
For example, the previous UI mode - (Dark/Light)
You might come across Shared Preferences for this requirement. Shared Preferences are used to persist data of key-value pairs.
I agree that shared preferences work fine but are still way too old. Imagine if you want to observe the live changes of a preference value. you can't.
DataStore
DataStore is a part of Jetpack libraries that lets you store data of key-value pairs or typed objects in the device.
Types
In this guide, we will learn about the Preferences DataStore.
Proto DataStore is for another day.
Why you should use DataStore instead of Shared Preferences?

Guide
Setup
Add the datastore preference in your grade dependency
dependencies {
implementation "androidx.datastore:datastore:1.0.0"
}
Build DataStore
Create a preference data store as an extension of context using the preferencesDataStore delegate in the top level of a Kotlin file.
The name of the Preferences DataStore is a mandatory parameter.
This ensures that a single instance of DataStore is created for the application process.
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "configs")
Create Preference Keys
To store key-value pairs, we have to create keys for the preferences.
object PreferenceKeys {
val booleanKey = booleanPreferencesKey(name = "key_for_bool_value")
val byteArrayKey = byteArrayPreferencesKey(name = "key_for_byte_array_value")
val doubleKey = doublePreferencesKey(name = "key_for_double_value")
val floatKey = floatPreferencesKey(name = "key_for_float_value")
val intKey = intPreferencesKey(name = "key_for_int_value")
val longKey = longPreferencesKey(name = "key_for_long_value")
val stringKey = stringPreferencesKey(name = "key_for_string_value")
val stringSetKey = stringSetPreferencesKey("key_for_string_set_value")
}
Write data
Write a value to the preferences with the following code.
suspend fun writeValue(key: Preferences.Key<Int>, value: Int) {
context.dataStore.edit { preferences ->
preferences[key] = value
}
}
Write a value from a fragment or activity
lifeCycleScope.launch {
writeValue(key = intKey, value = 17)
}
Read data
Read value from the preferences with the following code.
It returns a Flow.
fun readValue(key: Preferences.Key<Int>, defaultValue: Int): Flow<Int> {
return context.dataStore.data.map { preferences ->
preferences[key] ?: defValue
}
}
Collect the value from the Flow
lifeCycleScope.launch {
readValue(key = intKey, defaultValue = 0).collect { value ->
}
}
Bonus
Extension function to work with all types of keys.
fun <T> DataStore<Preferences>.getValue(
key: Preferences.Key<T>,
defValue: T
): Flow<T> {
return data.map { preferences ->
preferences[key] ?: defValue
}
}
suspend fun <T> DataStore<Preferences>.setValue(
key: Preferences.Key<T>,
value: T
) {
edit { preferences ->
preferences[key] = value
}
}
That's it for today.
Please do like if it helped you.
Comment if you have any queries.
Share if you want to help others.
For more articles like this, Do follow.
Thanks for reading. <3