使用已保存的偏好设置值 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="Y>our 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 保存的值发生更改的情况, 例如在与服务器同步设置时。以下示例展示了如何 监听一个键为 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);
}

使用自定义数据存储区

虽然我们建议使用 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.
    }
}

在主线程以外运行任何耗时的操作,以避免阻塞用户 界面。由于包含FragmentActivity 要在保留值时销毁的数据存储区,对数据进行序列化,以便 用户更改的任何值都不会丢失

启用数据存储区

实现数据存储区后,在 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);
}

要为整个层次结构启用自定义数据存储区,请调用 PreferenceManager上的 setPreferenceDataStore():

Kotlin

val preferenceManager = preferenceManager
preferenceManager.preferenceDataStore = dataStore

Java

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

为特定 Preference 设置的数据存储区会替换符合以下条件的任何数据存储区: 都已针对相应的层次结构设置在大多数情况下,您可以为 整个层次结构