打赏

android 使用MMKV代替SharePreference

 

 

  • 支持的数据类型

1,支持以下 Java 语言基础类型:

boolean、int、long、float、double、byte[]
2,支持以下 Java 类和容器:

String、Set< String >
任何实现了Parcelable的类型

 

  • 添加依赖
1
2
3
dependencies {
    implementation 'com.tencent:mmkv-static:1.2.6'
}

  

  • 初始化
1
2
3
4
5
6
7
8
9
10
11
12
在自定义的Application中:
  @Override
    public void onCreate() {
        super.onCreate();
        /**
         *  腾讯MMKV存储
         *  MMKV 默认把文件存放在$(FilesDir)/mmkv/目录。在 App 启动时自定义根目录
         *  String dir = getFilesDir().getAbsolutePath() + "/mmkv_aaaa";
         *  String rootDir = MMKV.initialize(dir);
         */
        MMKV.initialize(this);
    }

  

  • 基础数据存储
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/**
 * 基础数据存储
 */
private void iniDefault() {
    /**
     * 单进程:MMKV.SINGLE_PROCESS_MODE
     * 多进程:MMKV.MULTI_PROCESS_MODE
     *
     */
    // mKv = MMKV.defaultMMKV(MMKV.SINGLE_PROCESS_MODE, "123456");
 
    // 不同业务需要区别存储,单独创建自己的实例
    // mKv = MMKV.mmkvWithID("MyID");
 
    // MMKV 支持自定义某个文件的目录
    // String relativePath = getFilesDir().getAbsolutePath() + "/mmkv_3";
    // MMKV kv = MMKV.mmkvWithID("MyID", relativePath);
 
 
    mKv = MMKV.defaultMMKV();
 
    mStr.append("************基础数据类型************\n");
    mStr.append("boolean数据类型 \n");
    mKv.encode("bool", true);
    mStr.append("key=>bool,value=>" + mKv.decodeBool("bool") + " \n\n");
 
    mStr.append("int数据类型 \n");
    mKv.encode("int", 2020);
    mStr.append("key=>int,value=>" + mKv.decodeInt("int") + " \n\n");
 
    mStr.append("long数据类型 \n");
    mKv.encode("long", Long.MAX_VALUE);
    mStr.append("key=>long,value=>" + mKv.decodeLong("long") + " \n\n");
 
    mStr.append("float数据类型 \n");
    mKv.encode("float", 3.14f);
    mStr.append("key=>float,value=>" + mKv.decodeFloat("float") + " \n\n");
 
    mStr.append("double数据类型 \n");
    mKv.encode("double", 3.141596265356677897);
    mStr.append("key=>double,value=>" + mKv.decodeDouble("double", 3.14) + " \n\n");
 
    mStr.append("string数据类型 \n");
    mKv.encode("string", "我是 MMKV");
    mStr.append("key=>string,value=>" + mKv.decodeString("string") + " \n\n");
 
 
    mStr.append("byte[]数据类型 \n");
    byte[] bytes = {'m', 'm', 'k', 'v'};
    mKv.encode("bytes", bytes);
    mStr.append("key=>bytes,value=>" + new String(mKv.decodeBytes("bytes")) + " \n\n");
 
    mStr.append("Set数据类型 \n");
    HashSet<String> set = new HashSet<>();
    set.add("H");
    set.add("U");
    set.add("A");
    set.add("N");
    set.add("G");
    mKv.encode("HashSet", set);
    mStr.append("key=>HashSet,value=>" + mKv.decodeStringSet("HashSet").toString() + " \n\n");
 
    mStr.append("存储对象 \n");
    MmkvBean mmkvBean = new MmkvBean();
    mmkvBean.setAge(25);
    mmkvBean.setName("huangxiaoguo");
    mmkvBean.setNum("1201961031");
    mKv.encode("mmkvBean", mmkvBean);
    MmkvBean mmkvBean1 = mKv.decodeParcelable("mmkvBean", MmkvBean.class);
    mStr.append("存储对象数据:" + mmkvBean1.toString() + " \n\n");
 
    mTextView.setText(mStr.toString());
}

  

  • 删除 & 查询
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
 * 删除 & 查询
 */
