像對(duì)象一樣操作SP

像對(duì)象一樣操作SP

一、使用示例

1.在PreferenceManager中添加需要存進(jìn)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實(shí)現(xiàn)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")
                //退出應(yīng)用后,再次進(jìn)來時(shí),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) {
                    LogUtils.print("取SP-Object:$key -> $jsonString")
                    val clazz = ClassUtil.getClazz(default)
                    var it = gson.fromJson(jsonString, clazz) as T
                    map[key] = it
                    return@with it
                } else {
                    LogUtils.print("取默認(rèn)值:$key -> $default")
                    return@with default
                }
            }
        }
    }

    override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) = with(prefs.edit()) {
        val key = property.name
        //先存SP
        val commit = when (value) {
            is Long -> {
                LogUtils.print("存SP-Long:$key -> $value")
                putLong(key, value)
            }
            is String -> {
                LogUtils.print("存SP-String:$key -> $value")
                putString(key, value)
            }
            is Float -> {
                LogUtils.print("存SP-Float:$key -> $value")
                putFloat(key, value)
            }
            is Int -> {
                LogUtils.print("存SP-Int:$key -> $value")
                putInt(key, value)
            }
            is Boolean -> {
                LogUtils.print("存SP-Boolean:$key -> $value")
                putBoolean(key, value)
            }
            else -> {
                var jsonString = gson.toJson(value)
                LogUtils.print("存SP-Object:$key -> $jsonString")
                putString(key, jsonString)
            }
        }.commit()
        //SP存成功了,再存Map
        if (commit) {
            LogUtils.print("存Map:$key -> $value")
            map[key] = value
        }
    }
}

之后再在自己的Application的伴生對(duì)象中,定義一個(gè)全局的靜態(tài)PreferenceManager即可

val preferenceManager: PreferenceManager by lazy {
            PreferenceManager()
        }

三、特別提醒

為了防止Map和SP不一致,以后所有的SP操作,都必須通過PreferenceManager,禁止直接使用SharedPreferences?。?!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容