安装:
implementation 'com.tencent:mmkv:1.2.11'
简单使用
1.初始化
MMKV.initialize(this);
2.数据交互
a.获取全局实例
MMKV kv = MMKV.defaultMMKV();
b.存数据
kv.encode("bool", true);
c.取数据
boolean bValue = kv.decodeBool("bool");
支持类型
- 支持以下 Java 语言基础类型:
- boolean、int、long、float、double、byte[]
- 支持以下 Java 类和容器:
- String、Set
- 任何实现了Parcelable的类型
进阶用法
3.删除
a.删除某一个key
MMKV kv = MMKV.defaultMMKV();
kv.removeValueForKey("k1");
b.删除多个key
kv.removeValueForKey(new String[]{"k1","k2"});
c.删除所有
kv.removeValueForKey(kv.allKeys());
4.查询
boolean hask1 = kv.containsKey("k1");
boolean hask1 = kv.contains("k1");
这两个效果一样,不过官方推荐 containsKey
5.存多个kv文件
类似sharepreferences在创建kv的时候,可以指定名字,用来区别存储不一样的东西
MMKV kv1 = MMKV.mmkvWithID("id1");
MMKV kv2 = MMKV.mmkvWithID("id2");
这样 kv1 和 kv2 存的内容就分别在两个 文件里了
6.sharepreferences 一键迁移
MMKV preferences = MMKV.mmkvWithID("myData");
SharedPreferences old_man = getSharedPreferences("lovesosoi", MODE_PRIVATE);
preferences.importFromSharedPreferences(old_man);
old_man.edit().clear().commit();
其他功能
7.自定义
a.自定义根目录(初始化的时候用)
String dir = getFilesDir().getAbsolutePath() + "/mmkv_2";
String rootDir = MMKV.initialize(dir);
b.自定义某一个文件的存储路径
String relativePath = getFilesDir().getAbsolutePath() + "/mmkv_3";
MMKV kv = MMKV.mmkvWithID("testCustomDir", relativePath);
8.日志
a.关闭日志(不建议)
默认是开启的,关闭日志的话
MMKV.setLogLevel(MMKVLogLevel.LevelNone);
b.日志监控
MMKV.registerHandler(new MMKVHandler() {
@Override
public MMKVRecoverStrategic onMMKVCRCCheckFail(String mmapID) {
return null;
}
@Override
public MMKVRecoverStrategic onMMKVFileLengthError(String mmapID) {
return null;
}
@Override
public boolean wantLogRedirecting() {
return true;
}
@Override
public void mmkvLog(MMKVLogLevel level, String file, int line, String function, String message) {
String log = "<" + file + ":" + line + "::" + function + "> " + message;
Log.e("redirect logging MMKV", log);
}
});
注意两点wantLogRedirecting 设置 true,然后mmkvlog 里看回调日志
9.加密与解密
a.加密
String cryptKey = "My-Encrypt-Key";
MMKV kv = MMKV.mmkvWithID("MyID", MMKV.SINGLE_PROCESS_MODE, cryptKey);
b.解密
MMKV kv = MMKV.mmkvWithID("MyID", MMKV.SINGLE_PROCESS_MODE, null);
c.更改秘钥
kv.reKey("Key_seq_1");
d.取消秘钥
kv.reKey(null);
10.数据恢复
MMKV.registerHandler(new MMKVHandler() {
@Override
public MMKVRecoverStrategic onMMKVCRCCheckFail(String mmapID) {
return MMKVRecoverStrategic.OnErrorRecover;
}
@Override
public MMKVRecoverStrategic onMMKVFileLengthError(String mmapID) {
return MMKVRecoverStrategic.OnErrorRecover;
}
@Override
public boolean wantLogRedirecting() {
return false;
}
@Override
public void mmkvLog(MMKVLogLevel level, String file, int line, String function, String message) {
}
});
和日志一样的方法不过是修改的前两个回调。
注意修复率无法保证,而且可能修复出奇怪的 key-value
11.备份恢复
String backupRootDir = getFilesDir().getAbsolutePath() + "/mmkv_backup_3";
// backup one instance
boolean ret = MMKV.backupOneToDirectory(mmapID, backupRootDir, null);
// backup all instances
long count = MMKV.backupAllToDirectory(backupRootDir);
// restore one instance
ret = MMKV.restoreOneMMKVFromDirectory(mmapID, backupRootDir, otherDir);
// restore all instances
count = MMKV.restoreAllFromDirectory(backupRootDir);
12.自定义 library loader
一些 Android 设备(API level 19)在安装/更新 APK 时可能出错, 导致 libmmkv.so 找不到。然后就会遇到 java.lang.UnsatisfiedLinkError 之类的 crash。有个开源库 ReLinker 专门解决这个问题,你可以用它来加载 MMKV
String dir = getFilesDir().getAbsolutePath() + "/mmkv";
MMKV.initialize(dir, new MMKV.LibLoader() {
@Override
public void loadLibrary(String libName) {
ReLinker.loadLibrary(MyApplication.this, libName);
} });
13.Native Buffer
当从 MMKV 取一个 String or byte[]的时候,会有一次从 native 到 JVM 的内存拷贝。如果这个值立即传递到另一个 native 库(JNI),又会有一次从 JVM 到 native 的内存拷贝。当这个值比较大的时候,整个过程会非常浪费。Native Buffer 就是为了解决这个问题。
Native Buffer 是由 native 创建的内存缓冲区,在 Java 里封装成 NativeBuffer 类型,可以透明传递到另一个 native 库进行访问处理。整个过程避免了先拷内存到 JVM 又从 JVM 拷回来导致的浪费。示例代码:
int sizeNeeded = kv.getValueActualSize("bytes");
NativeBuffer nativeBuffer = MMKV.createNativeBuffer(sizeNeeded);
if (nativeBuffer != null) {
int size = kv.writeValueToNativeBuffer("bytes", nativeBuffer);
Log.i("MMKV", "size Needed = " + sizeNeeded + " written size = " + size);
// destroy when you're done
MMKV.destroyNativeBuffer(nativeBuffer);
}
14.多进程访问
在初始化的时候加上标志位 MMKV.MULTI_PROCESS_MODE:
MMKV kv = MMKV.mmkvWithID("InterProcessKV", MMKV.MULTI_PROCESS_MODE);
kv.encode("bool", true);
参考资料:MMKV github