DataStore: wat is het, basisprincipes van gegevensopslag en vervanging van SharedPreferences

Auteur: IT Sectr Gepubliceerd: 2026-03-12 Leestijd: 9 min

DataStore — een component uit de Jetpack-bibliotheek bedoeld voor het opslaan van kleine hoeveelheden gegevens in Android-applicaties. In tegenstelling tot SharedPreferences werkt het asynchroon en garandeert het gegevensconsistentie bij gelijktijdige toegang. Volgens Google, 2024 gebruikt DataStore Kotlin Coroutines en Flow, wat het veilig maakt voor de hoofdthread en geschikt voor reactieve architecturen.

Belangrijkste punten

  • DataStore — vervanging van SharedPreferences met asynchrone API en gegevenstypen via Protocol Buffers
  • Preferences DataStore — eenvoudige Key-Store met lezen via Flow en transacties
  • Proto DataStore — getypeerde opslag met automatische schemamigraties
  • SharedPreferences — synchrone API die de UI-thread blokkeert bij grote volumes
  • Migratie wordt uitgevoerd via een speciale SharedPreferencesMigration-interface zonder gegevensverlies

Wat is DataStore?

DataStore — een oplossing van Google voor lokale gegevensopslag in Android, geïntroduceerd in 2020 als alternatief voor SharedPreferences. Het ondersteunt twee modi: Preferences DataStore (eenvoudige sleutel-waardeparen) en Proto DataStore (getypeerd schema op basis van Protocol Buffers).

Het belangrijkste voordeel — volledige asynchroniteit: alle leesbewerkingen retourneren Flow van Kotlin Coroutines en schrijven wordt uitgevoerd in een coroutine-context. Dit elimineert het blokkeren van de hoofdthread, wat een typisch probleem was van SharedPreferences bij het werken met grote hoeveelheden gegevens.

DataStore garandeert atomiciteit van bewerkingen: gelijktijdige schrijfbewerkingen leiden niet tot gegevensverlies dankzij het transactiemodel. Als twee componenten tegelijkertijd dezelfde waarde wijzigen, handelt DataStore het conflict correct af via het compare-and-swap-mechanisme.

Volgens Google I/O 2023 wordt DataStore gebruikt in 40% van de nieuwe projecten op Android en Google raadt migratie van SharedPreferences aan in alle applicaties waar stabiliteit van instellingenopslag vereist is.

DataStore-architectuur

Aan de basis van DataStore ligt SingleProcessDataStore — een implementatie die binnen één proces werkt. Het gebruikt bestandsopslag met vergrendelingen op bestandsniveau: bij het schrijven van gegevens wordt het bestand vergrendeld, wat beschadiging bij gelijktijdige toegang voorkomt.

DataStore handelt deserialisatiefouten automatisch af: als het bestand beschadigd is, retourneert het de standaardwaarde en overschrijft het bestand. Dit gedrag wordt geconfigureerd via corruptionHandler, die kan worden ingesteld bij het maken van DataStore.

Problemen van SharedPreferences die DataStore oplost

SharedPreferences heeft last van drie fundamentele problemen: synchroon lezen van schijf op de hoofdthread, gebrek aan atomiciteitsgaranties bij gelijktijdige schrijfbewerkingen en onmogelijkheid van reactieve wijzigingsdetectie. DataStore lost ze alle drie op: Flow voor observatie, bestandsvergrendeling voor atomiciteit en asynchrone API voor threadveiligheid.

Hoe werkt DataStore in Android?

DataStore slaat gegevens op in bestanden op het interne geheugen van het apparaat. Preferences DataStore gebruikt een bestandsformaat vergelijkbaar met SharedPreferences, maar met extra metadata voor integriteitscontrole. Proto DataStore gebruikt het binaire Protocol Buffers-formaat, wat de bestandsgrootte verkleint en serialisatie versnelt.

Bij het lezen van gegevens laadt DataStore het volledige bestand eenmalig in het geheugen, waarna abonnees de huidige status ontvangen via Flow. Wijzigingen worden automatisch naar alle actieve abonnees verzonden — handmatige registratie van listeners, zoals in SharedPreferences, is niet nodig.

Werkingsprincipe van Preferences DataStore

Preferences DataStore gebruikt een ingebouwd serialisatiemechanisme op basis van Map. Elke invoer is een paar van een string en een primitief type (Int, Boolean, Float, Long, String, Set). Gegevens worden opgeslagen in een XML-bestand, vergelijkbaar met SharedPreferences, maar met atomaire schrijfbewerking via bestandsvergrendeling.

Voorbeeld van het maken van Preferences DataStore: de extensie preferencesDataStore op Context maakt een singleton met de bestandsnaam. Bij herhaalde aanroepen wordt dezelfde instantie geretourneerd — dit elimineert duplicatie van bestanden en verwarring met verschillende opslaginstanties.

