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()); } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于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最大的设计失误
· 单元测试从入门到精通