首页 > 解决方案 > 当我将 androidx.preference:preference:1.1.1 与 kotlin 一起使用时,是否需要添加 .apply() 来写入偏好值?

问题描述

代码 A 的功能是使用androidx.preference:preference:1.1.1kotlin 读取和写入偏好值。不知道对不对,能告诉我吗?

还有更多,我想当我像Code B一样.apply()使用时我可以删除,对androidx.preference:preference:1.1.1吗?

代码 A

import android.content.Context
import android.content.SharedPreferences
import androidx.preference.PreferenceManager

class PreferenceTool<T>(private val context: Context, private val name: String, private val default: T) {

    private val prefs: SharedPreferences by lazy {      
        PreferenceManager.getDefaultSharedPreferences(context)
    }

    operator fun getValue(thisRef: Any?, property: KProperty<*>): T = findPreference(name, default)

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        putPreference(name, value)
    }

    @Suppress("UNCHECKED_CAST")
    private fun findPreference(name: String, default: T): T = with(prefs) {
        val res: Any = when (default) {              //I change from Any to Any?
            is Long -> getLong(name, default)
            is String -> getString(name, default)?:default
            is Int -> getInt(name, default)
            is Boolean -> getBoolean(name, default)
            is Float -> getFloat(name, default)
            else -> throw IllegalArgumentException("This type can be saved into Preferences")
        }
        res as T
    }

    @SuppressLint("CommitPrefEdits")
    private fun putPreference(name: String, value: T) = with(prefs.edit()) {
        when (value) {
            is Long -> putLong(name, value)
            is String -> putString(name, value)
            is Int -> putInt(name, value)
            is Boolean -> putBoolean(name, value)
            is Float -> putFloat(name, value)
            else -> throw IllegalArgumentException("This type can't be saved into Preferences")
        }.apply()
    }
}

代码 B

...
class PreferenceTool<T>(private val context: Context, private val name: String, private val default: T) {
   ...

    @SuppressLint("CommitPrefEdits")
    private fun putPreference(name: String, value: T) = with(prefs.edit()) {
        when (value) {
            is Long -> putLong(name, value)
            is String -> putString(name, value)
            is Int -> putInt(name, value)
            is Boolean -> putBoolean(name, value)
            is Float -> putFloat(name, value)
            else -> throw IllegalArgumentException("This type can't be saved into Preferences")
        }
    }
}

标签: androidkotlinandroid-jetpack

解决方案


with来自 Kotlin 标准库的它的参数可以作为接收器访问。就是这样,没有别的了。它没有 AndroidSharedPreference的概念,也没有任何对它的Editor更改必须提交的概念。所以这...

我想我可以.apply()像代码 B 一样删除 [...],对吗?

...是不正确的。以下是您可以执行的操作:

a) 最后调用SharedPreference.Editor.apply(),就像在您的代码示例 A 中一样。

b) 使用SharedPreference.edit {}AndroidX Core KTX 的扩展功能,它为您提供一个Editor作为接收器和呼叫applycommit在结束时。

private fun putPreference(name: String, value: T) = prefs.edit(commit = false) {
    when (value) {
        is Long -> putLong(name, value)
        is String -> putString(name, value)
        is Int -> putInt(name, value)
        is Boolean -> putBoolean(name, value)
        is Float -> putFloat(name, value)
        else -> throw IllegalArgumentException("This type can't be saved into Preferences")
    }
}

请参阅SharedPreferences.kt - Source

c) 重构,创建一个SharedPreference.Editor.put流畅风格的扩展函数,然后调用它:

private fun putPreference(name: String, value: T) {
    prefs.edit()
        .put(name, value)
        .apply()
}

private fun SharedPreferences.Editor.put(name: String, value: Any) = apply {
    when (value) {
        is Long -> putLong(name, value)
        is String -> putString(name, value)
        is Int -> putInt(name, value)
        is Boolean -> putBoolean(name, value)
        is Float -> putFloat(name, value)
        else -> throw IllegalArgumentException("This type can't be saved into Preferences")
    }
}

这里,apply也来自 Kotlin 标准库。我用了它,所以我不必写

                                                                      // vvvvvv this vvvvvv
private fun SharedPreferences.Editor.put(name: String, value: Any): SharedPreferences.Editor {
    when (value) {
        // ...
    }
    return this // <<<<<< and this
}

选择半年后你看到你的代码时最容易理解的选项。


推荐阅读