By looking the document, DataStore, I have the setup
build.gradle.kts
implementation ("androidx.datastore:datastore-preferences:1.0.0")
MainActivity.kt
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
val MY_COUNTER_1 = intPreferencesKey("my_counter_1")
val MY_COUNTER_2 = intPreferencesKey("my_counter_2")
lifecycleScope.launch {
dataStore.data
.map { currentPreferences ->
// Unlike Proto DataStore, there's no type safety here.
currentPreferences[MY_COUNTER_1] ?: 0
}.collect {
Log.d("MainActivity", "Counter 1: $it")
}
}
lifecycleScope.launch {
dataStore.data
.map { currentPreferences ->
// Unlike Proto DataStore, there's no type safety here.
currentPreferences[MY_COUNTER_2] ?: 0
}.collect {
Log.d("MainActivity", "Counter 2: $it")
}
}
lifecycleScope.launch {
while (true) {
dataStore.edit { currentPreferences ->
val currentCounterValue = currentPreferences[MY_COUNTER_2] ?: 0
currentPreferences[MY_COUNTER_2] = currentCounterValue + 1
}
delay(3000)
}
}
I found that when MY_COUNTER_2
is written with new values, MY_COUNTER_1
read is also triggered. I expected to see MY_COUNTER_2
read only, do I mis-config my DataStore?
What the documentation says about the data
function:
val data: Flow
Provides [...] access to the latest durably persisted state.
Returns a flow representing the current state of the data
This sounds like the Flow
will emit a new value whenever any value in the DataStore
changes. The newly emitted value will be an object that holds all current preferences that are stored in the DataStore
. You then filter the desired preference by its key, and collect
will always process the value, even if the value actually has not changed.
If you want to collect
the value of a specific preference only if it actually changes, try out the distinctUntilChanged
function:
dataStore.data
.map { currentPreferences ->
currentPreferences[MY_COUNTER_1] ?: 0
}.distinctUntilChanged().collect {
Log.d("MainActivity", "Counter 1: $it")
}