SharedPreferences je úložiště dat typu klíč-hodnota v Androidu, určené pro ukládání jednoduchých nastavení a konfigurací aplikace. Data jsou uložena v XML souboru na zařízení a jsou přístupná pouze v rámci aplikace, která je vytvořila. Podle oficiální dokumentace Android Developers, 2025 podporuje SharedPreferences ukládání primitivních typů: String, Int, Boolean, Float, Long a Set<String>. Jedná se o nejjednodušší a nejrychlejší řešení pro ukládání malých objemů uživatelských nastavení bez nutnosti SQL dotazů nebo přímé práce se souborovým systémem.
Hlavní body
SharedPreferences je vestavěný mechanismus Androidu pro ukládání párů klíč-hodnota v XML souboru na interním úložišti zařízení. Je dostupný od API Level 1 a nevyžaduje připojení dalších knihoven. Hlavní účel — ukládání uživatelských nastavení, stavu rozhraní, příznaků prvního spuštění a dalších jednoduchých dat, která nevyžadují strukturovanou databázi.
Každý soubor SharedPreferences je spojen s konkrétním názvem a režimem přístupu. Ve výchozím nastavení se používá režim Context.MODE_PRIVATE, který omezuje přístup k souboru pouze na aktuální aplikaci. Dříve Android podporoval režimy MODE_WORLD_READABLE a MODE_WORLD_WRITEABLE, ale ty byly od API Level 17 prohlášeny za zastaralé a zcela odstraněny v Androidu 7.0 (API 24) z bezpečnostních důvodů.
Navzdory své jednoduchosti je SharedPreferences používán v milionech aplikací pro Android. Podle Google více než 90% aplikací publikovaných v Google Play používá SharedPreferences pro ukládání nastavení. Pro složité scénáře (velké objemy dat, typová bezpečnost, asynchronnost) však Google doporučuje modernější řešení, jako je Preferences DataStore z knihovny Android Jetpack.
Fyzicky je SharedPreferences uložen jako XML soubor v adresáři aplikace: /data/data/{package_name}/shared_prefs/{file_name}.xml. Soubor obsahuje kořenový element <map> s podřízenými elementy <string>, <int>, <boolean>, <float> a <long> v závislosti na typu uložené hodnoty. Velikost souboru není omezena, ale pro velké objemy dat (nad 100 KB) začíná výkon čtení a zápisu znatelně klesat.
Soubory SharedPreferences nejsou ve výchozím nastavení šifrovány. Data jsou uložena v otevřené podobě v souborovém systému zařízení. Pro ukládání citlivých dat (tokeny, hesla) se doporučuje používat EncryptedSharedPreferences z knihovny AndroidX Security, která automaticky šifruje klíče a hodnoty pomocí AES256-GCM.
SharedPreferences funguje na principu ukládání do mezipaměti v paměti s pravidelnou synchronizací na disk. Při prvním přístupu k souboru (přes getSharedPreferences) Android nahraje XML soubor do RAM a parsuje ho do objektu Map. Všechny následné operace čtení se provádějí z paměti, bez opětovného čtení z disku. To zajišťuje vysokou rychlost přístupu k datům.
Operace zápisu používají Editor — interní buffer změn. Když vývojář zavolá putString nebo putBoolean, změny jsou uloženy v objektu Editor v paměti. Skutečný zápis na disk probíhá při volání metody commit (synchronně) nebo apply (asynchronně). Do doby volání těchto metod nejsou data uložena a při neočekávaném ukončení aplikace mohou být změny ztraceny.
Pro získání instance SharedPreferences se používají dvě metody: getPreferences a getSharedPreferences. První je dostupná pouze uvnitř Activity a vytváří soubor s názvem Activity. Druhá je flexibilnější, přijímá název souboru a režim přístupu a je dostupná z libovolného kontextu (Application, Activity, Service). Doporučuje se používat getSharedPreferences s názvem souboru odpovídajícím modulu nebo funkcionalitě aplikace.
// Získání SharedPreferences
val prefs = context.getSharedPreferences(
"user_settings", Context.MODE_PRIVATE
)
// Zápis dat
with(prefs.edit()) {
putString("username", "Anna")
putInt("age", 28)
putBoolean("isLoggedIn", true)
apply()
}
// Čtení dat
val username = prefs.getString("username", "")
val age = prefs.getInt("age", 0)
val isLoggedIn = prefs.getBoolean("isLoggedIn", false)
Při použití MODE_MULTI_PROCESS (zastaralé) se SharedPreferences synchronizuje mezi procesy. Tato synchronizace však nezaručuje atomicitu a Google doporučuje vyhnout se používání SharedPreferences v multi-process scénářích. Pro takové případy je lepší použít ContentProvider, Room s meziprocesovým přístupem nebo DataStore.
SharedPreferences poskytuje sadu metod pro čtení dat podle klíče a rozhraní Editor pro zápis. Každá metoda čtení přijímá dva parametry: klíč a výchozí hodnotu, která je vrácena, pokud klíč není nalezen. Výchozí hodnota také určuje typ vrácené hodnoty: getString vrací String, getInt vrací Int a tak dále.
| Metoda čtení | Metoda zápisu | Datový typ |
|---|---|---|
| getString | putString | String |
| getInt | putInt | Int |
| getBoolean | putBoolean | Boolean |
| getFloat | putFloat | Float |
| getLong | putLong | Long |
| getStringSet | putStringSet | Set<String> |
Editor — interní objekt SharedPreferences, který shromažďuje změny v bufferu. Po provedení všech změn vývojář zavolá commit() (synchronní zápis) nebo apply() (asynchronní zápis). Rozdíl je kritický: commit blokuje aktuální vlákno do úplného zápisu na disk a vrací boolean (úspěch/neúspěch), zatímco apply provádí zápis na pozadí a okamžitě vrací řízení, ale nevrací výsledek.
Doporučuje se používat apply místo commit ve všech případech, kdy není třeba znát výsledek zápisu. apply je rychlejší a neblokuje UI vlákno. commit by měl být použit pouze tehdy, když je kritické vědět, zda byla data úspěšně uložena, nebo při práci s multi-process režimem. Pro odstranění jednotlivých klíčů se používá metoda remove, pro úplné vyčištění — clear. Všechny operace odstranění se také provádějí přes Editor.
// Více změn - jeden apply
prefs.edit {
putString("theme", "dark")
putBoolean("notifications", false)
remove("old_key")
}
// Naslouchání změn hodnot
prefs.registerOnSharedPreferenceChangeListener { prefs, key ->
Log.d("TAG", "Klíč se změnil: $key")
}
Od Androidu 12 (API 31) je SharedPreferences doplněn o podporu registerOnSharedPreferenceChangeListener s automatickým odhlášením prostřednictvím Lifecycle. To umožňuje vyhnout se únikům paměti spojeným se zapomenutými posluchači. Ve starších verzích je vývojář povinen ručně volat unregisterOnSharedPreferenceChangeListener v onDestroy nebo onStop komponenty.
Navzdory širokému rozšíření není SharedPreferences univerzálním řešením pro všechny scénáře ukládání dat v Androidu. V závislosti na objemu dat, požadavcích na typovou bezpečnost a výkon doporučuje Google různé alternativy zahrnuté v Android Jetpack a standardní knihovně Androidu.
| Řešení | Kdy použít | Nevýhody |
|---|---|---|
| SharedPreferences | Malá nastavení (do 100 klíčů) | Žádná typová bezpečnost, synchronní čtení |
| DataStore | Nastavení střední složitosti s korutinami | Žádná zpětná kompatibilita pod API 14 |
| Room | Strukturovaná data a seznamy | Zbytečný pro 3-5 nastavení |
| EncryptedSharedPreferences | Citlivá data a tokeny | Závislost na AndroidX Security |
DataStore — knihovna Android Jetpack, představená Googlem jako náhrada za SharedPreferences. Nabízí dvě varianty: Preferences DataStore (klíč-hodnota, jako SharedPreferences) a Proto DataStore (typované ukládání přes Protocol Buffers). DataStore používá korutiny a Flow pro asynchronní práci, garantuje typovou bezpečnost a automaticky zpracovává migrace verzí. Google doporučuje DataStore pro všechny nové projekty.
Hlavní výhoda DataStore — asynchronnost na úrovni API. Všechny operace čtení vracejí Flow a operace zápisu jsou suspend-funkce. To zcela eliminuje blokování UI vlákna, které je možné při synchronním čtení SharedPreferences. Kromě toho DataStore garantuje konzistenci dat: zápis se provádí v transakci a v případě selhání jsou všechny změny vráceny zpět.
Podívejme se na praktický příklad: nastavení motivu (světlý/tmavý/systémový) v aplikaci pro Android. Uživatel vybere motiv a volba se uloží do SharedPreferences. Při následujících spuštěních aplikace se motiv obnoví z uložených nastavení. Pro reaktivní aktualizaci rozhraní se používá sledování změn prostřednictvím SharedPreferences.OnSharedPreferenceChangeListener.
Vytvoříme třídu ThemePreferences, která zapouzdřuje veškerou práci s SharedPreferences pro motiv. Třída poskytuje metody getTheme (čtení), setTheme (zápis) a observeTheme (sledování). Název souboru nastavení bude "app_preferences" s režimem MODE_PRIVATE. Pro pohodlí jsou klíče vyčleněny do companion object jako konstanty.
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())
}
}
}
}
V Activity nebo Fragmentu se získání instance ThemePreferences provádí přes kontext aplikace. Při inicializaci se volá getTheme pro nastavení aktuálního motivu. Když uživatel vybere nový motiv, zavolá se setTheme a prostřednictvím observeTheme se rozhraní aktualizuje bez restartování Activity. Je důležité nezapomenout se odhlásit z posluchače v onDestroy, aby se zabránilo úniku paměti, zejména pokud je Activity znovu vytvořeno při změně konfigurace.
Pro aplikace s minimální cílovou verzí Android 12+ se doporučuje používat registerOnSharedPreferenceChangeListener společně s LifecycleObserver. To automaticky spravuje přihlášení a odhlášení při změně životního cyklu komponenty. Pro starší verze je třeba přihlášení a odhlášení spravovat ručně, což je častým zdrojem chyb v produkčních aplikacích používajících SharedPreferences.
Často kladené otázky
SharedPreferences přímo podporuje pouze primitivní typy a Set<String>. Pro ukládání objektů je nutné je serializovat do JSON řetězce přes Gson nebo Moshi, uložit přes putString a při čtení deserializovat. Pro složité objekty s velkým počtem polí se doporučuje používat Room místo SharedPreferences s JSON serializací.
Ano, SharedPreferences je thread-safe. Všechny operace čtení a zápisu jsou synchronizovány na úrovni objektu SharedPreferences a jeho Editoru. Při použití multi-process režimu však synchronizace není zaručena. Pro konkurenční přístup z více vláken v rámci jedné aplikace je SharedPreferences bezpečný bez dalších zámků.
Pro úplné vymazání všech dat z SharedPreferences zavolejte metodu clear() na Editoru a aplikujte změny pomocí apply. Pokud potřebujete odstranit samotný XML soubor, použijte deleteSharedPreferences(name) na kontextu. Vymazání dat aplikace přes Nastavení → Aplikace → Vymazat data také odstraní všechny soubory SharedPreferences.
Pro nové projekty Google doporučuje DataStore jako náhradu za SharedPreferences. DataStore poskytuje asynchronní práci s korutinami, typovou bezpečnost (Proto DataStore) a automatické migrace. SharedPreferences by měl být vybrán pouze pro projekty s minimální verzí pod API 14 nebo když je potřeba rychlá integrace bez dalších závislostí.
Pro šifrování dat použijte EncryptedSharedPreferences z knihovny AndroidX Security. Automaticky šifruje klíče a hodnoty pomocí AES-256 GCM. Proces nastavení je minimální: getSharedPreferences se nahradí EncryptedSharedPreferences.create s uvedením hlavního klíče z Android Keystore.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také