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