SharedPreferences: co to jest, magazyn klucz-wartość w Androidzie

Autor: IT Sectr Opublikowano: 2026-03-12 Czas czytania: 9 min

SharedPreferences to magazyn danych typu klucz-wartość w Androidzie, przeznaczony do przechowywania prostych ustawień i konfiguracji aplikacji. Dane są przechowywane w pliku XML na urządzeniu i dostępne tylko w obrębie aplikacji, która je utworzyła. Zgodnie z oficjalną dokumentacją Android Developers, 2025, SharedPreferences obsługuje przechowywanie typów pierwotnych: String, Int, Boolean, Float, Long i Set<String>. To najprostsze i najszybsze rozwiązanie do przechowywania niewielkich ilości ustawień użytkownika bez konieczności korzystania z zapytań SQL lub bezpośredniej pracy z systemem plików.

Najważniejsze

  • SharedPreferences — magazyn klucz-wartość w Androidzie do przechowywania prostych ustawień aplikacji w pliku XML.
  • Obsługuje pięć typów danych: String, Int, Boolean, Float, Long i Set<String>.
  • Działa synchronicznie (get) i asynchronicznie (apply) dla operacji zapisu z zachowaniem na dysku.
  • Dane są izolowane według nazwy pliku i trybu dostępu (PRIVATE, MULTI_PROCESS).
  • Dla dużych ilości danych Google zaleca używanie DataStore lub Room zamiast SharedPreferences.

Czym są SharedPreferences?

SharedPreferences to wbudowany mechanizm Androida do przechowywania par klucz-wartość w pliku XML w wewnętrznej pamięci urządzenia. Jest dostępny od API Level 1 i nie wymaga podłączania dodatkowych bibliotek. Główne przeznaczenie — zapisywanie ustawień użytkownika, stanu interfejsu, flag first-launch i innych prostych danych, które nie wymagają strukturalnej bazy danych.

Każdy plik SharedPreferences jest powiązany z konkretną nazwą i trybem dostępu. Domyślnie używany jest tryb Context.MODE_PRIVATE, który ogranicza dostęp do pliku tylko bieżącej aplikacji. Wcześniej Android obsługiwał tryby MODE_WORLD_READABLE i MODE_WORLD_WRITEABLE, ale zostały one uznane za przestarzałe od API Level 17 i całkowicie usunięte w Androidzie 7.0 (API 24) ze względów bezpieczeństwa.

Mimo swojej prostoty, SharedPreferences jest używany w milionach aplikacji na Androida. Według Google, ponad 90% aplikacji opublikowanych w Google Play używa SharedPreferences do przechowywania ustawień. Jednak dla złożonych scenariuszy (duże ilości danych, bezpieczeństwo typów, asynchroniczność) Google zaleca bardziej nowoczesne rozwiązania, takie jak Preferences DataStore z biblioteki Android Jetpack.

Format przechowywania: XML na urządzeniu

Fizycznie SharedPreferences jest przechowywany jako plik XML w katalogu aplikacji: /data/data/{package_name}/shared_prefs/{file_name}.xml. Plik zawiera element główny <map> z elementami potomnymi <string>, <int>, <boolean>, <float> i <long> w zależności od typu zapisanej wartości. Rozmiar pliku nie jest ograniczony, ale dla dużych ilości danych (powyżej 100 KB) wydajność odczytu i zapisu zaczyna zauważalnie spadać.

Pliki SharedPreferences nie są domyślnie szyfrowane. Dane są przechowywane w otwartej postaci w systemie plików urządzenia. Do przechowywania wrażliwych danych (tokeny, hasła) zaleca się używanie EncryptedSharedPreferences z biblioteki AndroidX Security, która automatycznie szyfruje klucze i wartości za pomocą AES256-GCM.

Jak działa SharedPreferences w Androidzie

