赞
踩
内存准备
通过 mmap 内存映射文件,提供一段可供随时写入的内存块,App 只管往里面写数据,由操作系统负责将内存回写到文件,不必担心 crash 导致数据丢失。
数据组织
数据序列化方面我们选用 protobuf 协议,pb 在性能和空间占用上都有不错的表现。
写入优化
考虑到主要使用场景是频繁地进行写入更新,我们需要有增量更新的能力。我们考虑将增量 kv 对象序列化后,append 到内存末尾。
空间增长
使用 append 实现增量更新带来了一个新的问题,就是不断 append 的话,文件大小会增长得不可控。我们需要在性能和空间上做个折中。
- dependencies {
- implementation 'com.tencent:mmkv:1.0.23'
- }
MMKV 的使用非常简单,所有变更立马生效,无需调用 sync
、apply
。 在 App 启动时初始化 MMKV,设定 MMKV 的根目录(files/mmkv/),
- public class APP extends Application {
- @Override
- public void onCreate() {
- super.onCreate();
- String rootDir = MMKV.initialize(this);
- System.out.println("mmkv root: " + rootDir);
- }
- }
MMKV 提供一个全局的实例,可以直接使用:
- import com.tencent.mmkv.MMKV;
- //……
-
- MMKV kv = MMKV.defaultMMKV();
-
- kv.encode("bool", true);
- boolean bValue = kv.decodeBool("bool");
-
- kv.encode("int", Integer.MIN_VALUE);
- int iValue = kv.decodeInt("int");
-
- kv.encode("string", "Hello from mmkv");
- String str = kv.decodeString("string");
最后贴个封装类:
-
-
- import android.content.Context;
- import android.os.Parcelable;
-
- import com.tencent.mmkv.MMKV;
-
- import java.util.Collections;
- import java.util.Set;
-
- /**
- * @package name:com.sunyard.myapplication
- * @describe
- * @anthor jokerlover
- * @email:shengj.chen@sunyard.com
- * @time 2020/9/22 3:09 PM
- */
- public class SpUtils {
-
- private volatile static SpUtils mInstance;
- private static MMKV mv;
-
- private SpUtils(Context context) {
- MMKV.initialize(context);
- mv = MMKV.defaultMMKV();
- }
-
- /**
- * 初始化MMKV,只需要初始化一次,建议在Application中初始化
- *
- */
- public static SpUtils getInstance(Context context) {
- if (mInstance == null) {
- synchronized (SpUtils.class) {
- if (mInstance == null) {
- mInstance = new SpUtils(context);
- }
- }
- }
- 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<String> 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<String> decodeStringSet(String key) {
- return mv.decodeStringSet(key, Collections.<String>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();
- }
-
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。