How to Use DataStore in Android with Kotlin
Use
DataStore in Android Kotlin by creating a DataStore instance with a serializer, then read and write data using Kotlin coroutines. It replaces SharedPreferences with a safer, asynchronous API for storing key-value pairs or typed objects.Syntax
DataStore in Android Kotlin uses two main types: Preferences DataStore for key-value pairs and Proto DataStore for typed objects. You create a DataStore instance, then use data to read and edit to write data asynchronously.
val dataStore = context.createDataStore(name = "settings")- creates a Preferences DataStore.val valueFlow = dataStore.data.map { preferences -> preferences[key] ?: default }- reads data as a Flow.dataStore.edit { preferences -> preferences[key] = value }- writes data.
kotlin
val Context.dataStore by preferencesDataStore(name = "settings") val EXAMPLE_KEY = stringPreferencesKey("example_key") suspend fun saveExample(context: Context, value: String) { context.dataStore.edit { preferences -> preferences[EXAMPLE_KEY] = value } } val exampleFlow: Flow<String> = context.dataStore.data .map { preferences -> preferences[EXAMPLE_KEY] ?: "default" }
Example
This example shows how to save and read a string value using Preferences DataStore in an Android Kotlin app. It demonstrates creating the DataStore, saving a value, and observing changes with a Flow.
kotlin
import android.content.Context import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.preferencesDataStore import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map val Context.dataStore by preferencesDataStore(name = "settings") val USERNAME_KEY = stringPreferencesKey("username") suspend fun saveUsername(context: Context, username: String) { context.dataStore.edit { preferences -> preferences[USERNAME_KEY] = username } } fun getUsernameFlow(context: Context): Flow<String> = context.dataStore.data .map { preferences -> preferences[USERNAME_KEY] ?: "Guest" }
Output
When saveUsername is called with "Alice", getUsernameFlow emits "Alice"; before saving, it emits "Guest".
Common Pitfalls
- Not using Kotlin coroutines or Flow to read/write data causes blocking or errors.
- Forgetting to use
editinside a suspend function to write data. - Trying to access DataStore from the main thread without coroutines.
- Using incorrect keys or not initializing DataStore properly.
kotlin
/* Wrong: Writing data without suspend or edit */ fun wrongSave(context: Context, value: String) { // This will not compile or block main thread // context.dataStore.edit { preferences -> // preferences[EXAMPLE_KEY] = value // } } /* Right: Use suspend function */ suspend fun rightSave(context: Context, value: String) { context.dataStore.edit { preferences -> preferences[EXAMPLE_KEY] = value } }
Quick Reference
Remember these key points when using DataStore in Android Kotlin:
- Use
preferencesDataStoredelegate to create DataStore instance. - Use
editsuspend function to write data. - Use
dataFlow to read data asynchronously. - Always use keys like
stringPreferencesKeyto access values.
Key Takeaways
Use DataStore with Kotlin coroutines for safe, asynchronous data storage.
Create DataStore instance with preferencesDataStore delegate and keys with stringPreferencesKey or similar.
Read data as a Flow and write data inside suspend functions using edit.
Avoid blocking the main thread by never accessing DataStore synchronously.
DataStore replaces SharedPreferences with a modern, efficient API.