使用已保存的偏好设置值 Android Jetpack 的一部分。
本文档介绍了如何在 Google Cloud 中
保存的 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
值。有关
相关信息,请参阅使用自定义数据存储区。
读取偏好设置值
如要检索正在使用的 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 值的更改
如要监听 Preference
值的更改,您可以在以下两个接口中选择一个:
下表展示了这两个接口的不同之处:
OnPreferenceChangeListener |
OnSharedPreferenceChangeListener |
---|---|
在单个 Preference 上设置。 |
适用于所有 Preference 对象。 |
在 Preference 即将更改其已保存的值时调用,
即使待处理值与已保存值相同也是如此。 |
仅在 Preference 的保存值发生更改时调用。 |
仅通过 Preference 库调用。单独的部分
更改保存的值。 |
每当保存的值发生更改时调用,即使该值来自另一个 部分。 |
在待处理值保存之前调用。 | 在保存值后调用。 |
在使用 SharedPreferences 或
PreferenceDataStore 。 |
仅在使用 SharedPreferences 时调用。 |
实现 OnPreferenceChangeListener
通过实现 OnPreferenceChangeListener
,您可以监听待处理
更改为 Preference
的值。然后,您可以验证
。例如,以下代码展示了如何监听对
键为 "name"
的 EditTextPreference
的值:
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
在使用 SharedPreferences
保留 Preference
值时,您还可以使用 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);
}
使用自定义数据存储区
虽然我们建议使用 SharedPreferences
保留 Preference
对象,
还可以使用自定义数据存储区如果您
应用将值保留在数据库中,或者如果值是设备特定的值,例如
如以下示例中所示。
实现数据存储区
要实现自定义数据存储区,请创建一个可以扩展
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);
}
要为整个层次结构启用自定义数据存储区,请调用
PreferenceManager
上的 setPreferenceDataStore()
:
val preferenceManager = preferenceManager
preferenceManager.preferenceDataStore = dataStore
PreferenceManager preferenceManager = getPreferenceManager();
preferenceManager.setPreferenceDataStore(dataStore);
为特定 Preference
设置的数据存储区会替换符合以下条件的任何数据存储区:
都已针对相应的层次结构设置在大多数情况下,您可以为
整个层次结构