Android性能优化:微信自用高性能持久化框架——MMKV组件原理_mmkv size


[MMKV]( )的使用非常简单,  
 所有变更立马生效,无需调用 sync、apply。  
 在 App 启动时初始化 MMKV,设定 MMKV 的根目录  
 (默认/data/data/xxx.xxx/files/mmkv/)  
 (sp存储在/data/data/xxx.xxx/shared\_prefs/)


支持从SP迁移数据importFromSharedPreferences


MMKV 还额外实现了一遍 SharedPreferences、SharedPreferences.Editor 这两个 interface



// 可以跟SP用法一样
SharedPreferences.Editor editor = mmkv.edit();
// 无需调用 commit()
//editor.commit();


MMKV 的使用非常简单,所有变更立马生效,无需调用 sync、apply。 在 App 启动时初始化 MMKV,设定 MMKV 的根目录(files/mmkv/),例如在 MainActivity 里:


 



protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

String rootDir = MMKV.initialize(this);
System.out.println("mmkv root: " + rootDir);
//……

}


MMKV 提供一个全局的实例,可以直接使用:



import com.tencent.mmkv.MMKV;
//……

MMKV kv = MMKV.defaultMMKV();

kv.encode(“bool”, true);
boolean bValue = kv.decodeBool(“bool”);

kv.encode(“int”, Integer.MIN_VALUE);
int iValue = kv.decodeInt(“int”);

kv.encode(“string”, “Hello from mmkv”);
String str = kv.decodeString(“string”);


使用完毕的几个方法



public native void clearAll();

// MMKV's size won't reduce after deleting key-values
// call this method after lots of deleting f you care about disk usage
// note that `clearAll` has the similar effect of `trim`
public native void trim();

// call this method if the instance is no longer needed in the near future
// any subsequent call to the instance is undefined behavior
public native void close();

// call on memory warning
// any subsequent call to the instance will load all key-values from file again
public native void clearMemoryCache();

// you don't need to call this, really, I mean it
// unless you care about out of battery
public void sync() {
    sync(true);
}

#### 性能对比


我们将 MMKV 和 SharedPreferences、SQLite 进行对比, 重复读写操作 1k 次。相关测试代码在 Android/MMKV/mmkvdemo/。结果如下图表。


单进程性能


![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8xNzIzNjk3LTg2MTJmNGFkMGVhZWNlYjg?x-oss-process=image/format,png)


可见,MMKV 在写入性能上远远超越 SharedPreferences & SQLite,在读取性能上也有相近或超越的表现。


多进程性能


![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8xNzIzNjk3LTExOGJmMmZiMDhhNjk1YTY?x-oss-process=image/format,png)


可见,MMKV 无论是在写入性能还是在读取性能,都远远超越 MultiProcessSharedPreferences & SQLite & SQLite,  
 MMKV 在 Android 多进程 key-value 存储组件上是不二之选。


#### 补充适用建议


如果使用请务必做code19版本的适配,这个在github官网有说明


依赖下面这个库,然后对19区分处理  
 implementation ‘com.getkeepsafe.relinker:relinker:1.3.1’


 



if (android.os.Build.VERSION.SDK_INT == 19) {
MMKV.initialize(relativePath, new MMKV.LibLoader() {
@Override
public void loadLibrary(String libName) {
ReLinker.loadLibrary(context, libName);
}
});
} else {
MMKV.initialize(context);
}


#### 限制


可看到,一个键会存入多分实例,最后存入的就是最新的。  
 MMKV 在大部分情况下都性能强劲,key/value 的数量和长度都没有限制。  
 然而 MMKV 在内存里缓存了所有的 key-value,在总大小比较大的情况下(例如 100M+),App 可能会爆内存,触发重整回写时,写入速度也会变慢。  
 支持大文件的 MMKV 正在开发中,有望在下一个大版本发布。


#### 问题


数据变化监听 怎么获取?



// content change notification of other process
// trigger by getXXX() or setXXX() or checkContentChangedByOuterProcess()


[多进程 issue]( )  
 //CallStaticVoidMethod 错误写成 CallStaticIntMethod,方法匹配crash


registerOnSharedPreferenceChangeListener not support  
 //官方推荐使用event方式通知更新  
 Data-change-listener is not supported by design.  
 We suggest using something like event-bus to notify any interesting clients.  
 Doing this inside a storage framework smells really bad.


defaultMMKV 是单进程SINGLE\_PROCESS\_MODE  
 使用MULTI\_PROCESS\_MODE创建多进程


带来的APK尺寸增加问题


libc++\_shared.so 252.5k


libmmkv.so 43.5k


implementation 'com.tencent:mmkv:1.0.23'


// implementation 'com.tencent:mmkv-static:1.0.23' (无libc++\_shared.so)


只打包需要的平台对应.so



ndk {
        abiFilters "armeabi-v7a", 'x86'
    }

.so加载问题


implementation 'com.getkeepsafe.relinker:relinker:1.3.1'


log太多


初始化可以设置log打印层级 initialize(rootDir, MMKVLogLevel.LevelInfo);  
 设置log转发,控制log输出格式、文件 MMKVHandler wantLogRedirecting=true


#### 多进程


锁 lock unlock tryLock


注意如果一个进程lock住,另一个进程mmkvWithID获取MMKV时就阻塞住,直到持有进程释放。



    // get the lock immediately
    MMKV mmkv2 = MMKV.mmkvWithID(LOCK_PHASE_2, MMKV.MULTI_PROCESS_MODE);
    mmkv2.lock();
    Log.d("locked in child", LOCK_PHASE_2);

    Runnable waiter = new Runnable() {
        @Override
        public void run() {
            //阻塞住 直到其他进程释放
            MMKV mmkv1 = MMKV.mmkvWithID(LOCK_PHASE_1, MMKV.MULTI_PROCESS_MODE);
            mmkv1.lock();
            Log.d("locked in child", LOCK_PHASE_1);
        }
    };


## 学习福利

**【Android 详细知识点思维脑图(技能树)】**

> ![](https://img-blog.csdnimg.cn/img_convert/c74e731994474569fa2ca6af68496bdf.webp?x-oss-process=image/format,png)

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,**现在高级工程师还是比较缺少的**,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。

> 这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

![](https://img-blog.csdnimg.cn/img_convert/4e7c3a5157f93870f8541872b43303a8.webp?x-oss-process=image/format,png)

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。



**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化学习资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618156601)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。



**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化学习资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618156601)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值