android mmkv使用_Android:MMKV 组件入门
一、前言:
MMKV 是騰訊開源的一款基于 mmap 內存映射的 key-value 組件,底層序列化/反序列化使用 protobuf 實現,性能高,穩定性強,從 2015 年中至今在微信上使用,其性能和穩定性經過了時間的驗證。GitHub地址:https://github.com/Tencent/MMKV
1、為什么要替代SharedPreferences?
1,數據加密。 在 Android 環境里,數據加密是非常必須的,SP實際上是把鍵值對放到本地文件中進行存儲。如果要保證數據安全需要自己加密,MMKV 使用了 AES CFB-128 算法來加密/解密。
2,多進程共享。系統自帶的 SharedPreferences 對多進程的支持不好。現有基于 ContentProvider 封裝的實現,雖然多進程是支持了,但是性能低下,經常導致 ANR。考慮到 mmap 共享內存本質上是多進程共享的,MMKV 在這個基礎上,深入挖掘了 Android 系統的能力,提供了可能是業界最高效的多進程數據共享組件。
3,匿名內存。 在多進程共享的基礎上,考慮到某些敏感數據(例如密碼)需要進程間共享,但是不方便落地存儲到文件上,直接用 mmap 不合適。而Android 系統提供了 Ashmem 匿名共享內存的能力,它在進程退出后就會消失,不會落地到文件上,非常適合這個場景。MMKV 基于此也提供了 Ashmem(匿名共享內存) MMKV 的功能。
4,效率更高。MMKV 使用protobuf進行序列化和反序列化,比起SP的xml存放方式,更加高效。
5,支持從 SP遷移,如果你之前項目里面都是使用SP,現在想改為使用MMKV,只需幾行代碼即可將之前的SP實現遷移到MMKV。
2、支持的數據類型
1,支持以下 Java 語言基礎類型:
boolean、int、long、float、double、byte[]
2,支持以下 Java 類和容器:
String、Set< String >
任何實現了Parcelable的類型
二、使用:
1、添加依賴
dependencies {
implementation 'com.tencent:mmkv-static:1.2.7'
}
2、初始化
在自定義的Application中:
MMKV.initialize(this);
3、數據操作(工具類封裝)
MMKV 提供一個全局的實例,可以直接使用:
MMKV kv = MMKV.defaultMMKV();
kv.encode("bool", true);
kv.encode("int", Integer.MIN_VALUE);
kv.encode("float", -3.14f);
kv.encode("string", "Hello from mmkv");
byte[] bytes = {'m', 'm', 'k', 'v'};
kv.encode("bytes",bytes);
//打印結果:
Timber.d("bool值: "+ kv.decodeBool("bool"));
Timber.d("int值: "+ kv.decodeInt("int"));
Timber.d("float值: "+ kv.decodeFloat("float"));
Timber.d("string值: "+ kv.decodeString("string"));
Timber.d("bytes值: "+ new String(kv.decodeBytes("bytes")));
Timber.d("1是否包含: "+ kv.containsKey("stringName"));
Timber.d("2是否包含: "+ kv.containsKey("stringffName"));
結果:
com.sumansoul.myviewdemo D/MainActivity: bool值: true
com.sumansoul.myviewdemo D/MainActivity: int值: -2147483648
com.sumansoul.myviewdemo D/MainActivity: float值: -3.14
com.sumansoul.myviewdemo D/MainActivity: string值: Hello from mmkv
com.sumansoul.myviewdemo D/MainActivity: bytes值: mmkv
com.sumansoul.myviewdemo D/MainActivity: 1是否包含: true
com.sumansoul.myviewdemo D/MainActivity: 2是否包含: false
4、刪除 & 查詢:
MMKV kv = MMKV.defaultMMKV();
kv.removeValueForKey("bool");
System.out.println("bool: " + kv.decodeBool("bool"));
kv.removeValuesForKeys(new String[]{"int", "long"});
System.out.println("allKeys: " + Arrays.toString(kv.allKeys()));
kv.clearAll();
boolean hasBool = kv.containsKey("bool");
5、如果不同業務需要區別存儲,也可以單獨創建自己的實例:
MMKV mmkv = MMKV.mmkvWithID("MyID");
mmkv.encode("bool", true);
6、默認是支持單進程的,如果業務需要多進程訪問,那么在初始化的時候加上標志位 MMKV.MULTI_PROCESS_MODE:
MMKV mmkv = MMKV.mmkvWithID("InterProcessKV", MMKV.MULTI_PROCESS_MODE);
mmkv.encode("bool", true);
三、自定義根目錄
MMKV 默認把文件存放在$(FilesDir)/mmkv/目錄。你可以在 App 啟動時自定義根目錄:
String dir = getFilesDir().getAbsolutePath() + "/mmkv_2";
String rootDir = MMKV.initialize(dir);
Log.i("MMKV", "mmkv root: " + rootDir);
MMKV 甚至支持自定義某個文件的目錄:
String relativePath = getFilesDir().getAbsolutePath() + "/mmkv_3";
MMKV kv = MMKV.mmkvWithID("testCustomDir", relativePath);
四、工具類封裝如下:
1、工具類:
public class SpUtils {
private static SpUtils mInstance;
private static MMKV mv;
private SpUtils() {
mv = MMKV.defaultMMKV();
}
/**
* 初始化MMKV,只需要初始化一次,建議在Application中初始化
*
*/
public static SpUtils getInstance() {
if (mInstance == null) {
synchronized (SpUtils.class) {
if (mInstance == null) {
mInstance = new SpUtils();
}
}
}
return mInstance;
}
/**
* 保存數據的方法,我們需要拿到保存數據的具體類型,然后根據類型調用不同的保存方法
*
* @param key
* @param object
*/
public static void encode(String key, Object object) {
if (object instanceof String) {
mv.encode(key, (String) object);
} else if (object instanceof Integer) {
mv.encode(key, (Integer) object);
} else if (object instanceof Boolean) {
mv.encode(key, (Boolean) object);
} else if (object instanceof Float) {
mv.encode(key, (Float) object);
} else if (object instanceof Long) {
mv.encode(key, (Long) object);
} else if (object instanceof Double) {
mv.encode(key, (Double) object);
} else if (object instanceof byte[] ) {
mv.encode(key, (byte[]) object);
} else {
mv.encode(key, object.toString());
}
}
public static void encodeSet(String key, Set sets) {
mv.encode(key, sets);
}
public static void encodeParcelable(String key, Parcelable obj) {
mv.encode(key, obj);
}
/**
* 得到保存數據的方法,我們根據默認值得到保存的數據的具體類型,然后調用相對于的方法獲取值
*/
public static Integer decodeInt(String key) {
return mv.decodeInt(key, 0);
}
public static Double decodeDouble(String key) {
return mv.decodeDouble(key, 0.00);
}
public static Long decodeLong(String key) {
return mv.decodeLong(key, 0L);
}
public static Boolean decodeBoolean(String key) {
return mv.decodeBool(key, false);
}
public static Float decodeFloat(String key) {
return mv.decodeFloat(key, 0F);
}
public static byte[] decodeBytes(String key) {
return mv.decodeBytes(key);
}
public static String decodeString(String key) {
return mv.decodeString(key,"");
}
public static Set decodeStringSet(String key) {
return mv.decodeStringSet(key, Collections.emptySet());
}
public static Parcelable decodeParcelable(String key) {
return mv.decodeParcelable(key, null);
}
/**
* 移除某個key對
*
* @param key
*/
public static void removeKey(String key) {
mv.removeValueForKey(key);
}
/**
* 清除所有key
*/
public static void clearAll() {
mv.clearAll();
}
/**
* 是否包含某個key
*/
public static boolean containsKey(String key) {
return mv.containsKey(key);
}
}
2、在application中初始化:
//數據存儲初始化
MMKV.initialize(this);
SpUtils.getInstance();
3、Activity中使用:
SpUtils.encode("stringName","中國歡迎你");
SpUtils.encode("boolName",true);
SpUtils.encode("intName",1204);
//打印日志
Timber.d("bool值: "+ SpUtils.decodeBoolean("boolName"));
Timber.d("int值: "+ SpUtils.decodeInt("intName"));
Timber.d("string值: "+ SpUtils.decodeString("stringName"));
結果:
2021-02-22 16:45:51.444 13379-13379/com.sumansoul.myviewdemo D/MainActivity: bool值: true
2021-02-22 16:45:51.444 13379-13379/com.sumansoul.myviewdemo D/MainActivity: int值: 1204
2021-02-22 16:45:51.445 13379-13379/com.sumansoul.myviewdemo D/MainActivity: string值: 中國歡迎你
五、MMKV組件實現原理以及和SharedPreferences的比較
1、MMKV:
原理:MMKV是基于mmap內存映射關系的key-value組件,底層序列化/反序列化使用protobuf實現。性能高,穩定性強。從2015年就在微信上使用,已經移植到了Android/MacOS/Windows平臺
MMAP的優勢:
MMAP對文件的讀寫操作只需要 從磁盤到用戶主存的一次數據拷貝,減少了數據拷貝次數,提高了文件讀寫效率;
MMAP使用邏輯內存對此盤文件進行映射,操作內存就相當于操作文件,不需要開啟線程,操作MMAP的速度和操作內存一樣快;
MMAP提供一段可以隨時寫入的內存塊,APP只管往里面寫數據,在內存不足,進程退出的情況下由操作系統負責將數據寫回到文件,不必擔心Crash導致數據丟失;
2、SharedPreferences:
原理:SharedPreferences是Android提供的一種使用XML文件保存內容的機制,內部通過XML寫入文件。
特點:
讀寫方式:直接I/O(耗時,容易出現anr)
數據格式:xml
寫入方式:全量更新
總結
以上是生活随笔為你收集整理的android mmkv使用_Android:MMKV 组件入门的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是BSP工程师?
- 下一篇: android tv 应用安装器,论An