Użyj zapisanych wartości preferencji Część stanowiąca część Androida Jetpack.

W tym dokumencie opisujemy, jak przechowywać i wykorzystywać wartości Preference zapisane w bibliotece preferencji.

Przechowywanie danych preferencji

Ta sekcja opisuje, jak Preference może zachować dane.

SharedPreferences

Domyślnie Preference zapisuje wartości za pomocą SharedPreferences. Interfejs SharedPreferences API obsługuje odczytywanie i zapisywanie prostych par klucz-wartość z pliku zapisanego w różnych sesjach aplikacji. Biblioteka preferencji używa prywatnej instancji SharedPreferences, dzięki czemu tylko Twoja aplikacja ma do niej dostęp.

Dla przykładu przyjmijmy, że SwitchPreferenceCompat wygląda tak:

<SwitchPreferenceCompat
        app:key="notifications"
        app:title="Enable message notifications"/>

Gdy użytkownik przełączy to ustawienie na „Włączone”, plik SharedPreferences zostanie zaktualizowany przy użyciu pary klucz-wartość "notifications" : "true". Użyty klucz jest taki sam jak klucz ustawiony na potrzeby Preference.

Więcej informacji o interfejsie SharedPreferences API znajdziesz w artykule Zapisywanie danych par klucz-wartość.

Informacje o różnych sposobach przechowywania danych na Androidzie znajdziesz w artykule Omówienie miejsca na dane i pliki.

PreferenceDataStore (magazyn danych preferencji)

Chociaż biblioteka preferencji utrzymuje dane z ustawieniem SharedPreferences domyślnie, SharedPreferences nie zawsze jest idealnym rozwiązaniem. Jeśli na przykład Twoja aplikacja wymaga od użytkownika zalogowania się, możesz zachować ustawienia aplikacji w chmurze, aby były odzwierciedlane na innych urządzeniach i platformach. I podobnie, jeśli Twoja aplikacja ma opcje konfiguracji dotyczące konkretnych urządzeń, każdy użytkownik tego urządzenia ma własne ustawienia, przez co SharedPreferences nie jest idealnym rozwiązaniem.

PreferenceDataStore umożliwia użycie backendu pamięci niestandardowej do zachowywania wartości Preference. Więcej informacji znajdziesz w artykule Używanie niestandardowego magazynu danych.

Odczytuj wartości preferencji

Aby pobrać używany obiekt SharedPreferences, wywołaj PreferenceManager.getDefaultSharedPreferences(). Chociaż ta metoda działa z dowolnego miejsca w aplikacji, zalecamy jej podzielenie na warstwy. Więcej informacji znajdziesz w sekcji Warstwa danych.

Na przykład w przypadku elementu EditTextPreference z kluczem "signature":

<EditTextPreference
        app:key="signature"
        app:title="Your signature"/>

Zapisaną wartość parametru Preference możesz pobrać globalnie w ten sposób:

Kotlin

val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this /* Activity context */)
val name = sharedPreferences.getString("signature", "")

Java

SharedPreferences sharedPreferences =
        PreferenceManager.getDefaultSharedPreferences(this /* Activity context */);
String name = sharedPreferences.getString("signature", "");

Wykrywaj zmiany wartości preferencji

Aby wykrywać zmiany wartości Preference, możesz wybrać jeden z 2 interfejsów:

W tabeli poniżej znajdziesz różnice między tymi dwoma interfejsami:

OnPreferenceChangeListener OnSharedPreferenceChangeListener
Ustawiony na jednym elemencie Preference. Dotyczy wszystkich Preference obiektów.
Wywoływane, gdy wartość Preference ma zmienić zapisaną wartość, nawet jeśli wartość oczekująca jest taka sama jak zapisana wartość. Wywoływane tylko wtedy, gdy zmieni się zapisana wartość dla elementu Preference.
Wywoływano tylko przez bibliotekę Preference. Zapisaną wartość można zmienić w oddzielnej części aplikacji. Wywoływane za każdym razem, gdy zmieni się zapisana wartość, nawet jeśli pochodzi z innej części aplikacji.
Wywoływana przed zapisaniem oczekującej wartości. Wywoływane po zapisaniu wartości.
Wywoływane podczas korzystania z właściwości SharedPreferences lub PreferenceDataStore. Stosowane tylko wtedy, gdy używana jest funkcja SharedPreferences.

Implementacja OnPreferenceChangeListener

Implementacja OnPreferenceChangeListener pozwala wychwytywać oczekującą zmianę wartości Preference. Potem możesz sprawdzić, czy zaszła zmiana. Na przykład ten kod pokazuje, jak wychwycić zmianę wartości parametru EditTextPreference z kluczem "name":

Kotlin

override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
    Log.e("preference", "Pending Preference value is: $newValue")
    return true
}

Java

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
    Log.e("preference", "Pending Preference value is: " + newValue);
    return true;
}

