0Pricing
Android Academy · Lesson

Preferences DataStore

Store key-value settings reactively.

Preferences DataStore is a free Android Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Android Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Preferences DataStore

Preferences DataStore stores simple key-value pairs, just like SharedPreferences, but with the modern async API. It does not enforce a schema or type-safety on the whole object.

You access values through typed keys.

Creating the DataStore

You create a single DataStore instance per file using the preferencesDataStore property delegate at the top level of a Kotlin file. The name becomes the on-disk filename.

import androidx.datastore.preferences.preferencesDataStore
import androidx.datastore.preferences.core.Preferences

val Context.dataStore: DataStore<Preferences> by
    preferencesDataStore(name = "settings")

Why a Top-Level Delegate

The delegate ensures there is exactly one DataStore instance for that file name in your process. Creating two for the same file throws an error, because they would fight over the same data.

Declaring it as a top-level Context extension keeps it a singleton.

Preference Keys

Each value needs a typed key. The key both names the entry and pins its type. Helper functions create keys for each supported type.

import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.intPreferencesKey

val USERNAME = stringPreferencesKey("username")
val DARK_MODE = booleanPreferencesKey("dark_mode")
val LAUNCH_COUNT = intPreferencesKey("launch_count")

Supported Key Types

Preferences DataStore supports these primitive key types:

  • stringPreferencesKey
  • booleanPreferencesKey
  • intPreferencesKey, longPreferencesKey, floatPreferencesKey, doublePreferencesKey
  • stringSetPreferencesKey

Define Keys in One Place

A common pattern is to gather all keys into an object so they are easy to find and reuse, avoiding typos in the string names.

object PrefKeys {
    val USERNAME = stringPreferencesKey("username")
    val DARK_MODE = booleanPreferencesKey("dark_mode")
    val FONT_SIZE = intPreferencesKey("font_size")
}

String Keys vs Variable Names

Keep in mind the string argument (e.g. "dark_mode") is what is written to disk. If you rename it later, old values become unreachable. The Kotlin val name is just for your code.

One DataStore per Concern

You can create multiple DataStores for different concerns, each with its own file name, for example a "settings" store and a "user_session" store. Keep related keys together.

val Context.settingsStore by preferencesDataStore(name = "settings")
val Context.sessionStore by preferencesDataStore(name = "session")

Accessing From the UI Layer

Although the delegate hangs off Context, do not read it directly in Composables. Inject the DataStore into a repository, then expose flows to a ViewModel. This keeps the UI testable.

A Simple Repository Shape

Wrapping DataStore in a repository class gives you a clean API and a single place to define keys and mapping logic.

class SettingsRepository(private val dataStore: DataStore<Preferences>) {
    val darkMode: Flow<Boolean> = dataStore.data
        .map { it[PrefKeys.DARK_MODE] ?: false }
}

Default Values

A key may not exist yet, so reads return null. Always provide a default with the Elvis operator ?: when mapping a preference value.

val fontSize: Flow<Int> = dataStore.data
    .map { prefs -> prefs[PrefKeys.FONT_SIZE] ?: 14 }

Quick Check

Test your understanding of preference keys.

Recap

You set up Preferences DataStore:

  • Create one instance via the top-level preferencesDataStore delegate
  • Define typed keys with stringPreferencesKey, booleanPreferencesKey, etc.
  • Gather keys in an object and wrap access in a repository
  • Always supply defaults for missing keys

Next: actually reading and writing those settings.

Frequently asked questions

Is the “Preferences DataStore” lesson free?

Yes — the full text of “Preferences DataStore” is free to read here on the web, and the Android Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Android Academy course, upgrade to CoddyKit PRO.

What will I learn in “Preferences DataStore”?

Store key-value settings reactively. You practise Android Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Android Academy?

No prior experience is required. Android Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Preferences DataStore” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Android Academy lesson?

Yes. Every Android Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. DataStore vs SharedPreferences
  2. Preferences DataStore
  3. Reading and Writing Settings
  4. Proto DataStore
← Back to Android Academy