- 可以能会导致ANR
public void apply() {
// …省略无关代码…
QueuedWork.addFinisher(awaitCommit);
Runnable postWriteRunnable = new Runnable() {
@Override
public void run() {
awaitCommit.run();
QueuedWork.removeFinisher(awaitCommit);
}
};
SharedPreferencesImpl.this.enqueueDiskWrite(mcr, postWriteRunnable);
}
public void handleStopActivity(IBinder token, boolean show, int configChanges,
PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
// …省略无关代码…
// Make sure any pending writes are now committed.
if (!r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
}
Activity stop时会等待SP的写入任务,如果SP的写入任务多且执行慢的话,可能会阻塞主线程较长时间,轻则卡顿,重则ANR。
1.2 MMKV的不足
- 没有类型信息,不支持getAll
MMKV的存储用类似于Protobuf的编码方式,只存储key和value本身,没有存类型信息(Protobuf用tag标记字段,信息更少)。
由于没有记录类型信息,MMKV无法自动反序列化,也就无法实现getAll接口。
- 读取相对较慢
SP在加载的时候已经将value反序列化存在HashMap中了,读取的时候索引到之后就能直接引用了。
而MMKV每次读取时都需要重新解码,除了时间上的消耗之外,还需要每次都创建新的对象。
不过这不是大问题,相对SP没有差很多。
- 需要引入so, 增加包体积
引入MMKV需要增加的体积还是不少的,且不说jar包和aidl文件,光是一个arm64-v8a的so就有四百多K。