DataStore


DataStore provides a safe and durable way to store small amounts of data, such as preferences and application state. It does not support partial updates: if any field is modified, the whole object will be serialized and persisted to disk. If you want partial updates, consider the Room API (SQLite).

DataStore provides ACID guarantees. It is thread-safe, and non-blocking. In particular, it addresses these design shortcomings of the SharedPreferences API:

  1. Synchronous API encourages StrictMode violations

  2. apply() and commit() have no mechanism of signalling errors

  3. apply() will block the UI thread on fsync()

  4. Not durable – it can returns state that is not yet persisted

  5. No consistency or transactional semantics

  6. Throws runtime exception on parsing errors

  7. Exposes mutable references to its internal state

Summary

Public functions

suspend T
updateData(transform: suspend (t) -> T)

Updates the data transactionally in an atomic read-modify-write operation.

Cmn

Public properties

Flow<T>

Provides efficient, cached (when possible) access to the latest durably persisted state.

Cmn

Extension functions

suspend Preferences
DataStore<Preferences>.edit(
    transform: suspend (MutablePreferences) -> Unit
)

Edit the value in DataStore transactionally in an atomic read-modify-write operation.

Cmn

Public functions

updateData

suspend fun updateData(transform: suspend (t) -> T): T

Updates the data transactionally in an atomic read-modify-write operation. All operations are serialized, and the transform itself is a coroutine so it can perform heavy work such as RPCs.

The coroutine completes when the data has been persisted durably to disk (after which data will reflect the update). If the transform or write to disk fails, the transaction is aborted and an exception is thrown.

Returns
T

the snapshot returned by the transform

Throws
androidx.datastore.core.IOException

when an exception is encountered when writing data to disk

kotlin.Exception

when thrown by the transform function

Public properties

data

val dataFlow<T>

Provides efficient, cached (when possible) access to the latest durably persisted state. The flow will always either emit a value or throw an exception encountered when attempting to read from disk. If an exception is encountered, collecting again will attempt to read the data again.

Do not layer a cache on top of this API: it will be be impossible to guarantee consistency. Instead, use data.first() to access a single snapshot.

Returns
Flow<T>

a flow representing the current state of the data

Throws
androidx.datastore.core.IOException

when an exception is encountered when reading data

Extension functions

suspend fun DataStore<Preferences>.edit(
    transform: suspend (MutablePreferences) -> Unit
): Preferences

Edit the value in DataStore transactionally in an atomic read-modify-write operation. All operations are serialized.

The coroutine completes when the data has been persisted durably to disk (after which DataStore.data will reflect the update). If the transform or write to disk fails, the transaction is aborted and an exception is thrown.

Note: values that are changed in transform are NOT updated in DataStore until after the transform completes. Do not assume that the data has been successfully persisted until after edit returns successfully.

Note: do NOT store a reference to the MutablePreferences provided to transform. Mutating this after transform returns will NOT change the data in DataStore. Future versions of this may throw exceptions if the MutablePreferences object is mutated outside of transform.

See DataStore.updateData.

Example usage: val COUNTER_KEY = intPreferencesKey("my_counter")

dataStore.edit { prefs -> prefs\[COUNTER_KEY\] = prefs\[COUNTER_KEY\] :? 0 + 1 }

Parameters
transform: suspend (MutablePreferences) -> Unit

block which accepts MutablePreferences that contains all the preferences currently in DataStore. Changes to this MutablePreferences object will be persisted once transform completes.

Throws
androidx.datastore.core.IOException

when an exception is encountered when writing data to disk

kotlin.Exception

when thrown by the transform block