tezvyn:

Preferences DataStore: The Safe SharedPreferences

AI-drafted, machine-checkedSource: developer.android.combeginner
Preferences DataStore: The Safe SharedPreferences

Preferences DataStore is Android's modern way to save simple key-value data. It uses Kotlin's Flow to read data asynchronously, preventing UI freezes. Use it for user settings, but remember you can't read values synchronously like with SharedPreferences.

WHY IT EXISTS Android's original key-value storage, SharedPreferences, had critical flaws. Its API allowed synchronous I/O on the main thread, a common cause of app freezes (ANRs). It also lacked a way to safely know when a value changed. Preferences DataStore was created to solve these problems with a modern, safe API.

THE MENTAL MODEL Think of Preferences DataStore as an asynchronous version of SharedPreferences. Instead of directly fetching a value and blocking your code, you subscribe to a stream of data (a Kotlin Flow). You get the current value and any future updates automatically. Writing data is a non-blocking 'fire and forget' operation managed in the background.

HOW IT WORKS Preferences DataStore stores data in a file on the device. All read and write operations are executed on a background thread using Kotlin Coroutines. Data is exposed as a Flow<Preferences>, which emits the latest state of all preferences whenever a value changes. To write data, you use a suspending edit() function within a coroutine scope. This guarantees that I/O never touches the main thread. Keys are also type-safe, preventing you from writing an integer into a key defined for a string.

WHEN TO USE IT Use Preferences DataStore for small, simple data sets. It is ideal for storing user settings, like a dark mode toggle, notification preferences, or a flag indicating whether a user has seen the onboarding tour. It's the go-to solution for simple key-value persistence.

WHEN NOT TO USE IT Do not use Preferences DataStore for large or complex data, data that requires partial updates, or data with relational integrity. For those cases, Android provides Proto DataStore (for type-safe, structured objects) or the Room library (for a full SQL database).

ONE CANONICAL EXAMPLE A common use case is storing a user's authentication token. You define a type-safe key, like val AUTH_TOKEN = stringPreferencesKey("auth_token"). You read the token by collecting a Flow: dataStore.data.map { prefs -> prefs[AUTH_TOKEN] }. You save a new token after login with a suspend function: dataStore.edit { prefs -> prefs[AUTH_TOKEN] = "new_token_here" }.

Read the original → developer.android.com

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.