当前位置:   article > 正文

MMKV——基于 mmap 的高性能通用 key-value 组件_mmkv数据丢失怎么解决

mmkv数据丢失怎么解决

MMKV 原理

  • 内存准备
    通过 mmap 内存映射文件,提供一段可供随时写入的内存块,App 只管往里面写数据,由操作系统负责将内存回写到文件,不必担心 crash 导致数据丢失。

  • 数据组织
    数据序列化方面我们选用 protobuf 协议,pb 在性能和空间占用上都有不错的表现。

  • 写入优化
    考虑到主要使用场景是频繁地进行写入更新,我们需要有增量更新的能力。我们考虑将增量 kv 对象序列化后,append 到内存末尾。

  • 空间增长
    使用 append 实现增量更新带来了一个新的问题,就是不断 append 的话,文件大小会增长得不可控。我们需要在性能和空间上做个折中。

  1. dependencies {
  2. implementation 'com.tencent:mmkv:1.0.23'
  3. }

MMKV 的使用非常简单,所有变更立马生效,无需调用 syncapply。 在 App 启动时初始化 MMKV,设定 MMKV 的根目录(files/mmkv/),

  1. public class APP extends Application {
  2. @Override
  3. public void onCreate() {
  4. super.onCreate();
  5. String rootDir = MMKV.initialize(this);
  6. System.out.println("mmkv root: " + rootDir);
  7. }
  8. }

MMKV 提供一个全局的实例,可以直接使用:

  1. import com.tencent.mmkv.MMKV;
  2. //……
  3. MMKV kv = MMKV.defaultMMKV();
  4. kv.encode("bool", true);
  5. boolean bValue = kv.decodeBool("bool");
  6. kv.encode("int", Integer.MIN_VALUE);
  7. int iValue = kv.decodeInt("int");
  8. kv.encode("string", "Hello from mmkv");
  9. String str = kv.decodeString("string");

最后贴个封装类:

  1. import android.content.Context;
  2. import android.os.Parcelable;
  3. import com.tencent.mmkv.MMKV;
  4. import java.util.Collections;
  5. import java.util.Set;
  6. /**
  7. * @package name:com.sunyard.myapplication
  8. * @describe
  9. * @anthor jokerlover
  10. * @email:shengj.chen@sunyard.com
  11. * @time 2020/9/22 3:09 PM
  12. */
  13. public class SpUtils {
  14. private volatile static SpUtils mInstance;
  15. private static MMKV mv;
  16. private SpUtils(Context context) {
  17. MMKV.initialize(context);
  18. mv = MMKV.defaultMMKV();
  19. }
  20. /**
  21. * 初始化MMKV,只需要初始化一次,建议在Application中初始化
  22. *
  23. */
  24. public static SpUtils getInstance(Context context) {
  25. if (mInstance == null) {
  26. synchronized (SpUtils.class) {
  27. if (mInstance == null) {
  28. mInstance = new SpUtils(context);
  29. }
  30. }
  31. }
  32. return mInstance;
  33. }
  34. /**
  35. * 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
  36. *
  37. * @param key
  38. * @param object
  39. */
  40. public static void encode(String key, Object object) {
  41. if (object instanceof String) {
  42. mv.encode(key, (String) object);
  43. } else if (object instanceof Integer) {
  44. mv.encode(key, (Integer) object);
  45. } else if (object instanceof Boolean) {
  46. mv.encode(key, (Boolean) object);
  47. } else if (object instanceof Float) {
  48. mv.encode(key, (Float) object);
  49. } else if (object instanceof Long) {
  50. mv.encode(key, (Long) object);
  51. } else if (object instanceof Double) {
  52. mv.encode(key, (Double) object);
  53. } else if (object instanceof byte[] ) {
  54. mv.encode(key, (byte[]) object);
  55. } else {
  56. mv.encode(key, object.toString());
  57. }
  58. }
  59. public static void encodeSet(String key,Set<String> sets) {
  60. mv.encode(key, sets);
  61. }
  62. public static void encodeParcelable(String key,Parcelable obj) {
  63. mv.encode(key, obj);
  64. }
  65. /**
  66. * 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
  67. */
  68. public static Integer decodeInt(String key) {
  69. return mv.decodeInt(key, 0);
  70. }
  71. public static Double decodeDouble(String key) {
  72. return mv.decodeDouble(key, 0.00);
  73. }
  74. public static Long decodeLong(String key) {
  75. return mv.decodeLong(key, 0L);
  76. }
  77. public static Boolean decodeBoolean(String key) {
  78. return mv.decodeBool(key, false);
  79. }
  80. public static Float decodeFloat(String key) {
  81. return mv.decodeFloat(key, 0F);
  82. }
  83. public static byte[] decodeBytes(String key) {
  84. return mv.decodeBytes(key);
  85. }
  86. public static String decodeString(String key) {
  87. return mv.decodeString(key,"");
  88. }
  89. public static Set<String> decodeStringSet(String key) {
  90. return mv.decodeStringSet(key, Collections.<String>emptySet());
  91. }
  92. public static Parcelable decodeParcelable(String key) {
  93. return mv.decodeParcelable(key, null);
  94. }
  95. /**
  96. * 移除某个key对
  97. *
  98. * @param key
  99. */
  100. public static void removeKey(String key) {
  101. mv.removeValueForKey(key);
  102. }
  103. /**
  104. * 清除所有key
  105. */
  106. public static void clearAll() {
  107. mv.clearAll();
  108. }
  109. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/319237
推荐阅读
相关标签
  

闽ICP备14008679号