Werkingsprincipe van Proto DataStore

Proto DataStore vereist het definiëren van een gegevensschema via een .proto-bestand en compilatie met behulp van de protobuf-plugin. De gegenereerde Java-klasse wordt gebruikt als enige toegangspunt voor alle velden — dit elimineert typefouten in sleutels, typisch voor SharedPreferences.

Het Proto DataStore-schema wordt eenmalig gedefinieerd en ondersteunt het toevoegen van nieuwe velden zonder verlies van oude gegevens. Als in een nieuwe versie van de applicatie een veld met een standaardwaarde wordt toegevoegd, wordt het oude bestand correct gedeserialiseerd — achterwaartse compatibiliteit is ingebouwd in het protocol.

Preferences DataStore en Proto DataStore: vergelijking

De keuze tussen Preferences DataStore en Proto DataStore hangt af van de complexiteit van de gegevens en de typiseringsvereisten. Beide varianten zijn asynchroon en transactioneel, maar verschillen in type-safety-niveau en serialisatieprestaties.

KenmerkPreferences DataStoreProto DataStore
TypiseringZwak (sleutel-waarde)Sterk (gegenereerde klasse)
SerialisatieXML (ingebouwd)Protocol Buffers (protobuf)
BestandsgrootteGroot (leesbare XML)Klein (binair)
ComplexiteitLaag (zonder .proto)Gemiddeld (.proto vereist)
Schema-migratieGeen schemaAutomatisch (proto)
CompatibiliteitSharedPreferences (via migratie)Alleen Proto DataStore

Wanneer kies je Preferences DataStore

Preferences DataStore is geschikt voor eenvoudige instellingen: functie-inschakelvlaggen, autorisatietokenstring, aantal applicatiestarts. Als er weinig gegevens zijn (tot 10–15 sleutels) en ze geen strikt schema vereisen — biedt Preferences DataStore een minimale instapdrempel zonder het aansluiten van de protobuf-plugin.

Wanneer kies je Proto DataStore

Proto DataStore is gerechtvaardigd wanneer de gegevensstructuur complex is of kan veranderen tussen applicatieversies. Bijvoorbeeld gebruikersprofielinstellingen of A/B-testconfiguratie met 20+ velden. Protobuf biedt sterke typisering en automatische migraties, wat runtime-fouten door sleutelconflicten elimineert.

Hoe migreer je van SharedPreferences naar DataStore

Google biedt een ingebouwd migratiemechanisme via de klasse SharedPreferencesMigration. De migratie wordt eenmalig uitgevoerd bij de eerste start na het updaten van de applicatie: DataStore leest gegevens uit SharedPreferences, schrijft ze in zijn eigen formaat en markeert de migratie als voltooid.

Migratie ondersteunt aangepaste transformaties: als in SharedPreferences de sleutels niet overeenkomen met de gewenste DataStore-sleutels, kan een transformatiefunctie worden gedefinieerd via SharedPreferencesMigration. Dit maakt het mogelijk sleutels te hernoemen en gegevenstypen te wijzigen tijdens het migratieproces.

Stapsgewijze migratie

Eerste stap: voeg DataStore toe aan build.gradle en maak een DataStore-instantie met migratie: SharedPreferencesMigration accepteert de naam van het SharedPreferences-bestand en de set sleutels die moeten worden overgedragen. Tweede stap: verwijder alle code die via SharedPreferences werkt en vervang deze door DataStore-aanroepen. Derde — test de migratie: bij de eerste start moeten gegevens verschijnen in DataStore en het oude SharedPreferences-bestand moet niet meer worden gebruikt.

kotlin
val Context.dataStore by preferencesDataStore(
    name = "settings",
    produceMigrations = { context ->
        listOf(
            SharedPreferencesMigration(context, "old_prefs")
        )
    }
)

Voorbeelden van DataStore-gebruik in code

DataStore integreert eenvoudig in een bestaand project. Hieronder vind je praktische voorbeelden voor Preferences DataStore en Proto DataStore — beide tonen lezen, schrijven en reactieve observatie van gegevens.

Preferences DataStore: lezen en schrijven van instellingen

In dit voorbeeld slaat Preferences DataStore drie instellingen op: donker thema, gebruikersnaam en aantal starts. Lezen gebeurt via de extensie .data, die Flow retourneert. Schrijven — via de suspend-functie .edit, die de atomiciteit van wijzigingen garandeert.

kotlin
val Context.settingsDataStore by preferencesDataStore(name = "settings")

val isDarkMode: Flow<Boolean> = settingsDataStore.data
    .map { preferences ->
        preferences[booleanPreferencesKey("dark_mode")] ?: false
    }