SharedPreferences działa na zasadzie buforowania w pamięci z okresową synchronizacją na dysk. Przy pierwszym dostępie do pliku (przez getSharedPreferences) Android ładuje plik XML do pamięci RAM i parsuje go do obiektu Map. Wszystkie kolejne operacje odczytu są wykonywane z pamięci, bez ponownego odczytu z dysku. Zapewnia to wysoką szybkość dostępu do danych.

Operacje zapisu używają Editor — wewnętrznego bufora zmian. Gdy programista wywołuje putString lub putBoolean, zmiany są przechowywane w obiekcie Editor w pamięci. Faktyczny zapis na dysk następuje przy wywołaniu metody commit (synchronicznie) lub apply (asynchronicznie). Do czasu wywołania tych metod dane nie są zapisywane, a w przypadku awaryjnego zakończenia aplikacji zmiany mogą zostać utracone.

Tryby dostępu i kontekst

Do uzyskania instancji SharedPreferences używane są dwie metody: getPreferences i getSharedPreferences. Pierwsza jest dostępna tylko wewnątrz Activity i tworzy plik o nazwie Activity. Druga — bardziej elastyczna, przyjmuje nazwę pliku i tryb dostępu, i jest dostępna z dowolnego kontekstu (Application, Activity, Service). Zaleca się używanie getSharedPreferences z nazwą pliku odpowiadającą modułowi lub funkcjonalności aplikacji.

kotlin
// Uzyskiwanie SharedPreferences
val prefs = context.getSharedPreferences(
    "user_settings", Context.MODE_PRIVATE
)

// Zapisywanie danych
with(prefs.edit()) {
    putString("username", "Anna")
    putInt("age", 28)
    putBoolean("isLoggedIn", true)
    apply()
}

// Odczyt danych
val username = prefs.getString("username", "")
val age = prefs.getInt("age", 0)
val isLoggedIn = prefs.getBoolean("isLoggedIn", false)

Przy użyciu MODE_MULTI_PROCESS (deprecated) SharedPreferences synchronizuje się między procesami. Jednak ta synchronizacja nie gwarantuje atomowości i Google zaleca unikanie używania SharedPreferences w scenariuszach multi-process. W takich przypadkach lepiej użyć ContentProvider, Room z dostępem międzyprocesowym lub DataStore.

Główne metody SharedPreferences

SharedPreferences udostępnia zestaw metod do odczytu danych po kluczu oraz interfejs Editor do zapisu. Każda metoda odczytu przyjmuje dwa parametry: klucz i wartość domyślną, która jest zwracana, jeśli klucz nie zostanie znaleziony. Wartość domyślna określa również typ zwracanej wartości: getString zwraca String, getInt — Int i tak dalej.

Metoda odczytuMetoda zapisuTyp danych
getStringputStringString
getIntputIntInt
getBooleanputBooleanBoolean
getFloatputFloatFloat
getLongputLongLong
getStringSetputStringSetSet<String>

Editor i apply vs commit

Editor — to wewnętrzny obiekt SharedPreferences, który gromadzi zmiany w buforze. Po wprowadzeniu wszystkich zmian programista wywołuje commit() (zapis synchroniczny) lub apply() (zapis asynchroniczny). Różnica jest krytyczna: commit blokuje bieżący wątek do pełnego zapisu na dysk i zwraca boolean (sukces/porażka), natomiast apply wykonuje zapis w tle i natychmiast zwraca sterowanie, ale nie zwraca wyniku.

Zaleca się używanie apply zamiast commit we wszystkich przypadkach, gdy nie trzeba znać wyniku zapisu. apply jest szybszy i nie blokuje wątku UI. commit należy stosować tylko wtedy, gdy krytyczne jest poznanie, czy dane zostały zapisane pomyślnie, lub przy pracy z trybem multi-process. Do usuwania pojedynczych kluczy używana jest metoda remove, do całkowitego czyszczenia — clear. Wszystkie operacje usuwania również są wykonywane przez Editor.

