使用保存的偏好值 作为 Android Jetpack 的一部分。
本文档介绍了如何存储和使用由 Preference 库保存的 Preference
值。
Preference 数据存储
本节介绍 Preference
如何持久化数据。
SharedPreferences
默认情况下,Preference
使用 SharedPreferences
保存值。SharedPreferences
API 支持从跨应用程序会话保存的文件中读取和写入简单的键值对。Preference 库使用私有的 SharedPreferences
实例,以便只有你的应用程序可以访问它。
例如,假设有以下 SwitchPreferenceCompat
<SwitchPreferenceCompat app:key="notifications" app:title="Enable message notifications"/>
当用户将此开关切换到“开”状态时,SharedPreferences
文件将更新为 "notifications" : "true"
的键值对。使用的键与为 Preference
设置的键相同。
有关 SharedPreferences
API 的更多信息,请参阅 保存键值数据。
有关在 Android 上存储数据的不同方法的信息,请参阅 数据和文件存储概述。
PreferenceDataStore
尽管 Preference 库默认情况下使用 SharedPreferences
持久化数据,但 SharedPreferences
并不总是理想的解决方案。例如,如果你的应用程序需要用户登录,你可能希望在云中持久化应用程序设置,以便在其他设备和平台上反映这些设置。同样,如果你的应用程序具有特定于设备的配置选项,则设备上的每个用户都有单独的设置,这使得 SharedPreferences
成为不太理想的解决方案。
PreferenceDataStore
允许你使用自定义存储后端来持久化 Preference
值。有关更多信息,请参阅 使用自定义数据存储。
读取 Preference 值
要检索正在使用的 SharedPreferences
对象,请调用 PreferenceManager.getDefaultSharedPreferences()
。虽然此方法可在应用程序的任何位置运行,但我们建议你将应用程序拆分为多层。有关更多信息,请参阅 数据层。
例如,给定一个键为 "signature"
的 EditTextPreference
,如下所示
<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
值的挂起更改。然后,你可以验证更改是否发生。例如,以下代码显示了如何侦听对键为 "name"
的 EditTextPreference
值的更改:
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
在使用 SharedPreferences
持久化 Preference
值时,你还可以使用 SharedPreferences.OnSharedPreferenceChangeListener
来侦听更改。这使你可以侦听 Preference
保存的值何时更改,例如将设置与服务器同步时。以下示例显示了如何侦听对键为 "name"
的 EditTextPreference
值的更改:
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); }
使用自定义数据存储
虽然我们推荐使用SharedPreferences
持久化Preference
对象,但您也可以使用自定义数据存储。如果您的应用程序将值持久化到数据库,或者值是设备特定的,则自定义数据存储非常有用,如下例所示。
实现数据存储
要实现自定义数据存储,请创建一个扩展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
启用自定义数据存储,请在Preference
上调用setPreferenceDataStore()
,如下例所示。
Kotlin
val preference: Preference? = findPreference("key") preference?.preferenceDataStore = dataStore
Java
Preference preference = findPreference("key"); if (preference != null) { preference.setPreferenceDataStore(dataStore); }
要为整个层次结构启用自定义数据存储,请在PreferenceManager
上调用setPreferenceDataStore()
。
Kotlin
val preferenceManager = preferenceManager preferenceManager.preferenceDataStore = dataStore
Java
PreferenceManager preferenceManager = getPreferenceManager(); preferenceManager.setPreferenceDataStore(dataStore);
为特定Preference
设置的数据存储会覆盖为相应层次结构设置的任何数据存储。在大多数情况下,您会为整个层次结构设置数据存储。