private void initContainRemove() {
    mStr.append("\n************删除 & 查询************\n");
 
    mStr.append("删除单个指定key \n");
    mKv.removeValueForKey("bool");
    mStr.append("key=>bool,value=>" + mKv.decodeBool("bool") + " \n\n");
 
    mStr.append("删除多个指定key \n");
    mKv.removeValuesForKeys(new String[]{"int", "long"});
    mStr.append("key=>int,long,value=>" + mKv.decodeBool("int") + "-----" + mKv.decodeBool("long") + " \n\n");
 
    mStr.append("查询所有数据 \n");
    mStr.append("所有数据:" + Arrays.toString(mKv.allKeys()) + " \n\n");
 
    mStr.append("查询是否存在某个数据 \n");
    boolean hasStringKey = mKv.containsKey("string");
    boolean hasString = mKv.contains("string");
    mStr.append("是否存在string====>hasStringKey:" + hasStringKey + "; hasString:" + hasString + " \n\n");
 
    mStr.append("清楚数据 \n");
    mKv.clearAll();
    boolean string = mKv.containsKey("string");
    mStr.append("清除后是否有数据:" + string + " \n\n");
 
    mTextView.setText(mStr.toString());
}

  

  • 如何涉及到SharedPreferences 迁移
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//SharedPreferences preferences = getSharedPreferences("myData", MODE_PRIVATE);
MMKV preferences = MMKV.mmkvWithID("MyID");
// 迁移旧数据
{
    SharedPreferences old_SP = getSharedPreferences("MyID", MODE_PRIVATE);
    preferences.importFromSharedPreferences(old_SP);
    old_SP.edit().clear().commit();
}
// 跟以前用法一样
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("bool", true);
editor.putInt("int", Integer.MIN_VALUE);
editor.putLong("long", Long.MAX_VALUE);
editor.putFloat("float", -3.14f);
editor.putString("string", "HUANG");
HashSet<String> set = new HashSet<String>();
set.add("H");
set.add("U");
set.add("A");
set.add("N");
set.add("G");
editor.putStringSet("set", set);
// 无需调用 commit()
//editor.commit();

  

  • 工具类封装
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
package aa.datastore.mmkv.utils;
 
import android.os.Parcelable;
 
import com.tencent.mmkv.MMKV;
 
import java.util.Collections;
import java.util.Set;
 
public class SpUtils {
 
    private static MMKV mkv;
 
    private SpUtils() {
        mkv = MMKV.defaultMMKV();
    }
 
    public static SpUtils getInstance() {
        return SingletonHolder.sInstance;
    }
 
    //静态内部类
    private static class SingletonHolder {
        private static final SpUtils sInstance = new SpUtils();
    }
 
    /**
     * 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
     *
     * @param key
     * @param object
     */
    public static void encode(String key, Object object) {
        if (object instanceof String) {
            mkv.encode(key, (String) object);
        } else if (object instanceof Integer) {
            mkv.encode(key, (Integer) object);
        } else if (object instanceof Boolean) {
            mkv.encode(key, (Boolean) object);
        } else if (object instanceof Float) {
            mkv.encode(key, (Float) object);
        } else if (object instanceof Long) {
            mkv.encode(key, (Long) object);
        } else if (object instanceof Double) {
            mkv.encode(key, (Double) object);
        } else if (object instanceof byte[]) {
            mkv.encode(key, (byte[]) object);
        } else {
            mkv.encode(key, object.toString());
        }
    }
 
    public static void encodeSet(String key, Set<String> sets) {
        mkv.encode(key, sets);
    }
 
    public static void encodeParcelable(String key, Parcelable obj) {
        mkv.encode(key, obj);
    }
 
    /**
     * 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
     *
     * @param key
     * @param defaultObject
     * @return
     */
    public static Object decode(String key, Object defaultObject) {
        if (defaultObject instanceof String) {
            return mkv.decodeString(key, (String) defaultObject);
        } else if (defaultObject instanceof Integer) {
            return mkv.decodeInt(key, (Integer) defaultObject);
        } else if (defaultObject instanceof Boolean) {
            return mkv.decodeBool(key, (Boolean) defaultObject);
        } else if (defaultObject instanceof Float) {
            return mkv.decodeFloat(key, (Float) defaultObject);
        } else if (defaultObject instanceof Long) {
            return mkv.decodeLong(key, (Long) defaultObject);
        } else if (defaultObject instanceof Double) {
            return mkv.decodeDouble(key, (Double) defaultObject);
        } else if (defaultObject instanceof byte[]) {
            return mkv.decodeBytes(key, (byte[]) defaultObject);
        }
        return defaultObject;
    }
 
    /**
     * 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
     */
    public static Integer decodeInt(String key) {
        return mkv.decodeInt(key, 0);
    }
 
    public static Double decodeDouble(String key) {
        return mkv.decodeDouble(key, 0.00);
    }
 
    public static Long decodeLong(String key) {
        return mkv.decodeLong(key, 0L);
    }
 
    public static Boolean decodeBoolean(String key) {
        return mkv.decodeBool(key, false);
    }
 
    public static Float decodeFloat(String key) {
        return mkv.decodeFloat(key, 0F);
    }
 
    public static byte[] decodeBytes(String key) {
        return mkv.decodeBytes(key);
    }
 
    public static String decodeString(String key) {
        return mkv.decodeString(key, "");
    }
 
    public static Set<String> decodeStringSet(String key) {
        return mkv.decodeStringSet(key, Collections.<String>emptySet());
    }
 
    public static Parcelable decodeParcelable(String key, Class clz) {
        return mkv.decodeParcelable(key, clz);
    }
 
    /**
     * 移除某个key对
     *
     * @param key
     */
    public static void removeKey(String key) {
        mkv.removeValueForKey(key);
    }
 
    /**
     * 移除多个key对
     *
     * @param key
     */
    public static void removeKeys(String[] key) {
        mkv.removeValuesForKeys(key);
    }
 
