如何包装MMKV

MMKV是什么

官宣:MMKV 是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。从 2015 年中至今在微信上使用,其性能和稳定性经过了时间的验证。近期也已移植到 Android / macOS / Windows 平台,一并开源。
从上我们了解到,微信早在2015年就用上了,用到至今,稳定性肯定没问题,这也是我们选择这个的原因之一,但据我了解到,微信还是有很多的原始SharedPreference存储文件,并没有全部使用,这也说明了,并不是所有场景都适合,适可而止。

为什么要用

看官方介绍,MMKV主要提供了和SharedPreference一样的key-value存储模式,protobuf 实现速度更块,跨平台数据可轻松迁移,支持指定文件存储路径,支持捕获打印LOG日志,支持跨进程,无需Context上下文,支持自定义加密方式。
等等吧,诸多的功能已经满足我们现有app所有的场景,集成大小多少呢(110kb)


image.png

昨天集成的一个老版本的AAR是300kb,新版本应该优化升级了,这大小还不是不错的。可以一用。

如何用

那么如何用呢,这里需要深度思考一下,由于谁都不能保证微信以后停止了该项目的维护,出现更好的替代方案,咱们畅想一下,5G来了,手机本地还需要存储吗?如果有一个网络云存储比现在更好呢,总之,我们要有个原则,任何一个引入的框架都不要在项目中直接使用,因为一旦用的地方相当多,你后期想替换那就是坠入深渊,想想都痛苦,为啥有的人总在加班,这是不是一个原因,哈哈,如果你的设计足够灵活,能兼容各种场景,是不是可以认为改个配置文件就OK了,闲话不多说,来看下,如何包装一下MMKV。
在看了MMKV的源码,我已经知道自己要怎么封装了

public class MMKV implements SharedPreferences, Editor {
.....
}

MMKV实现了原生的SharedPreferences, Editor接口,我们用的SharedPreferences就是该接口的实现,想要实现MMKV的包装,又能平滑的更换MMKV框架,我们用一个熟悉的设计模式- 装饰者模式,这个模式可以完美的解决该问题,又可以无缝使用MMKV的功能,又能扩展新的SharedPreferences实现,无缝切换,代码封装完,完全不需要修改原来的代码,坚守了我们代码设计的对修改关闭的原则。请看代码

interface JLSPInterface : SharedPreferences, SharedPreferences.Editor
class JLSharedPreference : JLSPInterface {
    //懒加载默认实现
    private val defaultSP: MMKV by lazy {
        MMKV.defaultMMKV()
    }

    private var sharedPreferences: SharedPreferences
    //装饰者的核心代码,将接口传进来,后期可以直接替换新的框架。
    constructor(sharedPreferences: SharedPreferences) {
        this.sharedPreferences = sharedPreferences
    }

    constructor() {
        this.sharedPreferences = defaultSP
    }

    companion object {
    
        @JvmStatic
        fun initWithContext(context: Context) {
            MMKV.initialize(context)
        }

        @JvmStatic
        fun initWithRootDir(rootDir: String) {
            MMKV.initialize(rootDir)
        }

        @JvmStatic
        fun defaultSp() = JLSharedPreference()

        @JvmStatic
        fun newSpWithId(spId: String) = JLSharedPreference(MMKV.mmkvWithID(spId))

        @JvmStatic
        fun newMultiProcessSp() {

        }
    }

    override fun contains(key: String?): Boolean {
        return sharedPreferences.contains(key)
    }

    override fun getBoolean(key: String?, defValue: Boolean): Boolean {
        return sharedPreferences.getBoolean(key, defValue)
    }

    override fun unregisterOnSharedPreferenceChangeListener(listener: SharedPreferences.OnSharedPreferenceChangeListener?) {
        return sharedPreferences.unregisterOnSharedPreferenceChangeListener(listener)
    }

    override fun getInt(key: String?, defValue: Int): Int {
        return sharedPreferences.getInt(key, defValue)
    }

    override fun getAll(): MutableMap<String, *> {
        return mutableMapOf<String,Any>()
    }

    fun allKeys(): Array<String>{
         val mmkv = sharedPreferences as? MMKV ?: throw NullPointerException("目前只支持MMKV提供的allKeys")
         return mmkv.allKeys()?: arrayOf()
    }

    override fun edit(): SharedPreferences.Editor {
        return sharedPreferences.edit()
    }

    override fun getLong(key: String?, defValue: Long): Long {
        return sharedPreferences.getLong(key, defValue)
    }

    override fun getFloat(key: String?, defValue: Float): Float {
        return sharedPreferences.getFloat(key, defValue)
    }

    override fun getStringSet(key: String?, defValues: MutableSet<String>?): MutableSet<String>? {
        return sharedPreferences.getStringSet(key, defValues)
    }

    override fun registerOnSharedPreferenceChangeListener(listener: SharedPreferences.OnSharedPreferenceChangeListener?) {
        return sharedPreferences.registerOnSharedPreferenceChangeListener(listener)
    }

    override fun getString(key: String?, defValue: String?): String? {
        return sharedPreferences.getString(key, defValue)
    }

    override fun clear(): SharedPreferences.Editor {
        return sharedPreferences.edit().clear()
    }

    override fun putLong(key: String?, value: Long): SharedPreferences.Editor {
        return sharedPreferences.edit().putLong(key, value)
    }

    override fun putInt(key: String?, value: Int): SharedPreferences.Editor {
        return sharedPreferences.edit().putInt(key, value)
    }

    override fun remove(key: String?): SharedPreferences.Editor {
        return sharedPreferences.edit().remove(key)
    }

    override fun putBoolean(key: String?, value: Boolean): SharedPreferences.Editor {
        return sharedPreferences.edit().putBoolean(key, value)
    }

    override fun putStringSet(key: String?, values: MutableSet<String>?): SharedPreferences.Editor {
        return sharedPreferences.edit().putStringSet(key, values)
    }

    override fun commit(): Boolean {
        return sharedPreferences.edit().commit()
    }

    override fun putFloat(key: String?, value: Float): SharedPreferences.Editor {
        return sharedPreferences.edit().putFloat(key, value)
    }

    override fun apply() {
        return sharedPreferences.edit().apply()
    }

    override fun putString(key: String?, value: String?): SharedPreferences.Editor {
        return sharedPreferences.edit().putString(key, value)
    }

    fun importFromSharedPreferences(preferences: SharedPreferences): Int {
        val mmkv = sharedPreferences as? MMKV ?: throw NullPointerException("目前只支持MMKV迁移")
        return mmkv.importFromSharedPreferences(preferences)
    }
}

好了封装完毕。

总结

希望对你有帮助,后面还可以根据这个设计一个kotlin的属性委托,这样用起来就更加方便。具体怎么实现可以模仿https://www.jianshu.com/p/5e55e3ba5ca9
这是之前基于原生写的,可以参考哦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值