MMKV是什么
官宣:MMKV 是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。从 2015 年中至今在微信上使用,其性能和稳定性经过了时间的验证。近期也已移植到 Android / macOS / Windows 平台,一并开源。
从上我们了解到,微信早在2015年就用上了,用到至今,稳定性肯定没问题,这也是我们选择这个的原因之一,但据我了解到,微信还是有很多的原始SharedPreference存储文件,并没有全部使用,这也说明了,并不是所有场景都适合,适可而止。
为什么要用
看官方介绍,MMKV主要提供了和SharedPreference一样的key-value存储模式,protobuf 实现速度更块,跨平台数据可轻松迁移,支持指定文件存储路径,支持捕获打印LOG日志,支持跨进程,无需Context上下文,支持自定义加密方式。
等等吧,诸多的功能已经满足我们现有app所有的场景,集成大小多少呢(110kb)

昨天集成的一个老版本的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
这是之前基于原生写的,可以参考哦。
网友评论