600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > android mmkv使用_Android:MMKV 组件入门

android mmkv使用_Android:MMKV 组件入门

时间:2019-03-19 10:08:00

相关推荐

android mmkv使用_Android:MMKV 组件入门

一、前言:

MMKV 是腾讯开源的一款基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强,从 年中至今在微信上使用,其性能和稳定性经过了时间的验证。GitHub地址:/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"));

结果:

-02-22 16:45:51.444 13379-13379/com.sumansoul.myviewdemo D/MainActivity: bool值: true

-02-22 16:45:51.444 13379-13379/com.sumansoul.myviewdemo D/MainActivity: int值: 1204

-02-22 16:45:51.445 13379-13379/com.sumansoul.myviewdemo D/MainActivity: string值: 中国欢迎你

五、MMKV组件实现原理以及和SharedPreferences的比较

1、MMKV:

原理:MMKV是基于mmap内存映射关系的key-value组件,底层序列化/反序列化使用protobuf实现。性能高,稳定性强。从就在微信上使用,已经移植到了Android/MacOS/Windows平台

MMAP的优势:

MMAP对文件的读写操作只需要 从磁盘到用户主存的一次数据拷贝,减少了数据拷贝次数,提高了文件读写效率;

MMAP使用逻辑内存对此盘文件进行映射,操作内存就相当于操作文件,不需要开启线程,操作MMAP的速度和操作内存一样快;

MMAP提供一段可以随时写入的内存块,APP只管往里面写数据,在内存不足,进程退出的情况下由操作系统负责将数据写回到文件,不必担心Crash导致数据丢失;

2、SharedPreferences:

原理:SharedPreferences是Android提供的一种使用XML文件保存内容的机制,内部通过XML写入文件。

特点:

读写方式:直接I/O(耗时,容易出现anr)

数据格式:xml

写入方式:全量更新

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。