开局一张图先看下两者的对比:
mmkv的使用:
1.在 App 模块的 build.gradle 文件里添加:
dependencies {
implementation 'com.tencent:mmkv:1.0.22'
// replace "1.0.22" with any available version
}
2.初始化
// 设置初始化的根目录
String dir = getFilesDir().getAbsolutePath() + "/mmkv_2";
String rootDir = MMKV.initialize(dir);
Log.i("MMKV", "mmkv root: " + rootDir);
3.单进程多进程获取实例
// 获取默认的全局实例
MMKV kv = MMKV.defaultMMKV();
// 根据业务区别存储, 附带一个自己的 ID
MMKV kv = MMKV.mmkvWithID("MyID");
// 多进程同步支持
MMKV kv = MMKV.mmkvWithID("MyID", MMKV.MULTI_PROCESS_MODE);
4.CURD
// 添加/更新数据
kv.encode(key, value);
// 获取数据
int tmp = kv.decodeInt(key);
// 删除数据
kv.removeValueForKey(key);
5.数据迁移,建议迁移完成之后,通过mmkv.allkeys,方法获取所有的key和sp的总量数据做一个对比。看是否迁移完全
private void testImportSharedPreferences() {
MMKV mmkv = MMKV.mmkvWithID("myData");
SharedPreferences old_man = getSharedPreferences("myData", MODE_PRIVATE);
// 迁移旧数据
mmkv.importFromSharedPreferences(old_man);
// 清空旧数据
old_man.edit().clear().commit();
......
}
具体使用参照:腾讯官方文档
SP的使用略过
SP存在的问题
1.容易anr,无论是commit、apply、getxxx都可能导致anr。下面简单分析一下这几种情况
SharedPreferences 本身是一个接口,其具体的实现类是 SharedPreferencesImpl,而 Context 的各个和 SharedPreferences 相关的方法则是由 ContextImpl 来实现的。我们项目中的每个 SP 或多或少都是保存着一些键值对数据,而每当我们获取到一个 SharedPreferences 对象,其对应的键值对数据就会一直被保留在内存中,直到应用进程被终结(所以sp文件过大,对项目的内存占用有有很大影响),因为每个 SharedPreferences 对象都被系统作为静态变量缓存起来了,对应 ContextImpl 中的静态变量 sSharedPrefsCache
class ContextImpl extends Context {
//根据应用包名缓存所有 SharedPreferences,根据 xmlFile 和具体的 SharedPreferencesImpl 对应上
private static ArrayMap<String, ArrayMap<File, SharedPreferencesImpl>> sSharedPrefsCache;
//根据 fileName 拿到对应的 xmlFile
private ArrayMap<String, File> mSharedPrefsPaths;
}
通常我们通过sp进行读写,第一步都是获取SharedPreferences对象。这块通过文件名加载想对象的文件进入内存,所以在app刚打开的时候,如果xml文件过大,这一块会很耗时,进而可能导致getxxx出现anr。
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
···
File file;
synchronized (ContextImpl.class) {
if (mSharedPrefsPaths == null) {
mSharedPrefsPaths = new ArrayMap<>();
}
file = mSharedPrefsPaths.get(name);
if (file == null) {
file = getSharedPreferencesPath(name);
mSharedPrefsPaths.put(name, file);
}
}
return getSharedPreferences(file, mode);
}
@Override
public SharedPreferences getSharedPreferences(File file, int mode) {
SharedPreferencesImpl sp;
synchr