像对象一样操作SP

Tags
#工具类

一、使用示例

1.在PreferenceManager中添加需要存进SP的字段
class PreferenceManager {

    //用户id,
    var userId: String by PreferenceProxy("")

    var age: Int by PreferenceProxy(0)

    var isMan: Boolean  by PreferenceProxy(false)

    var floatValue: Float  by PreferenceProxy(0.0f)

    var doubleValue: Double by PreferenceProxy(0.0)

    var bean: Bean  by PreferenceProxy(Bean.empty())
}
2.存值
App.preferenceManager .userId = "default userId"
3.取值
val value=App.preferenceManager .userId

二、原理

1.使用属性代理,将PreferenceManager的字段的set/get方法托管给PreferenceProxy
var bean: Bean  by PreferenceProxy(Bean.empty())
2.PreferenceProxy实现ReadWriteProperty接口,重写setValue/getValue方法
/**
 * SP的属性代理
 */
class PreferenceProxy<T>(private val default: T) : ReadWriteProperty<Any?, T> {

    companion object {
        val context: Context by lazy {
            App.instance
        }
    }

    private val prefs by lazy {
        context.getSharedPreferences("xxxx", Context.MODE_PRIVATE)
    }

    private val gson by lazy {
        Gson()
    }

    private val map by lazy {
        HashMap<String, Any?>()
    }

    override fun getValue(thisRef: Any?, property: KProperty<*>): T = with(prefs) {
        val key = property.name
        //先取Map
        val mapValue = map[key]
        mapValue?.let {
            LogUtils.print("取Map:$key -> $it")
            return@with it as T
        }
        //Map没有,才去取SP
        when (default) {
            is Long -> {
                var it = getLong(key, default) as T
                LogUtils.print("取SP-Long:$key -> $it")
                //退出应用后,再次进来时,SP还有值,但是Map没有值了,所以需要在第一次取SP后,存到Map,以后就不用再取SP了
                map[key] = it
                return@with it
            }
            is String -> {
                var it = getString(key, default) as T
                LogUtils.print("取SP-String:$key -> $it")
                map[key] = it
                return@with it
            }
            is Float -> {
                var it = getFloat(key, default) as T
                LogUtils.print("取SP-Float:$key -> $it")
                map[key] = it
                return@with it
            }
            is Int -> {
                var it = getInt(key, default) as T
                LogUtils.print("取SP-Int:$key -> $it")
                map[key] = it
                return@with it
            }
            is Boolean -> {
                var it = getBoolean(key, default) as T
                LogUtils.print("取SP-Boolean:$key -> $it")
                map[key] = it
                return@with it
            }
            else -> {
                val jsonString = getString(key, null)
                if (jsonString != null) {
之后再在自己的Application的伴生对象中,定义一个全局的静态PreferenceManager即可
val preferenceManager: PreferenceManager by lazy {
            PreferenceManager()
        }

三、特别提醒

为了防止Map和SP不一致,以后所有的SP操作,都必须通过PreferenceManager,禁止直接使用SharedPreferences!!!

© fishyer 2022 - 2023