Następnie musisz ustawić ten detektor bezpośrednio w setOnPreferenceChangeListener() w ten sposób:

Kotlin

preference.onPreferenceChangeListener = ...

Java

preference.setOnPreferenceChangeListener(...);

Implementacja OnSharedPreferenceChangeListener

Jeśli zachowujesz wartości Preference za pomocą SharedPreferences, możesz też użyć właściwości SharedPreferences.OnSharedPreferenceChangeListener, aby nasłuchiwać zmian. Dzięki temu możesz wykrywać, kiedy wartości zapisane w Preference zmienią się, np. podczas synchronizowania ustawień z serwerem. Z przykładu poniżej dowiesz się, jak wykryć zmianę wartości parametru EditTextPreference z kluczem "name":

Kotlin

override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
    if (key == "signature") {
        Log.i(TAG, "Preference value was updated to: " + sharedPreferences.getString(key, ""))
    }
}

Java

@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    if (key.equals("signature")) {
        Log.i(TAG, "Preference value was updated to: " + sharedPreferences.getString(key, ""));
    }
}

Zarejestruj detektor za pomocą registerOnSharedPreferenceChangedListener() w ten sposób:

Kotlin

preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(...)

Java

getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(...);

Kotlin

    val listener: SharedPreferences.OnSharedPreferenceChangeListener =
            SharedPreferences.OnSharedPreferenceChangeListener {...}
    

Java

    SharedPreferences.OnSharedPreferenceChangeListener listener =
            new SharedPreferences.OnSharedPreferenceChangeListener() {...}
    

Aby zapewnić prawidłowe zarządzanie cyklem życia w Activity lub Fragment, zarejestruj i wyrejestruj ten detektor w wywołaniach zwrotnych onResume() i onPause(), jak pokazano w tym przykładzie:

Kotlin

override fun onResume() {
    super.onResume()
    preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
}

override fun onPause() {
    super.onPause()
    preferenceManager.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
}

Java

@Override
public void onResume() {
    super.onResume();
    getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}

@Override
public void onPause() {
    super.onPause();
    getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}

Użyj niestandardowego magazynu danych

Zalecamy utrwalanie obiektów Preference za pomocą SharedPreferences, ale możesz też użyć niestandardowego magazynu danych. Niestandardowy magazyn danych może być przydatny, jeśli aplikacja utrzymuje wartości w bazie danych lub jeśli wartości są związane z urządzeniami, jak pokazano w poniższych przykładach.

Wdrażanie magazynu danych

Aby wdrożyć niestandardowy magazyn danych, utwórz klasę z rozszerzeniem PreferenceDataStore. Ten przykład tworzy magazyn danych, który obsługuje wartości String:

Kotlin

class DataStore : PreferenceDataStore() {
    override fun putString(key: String, value: String?) {
        // Save the value somewhere.
    }

    override fun getString(key: String, defValue: String?): String? {
        // Retrieve the value.
    }
}

Java

public class DataStore extends PreferenceDataStore {
    @Override
    public void putString(String key, @Nullable String value) {
        // Save the value somewhere.
    }
    @Override
    @Nullable
    public String getString(String key, @Nullable String defValue) {
        // Retrieve the value.
    }
}

Wykonuj czasochłonne operacje w wątku głównym, aby uniknąć zablokowania interfejsu użytkownika. Ze względu na możliwość zniszczenia magazynu danych Fragment lub Activity zawierającego magazyn danych podczas utrwalania wartości, zserializuj dane, aby nie utracić żadnych wartości zmienionych przez użytkownika.

Włącz magazyn danych

Po wdrożeniu magazynu danych ustaw nowy magazyn danych w onCreatePreferences() tak, aby obiekty Preference pozostawały wartości w magazynie danych, zamiast używać domyślnej wartości SharedPreferences. Możesz włączyć magazyn danych dla każdej funkcji Preference lub dla całej hierarchii.

Aby włączyć niestandardowy magazyn danych dla określonego elementu Preference, wywołaj setPreferenceDataStore() w metodzie Preference, jak w tym przykładzie:

Kotlin

val preference: Preference? = findPreference("key")
preference?.preferenceDataStore = dataStore

Java

Preference preference = findPreference("key");
if (preference != null) {
    preference.setPreferenceDataStore(dataStore);
}

Aby włączyć niestandardowy magazyn danych dla całej hierarchii, wywołaj setPreferenceDataStore() w PreferenceManager:

Kotlin

val preferenceManager = preferenceManager
preferenceManager.preferenceDataStore = dataStore

Java

PreferenceManager preferenceManager = getPreferenceManager();
preferenceManager.setPreferenceDataStore(dataStore);

Magazyn danych ustawiony dla określonego elementu Preference zastępuje każdy magazyn danych ustawiony dla odpowiedniej hierarchii. Zwykle przechowujesz magazyn danych dla całej hierarchii.