Preferences

Android provides two different ways to save preferences:

  • Preferences DataStore - uses key-value pairs.
  • Proto DataStore - stores data as instances of a custom data type.

They are using kotlin flows and work asynchronously.

Preferences DataStore

1. Add gradle dependency

// Preferences DataStore (SharedPreferences like APIs)
    dependencies {
        implementation "androidx.datastore:datastore-preferences:1.0.0"

        // optional - RxJava2 support
        implementation "androidx.datastore:datastore-preferences-rxjava2:1.0.0"

        // optional - RxJava3 support
        implementation "androidx.datastore:datastore-preferences-rxjava3:1.0.0"
    }

    // Alternatively - use the following artifact without an Android dependency.
    // You must manually add Proguard rules to your proguard-rules.pro file 
    // to keep your fields from being deleted.
    dependencies {
        implementation "androidx.datastore:datastore-preferences-core:1.0.0"
    }

2. Create extension field for the android Context class, for example "dataStore" at the top level of your kotlin file:

 // Let the name of the datastore file be "settings".
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")

3. You can use the following functions to create keys to access data. You can also define keys in a companion object.

val myStrKey = preferencesKey<String>("myStrKey")
val myStrKey = stringPreferencesKey("myStrKey")
val myLongKey = longPreferencesKey("myLongKey")
val myIntKey = intPreferencesKey("myIntKey")

4. Read data like this

val EXAMPLE_COUNTER = intPreferencesKey("example_counter")
val exampleCounterFlow: Flow<Int> = context.dataStore.data
  .map { preferences ->
    preferences[EXAMPLE_COUNTER] ?: 0  // No type safety.
}

5. Write data like this

suspend fun incrementCounter() {
  context.dataStore.edit { settings ->
    val currentCounterValue = settings[EXAMPLE_COUNTER] ?: 0
    settings[EXAMPLE_COUNTER] = currentCounterValue + 1
  }
}
Preferences DataStore example