Google 致力于为黑人社区推动种族平等。查看具体举措

使用已保存的值   Android Jetpack 的一部分。

本页面介绍了如何存储和使用由 Preference 库保存的 Preference 值。

偏好设置数据存储

本部分介绍了 Preference 会如何保留数据。

SharedPreferences

默认情况下,Preference 使用 SharedPreferences 保存值。对于在应用会话运行期间保存的文件,可通过 SharedPreferences API 读取和写入简单的键值对。 Preference 库使用不公开的 SharedPreferences 实例,因此只有您的应用可以访问它。

举例来说,我们假设存在以下 SwitchPreferenceCompat

    <SwitchPreferenceCompat
            app:key="notifications"
            app:title="Enable message notifications"/>
    

当用户将此开关切换至 On 状态时,SharedPreferences 文件将使用 "notifications" : "true" 键值对进行更新。请注意,所用键与为 Preference 设置的键相同。

要详细了解 SharedPreferences API,请参阅保存键值数据

要了解在 Android 上存储数据的不同方式,请参阅数据和文件存储空间概览

PreferenceDataStore

虽然 Preference 库默认通过 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 值的更改,您可以在两个接口中选择一个:

下表说明了两个接口的差别:

OnPreferenceChangeListener OnSharedPreferenceChangeListener
针对每个偏好设置进行设置 应用于所有偏好设置
当某个偏好设置即将要更改其已保存值时进行调用。这包括待处理值与当前已保存值相同的情况。 仅在偏好设置的已保存值发生更改时调用。
仅通过 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 保存的值发生更改的情况,例如在与服务器同步设置时。以下示例演示了如何监听键为“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() {...}
    

为正确管理 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(),如以下示例所示:

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 设置的数据存储会替换针对相应层次结构设置的任何数据存储。在大多数情况下,您应为整个层次结构设置数据存储。