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

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

Хранение данных предпочтений

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

Общие настройки

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

В качестве примера предположим следующий SwitchPreferenceCompat :

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

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

Дополнительные сведения об API SharedPreferences см. в разделе Сохранение данных «ключ-значение» .

Информацию о различных способах хранения данных на Android см. в разделе Обзор хранилища данных и файлов .

PreferenceDataStore

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

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

Чтение значений предпочтений

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

Например, если задан EditTextPreference с ключом "signature" следующим образом:

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

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

Котлин

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

Ява

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

Прослушивайте изменения значений предпочтений

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

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

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

Реализация OnPreferenceChangeListener

Реализация OnPreferenceChangeListener позволяет прослушивать ожидающее изменение значения Preference . Затем вы можете проверить, произошло ли изменение. Например, следующий код показывает, как прослушивать изменение значения EditTextPreference с ключом "name" :

Котлин

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

Ява

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

Далее вам нужно установить этот прослушиватель напрямую с помощью setOnPreferenceChangeListener() следующим образом:

Котлин

preference.onPreferenceChangeListener = ...

Ява

preference.setOnPreferenceChangeListener(...);

Реализация OnSharedPreferenceChangeListener

При сохранении значений Preference с помощью SharedPreferences вы также можете использовать SharedPreferences.OnSharedPreferenceChangeListener для прослушивания изменений. Это позволяет вам прослушивать изменения значений, сохраненных в Preference , например, при синхронизации настроек с сервером. В следующем примере показано, как прослушивать изменение значения EditTextPreference с ключом "name" :

Котлин

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

Ява

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

Зарегистрируйте прослушиватель с помощью registerOnSharedPreferenceChangedListener() следующим образом:

Котлин

preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(...)

Ява

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

Котлин

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

Ява

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

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

Котлин

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

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

Ява

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

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

Используйте собственное хранилище данных

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

Реализация хранилища данных

Чтобы реализовать собственное хранилище данных, создайте класс, расширяющий PreferenceDataStore . В следующем примере создается хранилище данных, которое обрабатывает String значения:

Котлин

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.
    }
}

Ява

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 , как показано в следующем примере:

Котлин

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

Ява

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

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

Котлин

val preferenceManager = preferenceManager
preferenceManager.preferenceDataStore = dataStore

Ява

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

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