当我在 kotlin 中使用 androidx.preference:preference:1.1.1 时,是否需要添加 .apply() 来写入偏好值?

Do I need to add .apply() to write preference value when I use androidx.preference:preference:1.1.1 with kotlin?

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

还有,我想我可以在使用androidx.preference:preference:1.1.1时删除.apply(),就像代码B一样,是否正确?

代码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")
        }
    }
}
来自 Kotlin 标准库的

with 使其参数可作为接收者访问。仅此而已,没有别的。它没有 Android SharedPreference 及其 Editor 的概念,也没有必须提交的任何更改的概念。所以这个...

I think I can remove .apply() [...] just like Code B, is it correct?

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

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

b) 使用来自 AndroidX Core KTX 的 SharedPreference.edit {} 扩展函数,它给你一个 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
}

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