    /**
     * 获取全部key对
     */
    public static String[] getAllKeys() {
        return mkv.allKeys();
    }
 
    /**
     * 含有某个key
     *
     * @param key
     * @return
     */
    public static boolean hasKey(String key) {
        return mkv.containsKey(key);
    }
 
    /**
     * 含有某个key
     *
     * @param key
     * @return
     */
    public static boolean have(String key) {
        return mkv.contains(key);
    }
 
    /**
     * 清除所有key
     */
    public static void clearAll() {
        mkv.clearAll();
    }
 
    /**
     * 获取操作对象
     *
     * @return
     */
    public static MMKV getMkv() {
        return mkv;
    }
 
}

  

  • 工具类使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/**
 * 工具类使用
 */
private void iniSpUtils() {
    mStr.append("************工具类使用************\n");
    mStr.append("boolean数据类型 \n");
    SpUtils.getInstance().encode("bool", true);
    mStr.append("key=>bool,value=>" + SpUtils.getInstance().decode("bool", false) + " \n\n");
 
    mStr.append("int数据类型 \n");
    SpUtils.getInstance().encode("int", 2020);
    mStr.append("key=>int,value=>" + SpUtils.getInstance().decode("int", 0) + " \n\n");
 
    mStr.append("long数据类型 \n");
    SpUtils.getInstance().encode("long", Long.MAX_VALUE);
    mStr.append("key=>long,value=>" + SpUtils.getInstance().decode("long", 0L) + " \n\n");
 
    mStr.append("float数据类型 \n");
    SpUtils.getInstance().encode("float", 3.14f);
    mStr.append("key=>float,value=>" + SpUtils.getInstance().decode("float", 0f) + " \n\n");
 
    mStr.append("double数据类型 \n");
    SpUtils.getInstance().encode("double", 3.141596265356677897);
    mStr.append("key=>double,value=>" + SpUtils.getInstance().decode("double", 3.14) + " \n\n");
 
    mStr.append("string数据类型 \n");
    SpUtils.getInstance().encode("string", "我是 MMKV");
    mStr.append("key=>string,value=>" + SpUtils.getInstance().decode("string", "") + " \n\n");
 
 
    mStr.append("byte[]数据类型 \n");
    byte[] bytes = {'m', 'm', 'k', 'v'};
    SpUtils.getInstance().encode("bytes", bytes);
    byte[] bytes1 = {'1', '2', '3'};
    mStr.append("key=>bytes,value=>" + new String((byte[]) SpUtils.getInstance().decode("bytes", bytes1)) + " \n\n");
 
    mStr.append("Set数据类型 \n");
    HashSet<String> set = new HashSet<>();
    set.add("H");
    set.add("U");
    set.add("A");
    set.add("N");
    set.add("G");
    SpUtils.getInstance().encodeSet("HashSet", set);
    mStr.append("key=>HashSet,value=>" + SpUtils.getInstance().decodeStringSet("HashSet").toString() + " \n\n");
 
 
    mStr.append("删除单个指定key \n");
    SpUtils.getInstance().removeKey("bool");
    mStr.append("key=>bool,value=>" + SpUtils.getInstance().decodeBoolean("bool") + " \n\n");
 
    mStr.append("删除多个指定key \n");
    SpUtils.getInstance().removeKeys(new String[]{"int", "long"});
    mStr.append("key=>int,long,value=>" + SpUtils.getInstance().decodeInt("int") + "-----"
            + SpUtils.getInstance().decodeLong("long") + " \n\n");
 
    mStr.append("查询所有数据 \n");
    mStr.append("所有数据:" + Arrays.toString(SpUtils.getInstance().getAllKeys()) + " \n\n");
 
    mStr.append("查询是否存在某个数据 \n");
    boolean hasStringKey = SpUtils.getInstance().hasKey("string");
    boolean hasString = SpUtils.getInstance().have("string");
    mStr.append("是否存在string====>hasStringKey:" + hasStringKey + "; hasString:" + hasString + " \n\n");
 
    mStr.append("清楚数据 \n");
    SpUtils.getInstance().clearAll();
    boolean string = SpUtils.getInstance().hasKey("string");
    mStr.append("清除后是否有数据:" + string + " \n\n");
 
    mStr.append("存储对象 \n");
    MmkvBean mmkvBean = new MmkvBean();
    mmkvBean.setAge(25);
    mmkvBean.setName("huangxiaoguo");
    mmkvBean.setNum("1201961031");
    SpUtils.getInstance().encodeParcelable("mmkvBean", mmkvBean);
    MmkvBean mmkvBean1 = (MmkvBean) SpUtils.getInstance().decodeParcelable("mmkvBean", MmkvBean.class);
    MmkvBean mmkvBean2 = SpUtils.getInstance().getMkv().decodeParcelable("mmkvBean", MmkvBean.class);
    mStr.append("存储对象数据:" + mmkvBean1.toString() + " \n\n");
    mStr.append("存储对象数据:" + mmkvBean2.toString() + " \n\n");
 
    mTextView.setText(mStr.toString());
}

  

posted @   YY2000  阅读(445)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示