kotlin
// Wiele zmian - jeden apply
prefs.edit {
    putString("theme", "dark")
    putBoolean("notifications", false)
    remove("old_key")
}

// Nasłuchiwanie zmian wartości
prefs.registerOnSharedPreferenceChangeListener { prefs, key ->
    Log.d("TAG", "Zmieniono klucz: $key")
}

Od Androida 12 (API 31), SharedPreferences została uzupełniona o wsparcie dla registerOnSharedPreferenceChangeListener z automatycznym wypisywaniem się przez Lifecycle. Pozwala to uniknąć wycieków pamięci związanych z zapomnianymi listenerami. W starszych wersjach programista jest zobowiązany do ręcznego wywoływania unregisterOnSharedPreferenceChangeListener w onDestroy lub onStop komponentu.

SharedPreferences vs alternatywy przechowywania

Mimo szerokiego rozpowszechnienia, SharedPreferences nie jest uniwersalnym rozwiązaniem dla wszystkich scenariuszy przechowywania danych w Androidzie. W zależności od ilości danych, wymagań dotyczących bezpieczeństwa typów i wydajności, Google zaleca różne alternatywy zawarte w Android Jetpack i standardowej bibliotece Androida.

RozwiązanieKiedy używaćWady
SharedPreferencesNiewielkie ustawienia (do 100 kluczy)Brak bezpieczeństwa typów, synchroniczny odczyt
DataStoreUstawienia średniej złożoności z korutynamiBrak wstecznej kompatybilności poniżej API 14
RoomDane strukturalne i listyZbędny dla 3–5 ustawień
EncryptedSharedPreferencesWrażliwe dane i tokenyZależność od AndroidX Security

DataStore — nowoczesna alternatywa

DataStore — to biblioteka Android Jetpack, przedstawiona przez Google jako zamiennik SharedPreferences. Oferuje dwa warianty: Preferences DataStore (klucz-wartość, jak SharedPreferences) i Proto DataStore (typowane przechowywanie przez Protocol Buffers). DataStore używa korutyn i Flow do asynchronicznej pracy, gwarantuje bezpieczeństwo typów i automatycznie obsługuje migracje wersji. Google zaleca DataStore dla wszystkich nowych projektów.

Główna zaleta DataStore — asynchroniczność na poziomie API. Wszystkie operacje odczytu zwracają Flow, a operacje zapisu są funkcjami suspend. To całkowicie eliminuje blokowanie wątku UI, które jest możliwe przy synchronicznym odczycie SharedPreferences. Ponadto DataStore gwarantuje spójność danych: zapis jest wykonywany w transakcji, a w przypadku awarii wszystkie zmiany są wycofywane.

Przykład użycia SharedPreferences w aplikacji

Rozważmy praktyczny przykład: ustawienia motywu (jasny/ciemny/systemowy) w aplikacji na Androida. Użytkownik wybiera motyw, a wybór jest zapisywany w SharedPreferences. Przy kolejnych uruchomieniach aplikacji motyw jest przywracany z zapisanych ustawień. Do reaktywnej aktualizacji interfejsu używane jest obserwowanie zmian przez SharedPreferences.OnSharedPreferenceChangeListener.

Zapisywanie ustawień użytkownika

Stwórzmy klasę ThemePreferences, która hermetyzuje całą pracę z SharedPreferences dla motywu. Klasa udostępnia metody getTheme (odczyt), setTheme (zapis) i observeTheme (obserwacja). Nazwa pliku ustawień to „app_preferences" z trybem MODE_PRIVATE. Dla wygody klucze są wyodrębnione do companion object jako stałe.

kotlin
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())
            }
        }
    }
}

W Activity lub Fragment uzyskanie instancji ThemePreferences odbywa się przez kontekst aplikacji. Przy inicjalizacji wywoływany jest getTheme w celu ustawienia aktualnego motywu. Gdy użytkownik wybiera nowy motyw, wywoływany jest setTheme, a poprzez observeTheme interfejs jest aktualizowany bez restartowania Activity. Ważne jest, aby nie zapomnieć o wypisaniu się z listenera w onDestroy, aby zapobiec wyciekowi pamięci, szczególnie jeśli Activity jest odtwarzane przy zmianie konfiguracji.

