引言
在 Android
开发中,SharedPreferences
是一个非常实用的轻量级存储机制,用于保存应用的配置信息和简单的数据。然而直接操作 SharedPreferences
可能会导致代码重复和不易维护。在 Kotlin
中,我们可以利用其强大的委托属性功能对 SharedPreferences
进行封装,从而使得读写数据更为简洁、直观。
封装 Kotlin 类
import android.content.Context
import android.content.SharedPreferences
import kotlin.properties.Delegates.observable
class MyPreferences(context: Context, fileName: String = "default_prefs") {
private val sharedPreferences: SharedPreferences =
context.getSharedPreferences(fileName, Context.MODE_PRIVATE)
// 封装一个可观察的委托属性
var username: String by observable(sharedPreferences.getString("username", "")) { _, old, new ->
if (old != new) {
sharedPreferences.edit().putString("username", new).apply()
}
}
// 同样的方式封装其他类型的数据
var userAge: Int by observable(sharedPreferences.getInt("userAge", 0)) { _, old, new ->
if (old != new) {
sharedPreferences.edit().putInt("userAge", new).apply()
}
}
// 其他自定义方法...
}
// 使用示例
val prefs = MyPreferences(this)
prefs.username = "JohnDoe"
println(prefs.username) // 输出已保存的用户名
基于委托属性的实现
在上述示例中,我们创建了一个名为 MyPreferences
的类,并且为每种需要持久化的数据类型封装了相应的委托属性。这里使用了 observable
委托,当属性值发生改变时,会自动将新值保存回 SharedPreferences
。
此外,还可以进一步优化,通过泛型和扩展函数的方式实现一个通用的 Preference
类,能够处理多种数据类型的存取,减少重复代码:
import android.content.SharedPreferences
import kotlin.reflect.KProperty
class Preference<T>(private val preferences: SharedPreferences,
private val key: String,
private val defaultValue: T) {
operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
return when (defaultValue) {
is String -> preferences.getString(key, defaultValue) as T
is Int -> preferences.getInt(key, defaultValue) as T
is Boolean -> preferences.getBoolean(key, defaultValue) as T
// ... 对其他类型进行扩展
else -> throw IllegalArgumentException("This type can't be saved using Preferences")
}
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
val editor = preferences.edit()
when (value) {
is String -> editor.putString(key, value as String?)
is Int -> editor.putInt(key, value as Int)
is Boolean -> editor.putBoolean(key, value as Boolean)
// ... 对其他类型进行编辑
}
editor.apply()
}
}
// 使用示例
val sharedPref = PreferenceManager.getDefaultSharedPreferences(this)
var isNightMode by Preference(sharedPref, "is_night_mode", false)
拓展
// 移除单个键值对
editor.remove("username").apply()
// 清除所有数据
editor.clear().apply()