suspend fun toggleDarkMode() {
    settingsDataStore.edit { prefs ->
        val current = prefs[booleanPreferencesKey("dark_mode")] ?: false
        prefs[booleanPreferencesKey("dark_mode")] = !current
    }
}

Proto DataStore: schema en gebruik

Proto DataStore vereist het definiëren van een .proto-bestand. Na compilatie wordt de klasse UserSettings gemaakt, die wordt gebruikt voor lezen en schrijven. Schemaversiemigraties worden beschreven in hetzelfde .proto-bestand en automatisch toegepast.

kotlin
// user_preferences.proto
syntax = "proto3";

message UserPreferences {
    string display_name = 1;
    int32 notification_count = 2;
    bool notifications_enabled = 3;
}

// Lezen van DataStore
val userPreferencesFlow: Flow<UserPreferences> =
    protoDataStore.data

// Schrijven van nieuwe waarden
suspend fun updateDisplayName(name: String) {
    protoDataStore.updateData { prefs ->
        prefs.toBuilder()
            .setDisplayName(name)
            .build()
    }
}

Reactieve observatie van wijzigingen

DataStore integreert met MVVM-architectuur via ViewModel. Flow van DataStore wordt verzameld via .stateIn en gebruikt in de UI. Bij elke gegevenswijziging wordt de UI automatisch bijgewerkt — handmatige updates of LiveData zijn niet nodig.

kotlin
class SettingsViewModel(
    private val dataStore: DataStore<Preferences>
) : ViewModel() {

    val uiState: StateFlow<SettingsUiState> =
        dataStore.data
            .map { prefs ->
                SettingsUiState(
                    isDarkMode = prefs[booleanPreferencesKey("dark_mode")] ?: false,
                    counter = prefs[intPreferencesKey("launch_count")] ?: 0
                )
            }
            .stateIn(
                scope = viewModelScope,
                started = SharingStarted.WhileSubscribed(5000),
                initialValue = SettingsUiState()
            )
}

Veelgestelde vragen

Waarom is DataStore beter dan SharedPreferences?

DataStore werkt asynchroon (blokkeert de UI-thread niet), ondersteunt gelijktijdige toegang via transacties en maakt reactieve abonnementen op wijzigingen via Flow mogelijk. SharedPreferences — synchrone API met ANR-risico bij grote hoeveelheden gegevens en zonder ingebouwde ondersteuning voor reactiviteit.

Kan DataStore met Java worden gebruikt?

DataStore is geschreven in Kotlin en vereist Kotlin Coroutines. Het gebruik ervan vanuit Java is mogelijk, maar onhandig: je moet wrappers maken met CompletableFuture of handmatig coroutines beheren. Voor Java-projecten raadt Google aan SharedPreferences te behouden of Kotlin aan de module toe te voegen.

Is DataStore geschikt voor het opslaan van grote hoeveelheden gegevens?

DataStore laadt het volledige bestand in het geheugen bij het lezen, dus is het niet geschikt voor het opslaan van lijsten of grote objecten. Gebruik voor dergelijke scenario's Room of SQLite. DataStore is geoptimaliseerd voor instellingen en kleine gestructureerde gegevens — tot honderden kilobytes.

Hoe verwerk je een fout van een beschadigd DataStore-bestand?

Bij het maken van DataStore kan corruptionHandler worden doorgegeven — een functie die wordt aangeroepen bij bestandsbeschadiging. Standaard gooit DataStore een CorruptionException. In corruptionHandler kunnen lege gegevens worden geretourneerd, waarna DataStore het bestand overschrijft met de juiste status.

Vereist Proto DataStore verplicht een .proto-bestand?

Ja, Proto DataStore vereist het definiëren van een schema in een .proto-bestand en het aansluiten van de protobuf-gradle-plugin. Als het project klein is en de gegevens eenvoudig, is het gemakkelijker om Preferences DataStore te gebruiken — het vereist geen extra build-configuratie.

Samenvatting

  • DataStore — moderne vervanging van SharedPreferences die werkt met Kotlin Coroutines en Flow
  • Preferences DataStore — eenvoudige sleutel-waarde zonder schema, geschikt voor instellingen
  • Proto DataStore — getypeerde opslag met protobuf-schema en automatische migratie
  • Migratie van SharedPreferences naar DataStore is ingebouwd via SharedPreferencesMigration
  • Threadveiligheid — alle bewerkingen zijn asynchroon, UI-blokkering is uitgesloten
  • Reactiviteit — Flow stelt abonnees op de hoogte bij elke gegevenswijziging
  • Aanbeveling — gebruik DataStore in alle nieuwe Android-projecten, migreer bestaande bij het werken met instellingen

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook