使用已保存的偏好设置值 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 的已保存值,如下所示:

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 库调用。单独的部分 更改保存的值。 每当保存的值发生更改时调用,即使该值来自另一个 部分。
在待处理值保存之前调用。 在保存值后调用。
在使用 SharedPreferencesPreferenceDataStore 仅在使用 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() {...}
    

如需在 ActivityFragment 中正确管理生命周期,请注册并 在 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 设置的数据存储区会替换符合以下条件的任何数据存储区: 都已针对相应的层次结构设置在大多数情况下,您可以为 整个层次结构