Используйте сохраненные значения Preference.   Входит в Android Jetpack.

В этом документе описано, как хранить и использовать значения Preference, сохраненные библиотекой Preference.

Хранилище данных о предпочтениях

В этом разделе описывается, как Preference может сохранять данные.

SharedPreferences

По умолчанию Preference использует SharedPreferences для сохранения значений. API SharedPreferences поддерживает чтение и запись простых пар "ключ-значение" из файла, который сохраняется между сеансами приложения. Библиотека Preference использует закрытый экземпляр SharedPreferences, поэтому доступ к нему есть только у вашего приложения.

Рассмотрим следующий пример SwitchPreferenceCompat:

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

Когда пользователь переводит переключатель в положение "включено", в файл SharedPreferences добавляется пара "ключ-значение" "notifications" : "true". Используется тот же ключ, что и для Preference.

Подробнее SharedPreferences о сохранении данных в формате "ключ-значение"…

Подробнее о хранении данных и файлов…

PreferenceDataStore

Хотя библиотека Preference по умолчанию сохраняет данные с помощью SharedPreferences, SharedPreferences не всегда являются идеальным решением. Например, если для работы с приложением требуется вход в аккаунт, вы можете хранить настройки приложения в облаке, чтобы они применялись на других устройствах и платформах. Аналогично, если в приложении есть параметры конфигурации, зависящие от устройства, у каждого пользователя на устройстве будут отдельные настройки, что делает SharedPreferences неидеальным решением.

PreferenceDataStore позволяет использовать пользовательский сервер хранения для сохранения значений Preference. Подробнее о том, как использовать собственное хранилище данных…

Чтение значений настроек

Чтобы получить используемый объект SharedPreferences, вызовите PreferenceManager.getDefaultSharedPreferences(). Хотя этот метод работает из любого места в приложении, мы рекомендуем разделить приложение на слои. Подробнее о слое данных…

Например, если у вас есть EditTextPreference с ключом "signature":

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

Вы можете получить сохраненное значение для этого Preference глобально, как показано ниже:

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", "");

Как отслеживать изменения значений Preference

Чтобы отслеживать изменения значений Preference, можно выбрать один из двух интерфейсов:

В таблице ниже показано, чем отличаются эти два интерфейса.

OnPreferenceChangeListener OnSharedPreferenceChangeListener
Задайте для одного Preference. Применяется ко всем объектам Preference.
Вызывается, когда Preference собирается изменить свое сохраненное значение, даже если ожидающее значение совпадает с сохраненным. Вызывается, только когда меняется значение, сохраненное для Preference.
Вызывается только через библиотеку Preference. Сохраненное значение может быть изменено в другой части приложения. Вызывается при каждом изменении сохраненного значения, даже если оно происходит в другой части приложения.
Вызывается перед сохранением ожидающего значения. Вызывается после сохранения значения.
Вызывается при использовании SharedPreferences или PreferenceDataStore. Вызывается только при использовании SharedPreferences.

Реализация OnPreferenceChangeListener

Реализация OnPreferenceChangeListener позволяет отслеживать ожидающие изменения значения Preference. Затем вы можете проверить, происходит ли изменение. Например, в следующем коде показано, как отслеживать изменение значения EditTextPreference с ключом "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;
}

Затем нужно настроить этот прослушиватель непосредственно с помощью setOnPreferenceChangeListener(), как показано ниже.

Kotlin

preference.onPreferenceChangeListener = ...

Java

preference.setOnPreferenceChangeListener(...);

Реализация OnSharedPreferenceChangeListener

При сохранении значений Preference с помощью SharedPreferences вы также можете использовать SharedPreferences.OnSharedPreferenceChangeListener для отслеживания изменений. Это позволяет отслеживать изменения значений, сохраненных вашим Preference, например при синхронизации настроек с сервером. В примере ниже показано, как отслеживать изменения значения EditTextPreference с ключом "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, ""));
    }
}

Зарегистрируйте прослушиватель с помощью registerOnSharedPreferenceChangedListener(), как показано ниже.

Kotlin

preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(...)

Java

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

Kotlin

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

Java

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

Чтобы правильно управлять жизненным циклом в Activity или Fragment, зарегистрируйте и отмените регистрацию этого прослушивателя в обратных вызовах onResume() и onPause(), как показано в примере ниже.

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);
}

Как использовать собственное хранилище данных

Хотя мы рекомендуем сохранять объекты Preference с помощью SharedPreferences, вы также можете использовать собственное хранилище данных. Собственное хранилище данных может быть полезно, если ваше приложение сохраняет значения в базе данных или если значения зависят от устройства, как показано в примерах ниже.

Реализуйте хранилище данных

Чтобы реализовать собственное хранилище данных, создайте класс, расширяющий PreferenceDataStore. В следующем примере создается хранилище данных, которое обрабатывает значения 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.
    }
}

Выполняйте все длительные операции вне основного потока, чтобы не блокировать пользовательский интерфейс. Поскольку Fragment или Activity, содержащие хранилище данных, могут быть уничтожены во время сохранения значения, сериализуйте данные, чтобы не потерять значения, измененные пользователем.

Включите хранилище данных

После реализации хранилища данных задайте новое хранилище данных в onCreatePreferences(), чтобы объекты Preference сохраняли значения в хранилище данных, а не использовали SharedPreferences по умолчанию. Вы можете включить хранилище данных для каждого Preference или для всей иерархии.

Чтобы включить собственное хранилище данных для определенного объекта Preference, вызовите setPreferenceDataStore() для этого объекта Preference, как показано в следующем примере:

Kotlin

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

Java

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

Чтобы включить собственное хранилище данных для всей иерархии, вызовите setPreferenceDataStore() для PreferenceManager:

Kotlin

val preferenceManager = preferenceManager
preferenceManager.preferenceDataStore = dataStore

Java

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

Хранилище данных, заданное для определенного Preference, переопределяет любое хранилище данных, заданное для соответствующей иерархии. В большинстве случаев хранилище данных задается для всей иерархии.