Android MMKV存储 从入门到精通

3,251 阅读3分钟

安装:

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