android - 当我将 androidx.preference:preference:1.1.1 与 kotlin 一起使用时,是否需要添加 .apply() 来写入偏好值?
问题描述
代码 A 的功能是使用androidx.preference:preference:1.1.1
kotlin 读取和写入偏好值。不知道对不对,能告诉我吗?
还有更多,我想当我像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")
}
}
}
解决方案
with
来自 Kotlin 标准库的它的参数可以作为接收器访问。就是这样,没有别的了。它没有 AndroidSharedPreference
的概念,也没有任何对它的Editor
更改必须提交的概念。所以这...
我想我可以
.apply()
像代码 B 一样删除 [...],对吗?
...是不正确的。以下是您可以执行的操作:
a) 最后调用SharedPreference.Editor.apply()
,就像在您的代码示例 A 中一样。
b) 使用SharedPreference.edit {}
AndroidX Core KTX 的扩展功能,它为您提供一个Editor
作为接收器和呼叫apply
或commit
在结束时。
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
}
选择半年后你看到你的代码时最容易理解的选项。
推荐阅读
- python - Joblib 导入错误。尝试加载一个我认为它不应该首先寻找的库
- entity-framework - 没有显示带有 EF 核心的 SqlException 的异常详细信息
- java - 如何在文件中写入/读取对象数组?
- c# - Linq 将指标值转换为附加列并聚合数据
- php - 新错误 Invalid parameter number: number of bound variables does not match number of tokens
- javascript - 使用没有事件侦听器的 Javascript 检测设备运动
- c++ - 我无法使用 Qt 引用 QSettings
- r - R:按日期排序(按年、按月)
- ios - FCM 生产和开发通知来自控制台但不是来自 dot net 服务器
- c++ - 在调试模式下对 std::vector 使用 `.at()` 而不是运算符 `[]`