android 使用MMKV代替SharePreference
- 支持的数据类型
1,支持以下 Java 语言基础类型:
boolean、int、long、float、double、byte[]
2,支持以下 Java 类和容器:
String、Set< String >
任何实现了Parcelable的类型
- 添加依赖
dependencies { implementation 'com.tencent:mmkv-static:1.2.6' }
- 初始化
在自定义的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); }
- 基础数据存储
/** * 基础数据存储 */ 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()); }
- 删除 & 查询
/** * 删除 & 查询 */ 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 迁移
//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();
- 工具类封装
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; } }
- 工具类使用
/** * 工具类使用 */ 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()); }