使用已保存的值 Android Jetpack 的一部分。
本页面介绍了如何存储和使用由 Preference 库保存的 Preference
值。
Preference 数据存储
本部分介绍了 Preference
会如何保留数据。
SharedPreferences
默认情况下,Preference
使用 SharedPreferences
保存值。对于在应用会话期间保存的文件,可通过 SharedPreferences
API 读取和写入简单的键值对。
Preference 库使用不公开的 SharedPreferences
实例,因此只有您的应用可以访问它。
举例来说,我们假设存在以下 SwitchPreferenceCompat
:
<SwitchPreferenceCompat app:key="notifications" app:title="Enable message notifications"/>
当用户将此开关切换至 On
状态时,系统将使用 "notifications" : "true"
键值对更新 SharedPreferences
文件。请注意,所用键与为 Preference
设置的键相同。
如需详细了解 SharedPreferences
API,请参阅保存键值对数据。
如需了解在 Android 上存储数据的不同方式,请参阅数据和文件存储概览。
PreferenceDataStore
虽然 Preference 库默认通过 SharedPreferences
保留数据,但 SharedPreferences
并不总是理想的解决方案。例如,如果您的应用要求用户登录,您可能需要在云中保留应用设置,以便在其他设备和平台上体现这些设置。同样,如果您的应用具有特定于设备的配置选项,那么设备上的每个用户都会有单独的设置,此时 SharedPreferences
就不是太理想的解决方案。
借助 PreferenceDataStore
,您可以使用自定义存储后端来保留 Preference
值。如需了解详情,请参阅使用自定义数据存储区。
读取 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
的值即将发生更改的情况。监听到更改后,您可以验证是否应该进行此更改。例如,以下代码演示了如何监听键为“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
设置的数据存储区会替换针对相应层次结构设置的任何数据存储区。在大多数情况下,您应为整个层次结构设置数据存储区。