Dla aplikacji z minimalną docelową wersją Android 12+ zaleca się używanie registerOnSharedPreferenceChangeListener razem z LifecycleObserver. To automatycznie zarządza subskrypcją i wypisywaniem się przy zmianie cyklu życia komponentu. Dla starszych wersji subskrypcja i wypisywanie muszą być zarządzane ręcznie, co jest częstym źródłem błędów w produkcyjnych aplikacjach używających SharedPreferences.

Często zadawane pytania

Czy można przechowywać obiekty w SharedPreferences?

SharedPreferences bezpośrednio obsługuje tylko typy pierwotne i Set<String>. Do przechowywania obiektów należy zserializować je do JSON przez Gson lub Moshi, zapisać przez putString i zdeserializować przy odczycie. Dla złożonych obiektów z dużą liczbą pól zaleca się używanie Room zamiast SharedPreferences z JSON-serializacją.

Czy SharedPreferences jest bezpieczny wątkowo?

Tak, SharedPreferences jest bezpieczny wątkowo. Wszystkie operacje odczytu i zapisu są synchronizowane na poziomie obiektu SharedPreferences i jego Editora. Jednak przy użyciu trybu multi-process synchronizacja nie jest gwarantowana. Dla współbieżnego dostępu z wielu wątków w obrębie jednej aplikacji SharedPreferences jest bezpieczny bez dodatkowych blokad.

Jak wyczyścić wszystkie dane SharedPreferences?

Aby całkowicie wyczyścić wszystkie dane z SharedPreferences, wywołaj metodę clear() na Editorze i zastosuj zmiany przez apply. Jeśli chcesz usunąć sam plik XML, użyj deleteSharedPreferences(name) na kontekście. Czyszczenie danych aplikacji przez Ustawienia → Aplikacje → Wyczyść dane również usuwa wszystkie pliki SharedPreferences.

SharedPreferences czy DataStore: co wybrać?

Dla nowych projektów Google zaleca DataStore jako zamiennik SharedPreferences. DataStore zapewnia asynchroniczną pracę z korutynami, bezpieczeństwo typów (Proto DataStore) i automatyczne migracje. SharedPreferences warto wybierać tylko dla projektów z minimalną wersją poniżej API 14 lub gdy potrzebna jest szybka integracja bez dodatkowych zależności.

Jak szyfrować dane w SharedPreferences?

Do szyfrowania danych używaj EncryptedSharedPreferences z biblioteki AndroidX Security. Automatycznie szyfruje klucze i wartości za pomocą AES-256 GCM. Proces konfiguracji jest minimalny: getSharedPreferences zastępuje się EncryptedSharedPreferences.create z podaniem klucza głównego z Android Keystore.

Podsumowanie

  • SharedPreferences — wbudowany magazyn klucz-wartość w Androidzie do przechowywania prostych ustawień aplikacji w formacie XML.
  • Obsługuje sześć typów danych: String, Int, Boolean, Float, Long i Set<String> z określeniem wartości domyślnej.
  • Operacje odczytu są wykonywane z pamięci (pamięć podręczna), zapis — przez Editor z synchronicznym commit lub asynchronicznym apply.
  • Dane są izolowane według nazwy pliku i trybu MODE_PRIVATE, dostępne tylko w obrębie aplikacji, która je utworzyła.
  • Do przechowywania wrażliwych danych używaj EncryptedSharedPreferences z szyfrowaniem AES-256.
  • Dla nowych projektów Google zaleca DataStore jako nowoczesną asynchroniczną alternatywę z korutynami i Flow.
  • SharedPreferences pozostaje najlepszym wyborem do szybkiego zapisywania 5–50 prostych ustawień bez dodatkowych zależności.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również