当我在 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
作为接收器并调用 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
}
选择你半年后看到你的代码时最容易理解的选项。
代码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")
}
}
}
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
作为接收器并调用 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
}
选择你半年后看到你的代码时最容易理解的选项。