优化Android SharedPreferences值存取逻辑 减少新增存储项的样板代码
问题1:自定义实现方案的合理性与隐患
你的实现思路是成立的,核心是利用Kotlin属性引用能力减少手动声明key的重复代码,运行性能和传统读写函数写法完全一致,不需要退回到传统方案。但你的现有代码存在2个明显隐患:
- 存在代码笔误:你定义的
storage是SharedPreferences实例不是函数,storage().edit()写法会直接触发运行报错,改成storage.edit()才能正常运行 - 属性默认值和字段绑定,如果后续需要调整某个存储项的默认值,要注意兼容已经写入过旧数据的场景,避免出现逻辑不一致的问题
- 如果你的应用存在多进程访问同一份存储的场景,不管哪种写法SharedPreferences本身都不支持跨进程安全读写,这种场景建议替换为MMKV等其他存储方案
问题2:进一步优化的实现方案
你想要的「仅声明变量自动生成读写逻辑」的需求,用Kotlin委托属性就能完美实现,这也是Android生态里非常成熟的SharedPreferences封装方案:
首先实现通用的属性委托工具:
import android.content.Context import android.content.SharedPreferences import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty // String类型存储委托,其他类型可按相同逻辑扩展 class SpStringDelegate( private val defaultValue: String, private val customKey: String? = null ) : ReadWriteProperty<SharedPreferences, String> { override fun getValue(thisRef: SharedPreferences, property: KProperty<*>): String { val key = customKey ?: property.name return thisRef.getString(key, defaultValue) ?: defaultValue } override fun setValue(thisRef: SharedPreferences, property: KProperty<*>, value: String) { thisRef.edit() .putString(customKey ?: property.name, value) .apply() } } // 扩展函数简化调用 fun SharedPreferences.string(defaultValue: String = "", key: String? = null) = SpStringDelegate(defaultValue, key)
之后你的Storage类只需要声明属性即可,无需编写额外的读写逻辑:
class Storage(context: Context) { private val storage = context.getSharedPreferences("my_storage", Context.MODE_PRIVATE) // 默认用变量名作为存储key,自定义默认值 var myString by storage.string("default String") // 也可以手动指定存储key var anotherStr by storage.string("default", key = "custom_key") }
使用时直接操作属性即可:
// 读存储 val content = storage.myString // 写存储 storage.myString = "new content"
你可以按照相同的模式扩展Int、Boolean、Long、Float、Set
内容的提问来源于stack exchange,提问作者Jonathan S
相关产品推荐
相关产品推荐

