前言
SharedPreferences是谷歌提供的轻量级存储方案,使用起来比较方便,可以直接进行数据存储,不必另起线程
不过也带来很多问题,尤其是由SP引起的ANR问题,非常常见。
正因如此,后来也出现了一些SP的替代解决方案,比如MMKV
本文主要包括以下内容
1.SharedPreferences存在的问题
2.MMKV的基本使用与介绍
3.MMKV的原理
SharedPreferences存在的问题
SP的效率比较低
1.读写方式:直接I/O
2.数据格式:xml
3.写入方式:全量更新
由于SP使用的xml格式保存数据,所以每次更新数据只能全量替换更新数据
这意味着如果我们有100个数据,如果只更新一项数据,也需要将所有数据转化成xml格式,然后再通过io写入文件中
这也导致SP的写入效率比较低
commit导致的ANR
public boolean commit() {
// 在当前线程将数据保存到mMap中
MemoryCommitResult mcr = commitToMemory();
SharedPreferencesImpl.this.enqueueDiskWrite(mcr, null);
try {
// 如果是在singleThreadPool中执行写入操作,通过await()暂停主线程,直到写入操作完成。
// commit的同步性就是通过这里完成的。
mcr.writtenToDiskLatch.await();
} catch (InterruptedException e) {
return false;
}
/*
* 回调的时机:
* 1\. commit是在内存和硬盘操作均结束时回调
* 2\. apply是内存操作结束时就进行回调
*/
notifyListeners(mcr);
return mcr.writeToDiskResult;
}
复制代码
如上所示
1.commit有返回值,表示修改是否提交成功
2.commit提交是同步的,直到磁盘操作成功后才会完成
所以当数据量比较大时,使用commit很可能引起ANR
Apply导致的ANR
commit是同步的,同时SP也提供了异步的apply
apply是将修改数据原子提交到内存, 而后异步真正提交到硬件磁盘, 而commit是同步的提交到硬件磁盘,因此,在多个并发的提交commit的时候,他们会等待正在处理的commit保存到磁盘后在操作,从而降低了效率。而apply只是原子的提交到内容,后面有调用apply的函数的将会直接覆盖前面的内存数据,这样从一定程度上提高了很多效率
但是apply