SharedPreferences is een sleutel-waarde gegevensopslag in Android, bedoeld voor het bewaren van eenvoudige instellingen en configuraties van de app. Gegevens worden opgeslagen in een XML-bestand op het apparaat en zijn alleen toegankelijk binnen de app die ze heeft gemaakt. Volgens de officiële documentatie Android Developers, 2025 ondersteunt SharedPreferences het opslaan van primitieve typen: String, Int, Boolean, Float, Long en Set<String>. Het is de eenvoudigste en snelste oplossing voor het bewaren van kleine hoeveelheden gebruikersinstellingen zonder SQL-query's of directe bestandssysteembewerkingen.
Belangrijkste punten
SharedPreferences is een ingebouwd mechanisme in Android voor het opslaan van sleutel-waarde paren in een XML-bestand op de interne opslag van het apparaat. Het is beschikbaar vanaf API Level 1 en vereist geen extra bibliotheken. Het hoofddoel is het bewaren van gebruikersinstellingen, interface-status, first-launch vlaggen en andere eenvoudige gegevens die geen gestructureerde database nodig hebben.
Elk SharedPreferences-bestand is gekoppeld aan een specifieke naam en toegangsmodus. Standaard wordt Context.MODE_PRIVATE gebruikt, die de toegang tot het bestand beperkt tot de huidige app. Eerder ondersteunde Android de modi MODE_WORLD_READABLE en MODE_WORLD_WRITEABLE, maar deze zijn vanaf API Level 17 verouderd verklaard en volledig verwijderd in Android 7.0 (API 24) om veiligheidsredenen.
Ondanks zijn eenvoud wordt SharedPreferences gebruikt in miljoenen Android-apps. Volgens Google gebruikt meer dan 90% van de apps die op Google Play zijn gepubliceerd SharedPreferences voor het opslaan van instellingen. Voor complexe scenario's (grote hoeveelheden gegevens, typeveiligheid, asynchroniteit) raadt Google echter modernere oplossingen aan, zoals Preferences DataStore uit de Android Jetpack-bibliotheek.
Fysiek wordt SharedPreferences opgeslagen als een XML-bestand in de app-directory: /data/data/{package_name}/shared_prefs/{file_name}.xml. Het bestand bevat het root-element <map> met onderliggende elementen <string>, <int>, <boolean>, <float> en <long> afhankelijk van het type opgeslagen waarde. De bestandsgrootte is niet beperkt, maar voor grote hoeveelheden gegevens (meer dan 100 KB) begint de lees- en schrijfprestatie aanzienlijk af te nemen.
SharedPreferences-bestanden worden standaard niet versleuteld. Gegevens worden in open vorm op het bestandssysteem van het apparaat opgeslagen. Voor het opslaan van gevoelige gegevens (tokens, wachtwoorden) wordt aanbevolen EncryptedSharedPreferences uit de AndroidX Security-bibliotheek te gebruiken, die automatisch sleutels en waarden versleutelt met AES256-GCM.
SharedPreferences werkt volgens het principe van caching in het geheugen met periodieke synchronisatie naar schijf. Bij de eerste toegang tot het bestand (via getSharedPreferences) laadt Android het XML-bestand in het RAM en parseert het naar een Map-object. Alle volgende leesbewerkingen worden vanuit het geheugen uitgevoerd, zonder opnieuw van schijf te lezen. Dit zorgt voor een hoge toegangssnelheid tot gegevens.
Schrijfbewerkingen gebruiken Editor — een interne buffer voor wijzigingen. Wanneer de ontwikkelaar putString of putBoolean aanroept, worden wijzigingen opgeslagen in het Editor-object in het geheugen. Het daadwerkelijke wegschrijven naar schijf gebeurt bij het aanroepen van de methode commit (synchroon) of apply (asynchroon). Tot deze methoden worden aangeroepen, worden gegevens niet opgeslagen en bij een onverwachte beëindiging van de app kunnen wijzigingen verloren gaan.
Voor het verkrijgen van een SharedPreferences-instantie worden twee methoden gebruikt: getPreferences en getSharedPreferences. De eerste is alleen beschikbaar binnen Activity en maakt een bestand met de naam van de Activity. De tweede is flexibeler, accepteert een bestandsnaam en toegangsmodus en is toegankelijk vanuit elke context (Application, Activity, Service). Het wordt aanbevolen getSharedPreferences te gebruiken met een bestandsnaam die overeenkomt met de module of functionaliteit van de app.
// SharedPreferences verkrijgen
val prefs = context.getSharedPreferences(
"user_settings", Context.MODE_PRIVATE
)
// Gegevens schrijven
with(prefs.edit()) {
putString("username", "Anna")
putInt("age", 28)
putBoolean("isLoggedIn", true)
apply()
}
// Gegevens lezen
val username = prefs.getString("username", "")
val age = prefs.getInt("age", 0)
val isLoggedIn = prefs.getBoolean("isLoggedIn", false)
Bij gebruik van MODE_MULTI_PROCESS (verouderd) synchroniseert SharedPreferences tussen processen. Deze synchronisatie garandeert echter geen atomiciteit en Google raadt af SharedPreferences te gebruiken in multi-process scenario's. Voor dergelijke gevallen kunt u beter ContentProvider, Room met inter-proces toegang of DataStore gebruiken.
SharedPreferences biedt een reeks methoden voor het lezen van gegevens op sleutel en de Editor-interface voor schrijven. Elke leesmethode accepteert twee parameters: de sleutel en een standaardwaarde die wordt geretourneerd als de sleutel niet wordt gevonden. De standaardwaarde bepaalt ook het type retourwaarde: getString retourneert String, getInt retourneert Int enzovoort.
| Leesmethode | Schrijfmethode | Gegevenstype |
|---|---|---|
| getString | putString | String |
| getInt | putInt | Int |
| getBoolean | putBoolean | Boolean |
| getFloat | putFloat | Float |
| getLong | putLong | Long |
| getStringSet | putStringSet | Set<String> |
Editor is het interne object van SharedPreferences dat wijzigingen in een buffer verzamelt. Nadat alle wijzigingen zijn aangebracht, roept de ontwikkelaar commit() (synchroon schrijven) of apply() (asynchroon schrijven) aan. Het verschil is cruciaal: commit blokkeert de huidige thread tot volledig wegschrijven naar schijf en retourneert boolean (succes/mislukking), terwijl apply het schrijven op de achtergrond uitvoert en onmiddellijk de controle teruggeeft, maar geen resultaat retourneert.
Het wordt aanbevolen apply te gebruiken in plaats van commit in alle gevallen waarin het resultaat van het schrijven niet belangrijk is. apply is sneller en blokkeert de UI-thread niet. commit moet alleen worden gebruikt wanneer het cruciaal is om te weten of gegevens succesvol zijn opgeslagen, of bij werken met multi-process modus. Voor het verwijderen van individuele sleutels wordt de methode remove gebruikt, voor volledig wissen — clear. Alle verwijderbewerkingen worden ook via Editor uitgevoerd.
// Meerdere wijzigingen - één apply
prefs.edit {
putString("theme", "dark")
putBoolean("notifications", false)
remove("old_key")
}
// Waardeverandering luisteraar
prefs.registerOnSharedPreferenceChangeListener { prefs, key ->
Log.d("TAG", "Sleutel gewijzigd: $key")
}
Vanaf Android 12 (API 31) is SharedPreferences uitgebreid met ondersteuning voor registerOnSharedPreferenceChangeListener met automatisch uitschrijven via Lifecycle. Dit voorkomt geheugenlekken die verband houden met vergeten listeners. In oudere versies moet de ontwikkelaar handmatig unregisterOnSharedPreferenceChangeListener aanroepen in onDestroy of onStop van de component.
Ondanks de brede verspreiding is SharedPreferences geen universele oplossing voor alle gegevensopslagscenario's in Android. Afhankelijk van de gegevensomvang, typeveiligheidseisen en prestaties raadt Google verschillende alternatieven aan die zijn opgenomen in Android Jetpack en de standaard Android-bibliotheek.
| Oplossing | Wanneer gebruiken | Nadelen |
|---|---|---|
| SharedPreferences | Kleine instellingen (tot 100 sleutels) | Geen typeveiligheid, synchroon lezen |
| DataStore | Instellingen met gemiddelde complexiteit met coroutines | Geen achterwaartse compatibiliteit onder API 14 |
| Room | Gestructureerde gegevens en lijsten | Overbodig voor 3-5 instellingen |
| EncryptedSharedPreferences | Gevoelige gegevens en tokens | Afhankelijkheid van AndroidX Security |
DataStore is een Android Jetpack-bibliotheek, door Google gepresenteerd als vervanging voor SharedPreferences. Het biedt twee varianten: Preferences DataStore (sleutel-waarde, zoals SharedPreferences) en Proto DataStore (getypeerde opslag via Protocol Buffers). DataStore gebruikt coroutines en Flow voor asynchrone werking, garandeert typeveiligheid en verwerkt automatisch versiemigraties. Google raadt DataStore aan voor alle nieuwe projecten.
Het belangrijkste voordeel van DataStore is asynchroniteit op API-niveau. Alle leesbewerkingen retourneren Flow en schrijfbewerkingen zijn suspend-functies. Dit elimineert volledig het blokkeren van de UI-thread, wat mogelijk is bij synchroon lezen van SharedPreferences. Bovendien garandeert DataStore gegevensconsistentie: schrijven wordt uitgevoerd in een transactie en bij een fout worden alle wijzigingen teruggedraaid.
Laten we een praktisch voorbeeld bekijken: themainstellingen (licht/donker/systeem) in een Android-app. De gebruiker kiest een thema en de keuze wordt opgeslagen in SharedPreferences. Bij volgende starts van de app wordt het thema hersteld uit de opgeslagen instellingen. Voor reactieve UI-updates wordt gebruik gemaakt van het observeren van wijzigingen via SharedPreferences.OnSharedPreferenceChangeListener.
We maken een klasse ThemePreferences die al het werk met SharedPreferences voor het thema inkapselt. De klasse biedt methoden getTheme (lezen), setTheme (schrijven) en observeTheme (observeren). De bestandsnaam voor instellingen wordt "app_preferences" met MODE_PRIVATE. Voor het gemak zijn sleutels als constanten in een companion object opgenomen.
class ThemePreferences(context: Context) {
companion object {
private const val PREF_NAME = "app_preferences"
private const val KEY_THEME = "theme_mode"
const val THEME_LIGHT = "light"
const val THEME_DARK = "dark"
const val THEME_SYSTEM = "system"
}
private val prefs = context
.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
fun getTheme(): String =
prefs.getString(KEY_THEME, THEME_SYSTEM) ?: THEME_SYSTEM
fun setTheme(theme: String) {
prefs.edit { putString(KEY_THEME, theme) }
}
fun observeTheme(callback: (String) -> Unit) {
prefs.registerOnSharedPreferenceChangeListener { _, key ->
if (key == KEY_THEME) {
callback.invoke(getTheme())
}
}
}
}
In Activity of Fragment wordt de instantie van ThemePreferences verkregen via de app-context. Bij initialisatie wordt getTheme aangeroepen om het huidige thema in te stellen. Wanneer de gebruiker een nieuw thema kiest, wordt setTheme aangeroepen en via observeTheme wordt de interface bijgewerkt zonder de Activity te herstarten. Het is belangrijk om niet te vergeten de listener uit te schrijven in onDestroy om geheugenlekken te voorkomen, vooral als de Activity opnieuw wordt aangemaakt bij configuratiewijzigingen.
Voor apps met een minimale doelversie Android 12+ wordt aanbevolen registerOnSharedPreferenceChangeListener te gebruiken in combinatie met LifecycleObserver. Dit beheert automatisch het in- en uitschrijven bij wijziging van de levenscyclus van de component. Voor oudere versies moeten in- en uitschrijven handmatig worden beheerd, wat een frequente bron van fouten is in productie-apps die SharedPreferences gebruiken.
Veelgestelde vragen
SharedPreferences ondersteunt direct alleen primitieve typen en Set<String>. Voor het opslaan van objecten moeten ze worden geserialiseerd naar een JSON-string via Gson of Moshi, opgeslagen met putString en gedeserialiseerd bij het lezen. Voor complexe objecten met veel velden wordt aanbevolen Room te gebruiken in plaats van SharedPreferences met JSON-serialisatie.
Ja, SharedPreferences is thread-safe. Alle lees- en schrijfbewerkingen worden gesynchroniseerd op het niveau van het SharedPreferences-object en zijn Editor. Bij gebruik van de multi-process modus is synchronisatie echter niet gegarandeerd. Voor gelijktijdige toegang vanuit meerdere threads binnen één app is SharedPreferences veilig zonder extra vergrendelingen.
Voor het volledig wissen van alle gegevens uit SharedPreferences roept u de methode clear() aan op Editor en past u de wijzigingen toe via apply. Als u het XML-bestand zelf wilt verwijderen, gebruikt u deleteSharedPreferences(name) op de context. Het wissen van app-gegevens via Instellingen → Apps → Gegevens wissen verwijdert ook alle SharedPreferences-bestanden.
Voor nieuwe projecten raadt Google DataStore aan als vervanging voor SharedPreferences. DataStore biedt asynchrone werking met coroutines, typeveiligheid (Proto DataStore) en automatische migraties. SharedPreferences moet alleen worden gekozen voor projecten met een minimale versie onder API 14 of wanneer snelle integratie zonder extra afhankelijkheden nodig is.
Voor het versleutelen van gegevens gebruikt u EncryptedSharedPreferences uit de AndroidX Security-bibliotheek. Het versleutelt automatisch sleutels en waarden met AES-256 GCM. Het installatieproces is minimaal: getSharedPreferences wordt vervangen door EncryptedSharedPreferences.create met opgave van de hoofdsleutel uit Android Keystore.
Samenvatting
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.
Lees ook