summary
Mmkv is a key value component based on mmap memory mapping. The underlying serialization / deserialization is implemented by protobuf, with high performance and strong stability. It has been used on wechat since mid-2015, and its performance and stability have been verified over time. GitHub address: https://github.com/Tencent/MMKV
MMKV principle
1) Memory preparation: a memory block that can be written at any time is provided through the mmap memory mapping file. App only writes data into it, and the operating system is responsible for writing the memory back to the file. There is no need to worry about data loss caused by crash.
2) Data organization: in terms of data serialization, we choose protobuf protocol, pb which has good performance in performance and space occupation.
3) Write Optimization: considering that the main usage scenario is frequent write updates, we need the ability of incremental updates. We consider serializing the incremental kv object and append ing it to the end of memory.
4) Space growth: using append to implement incremental updates brings a new problem, that is, if you continue to append, the file size will grow uncontrollably. We need to make a compromise between performance and space.
1. Used in Android
1.1 add dependency
dependencies { implementation 'com.tencent:mmkv-static:1.2.2'' }
one point two initialization
The use of MMKV is very simple. All changes take effect immediately without calling sync,apply. Initialize MMKV when App starts, and set the root directory of MMKV (files/mmkv /), for example, in Application Li:
public class MyApp extends Application { private static final String TAG = MyApp.class.getSimpleName(); @Override public void onCreate() { super.onCreate(); String rootDir = MMKV.initialize(this); Log.i(TAG,"mmkv root: " + rootDir); } }
1.3 CRUD operation
1) MMKV provides a global instance that can be used directly:
import com.tencent.mmkv.MMKV; ... MMKV kv = MMKV.defaultMMKV(); kv.encode("bool", true); System.out.println("bool: " + kv.decodeBool("bool")); kv.encode("int", Integer.MIN_VALUE); System.out.println("int: " + kv.decodeInt("int")); kv.encode("long", Long.MAX_VALUE); System.out.println("long: " + kv.decodeLong("long")); kv.encode("float", -3.14f); System.out.println("float: " + kv.decodeFloat("float")); kv.encode("double", Double.MIN_VALUE); System.out.println("double: " + kv.decodeDouble("double")); kv.encode("string", "Hello from mmkv"); System.out.println("string: " + kv.decodeString("string")); byte[] bytes = {'m', 'm', 'k', 'v'}; kv.encode("bytes", bytes); System.out.println("bytes: " + new String(kv.decodeBytes("bytes")));
2) Delete and query
MMKV kv = MMKV.defaultMMKV(); // Remove the specified key kv.removeValueForKey("bool"); System.out.println("bool: " + kv.decodeBool("bool")); // Remove a set of key s kv.removeValuesForKeys(new String[]{"int", "long"}); System.out.println("allKeys: " + Arrays.toString(kv.allKeys())); boolean hasBool = kv.containsKey("bool");
3) If different businesses need different storage, you can also create your own instances separately:
MMKV mmkv = MMKV.mmkvWithID("MyID"); mmkv.encode("bool", true);
4) If the business needs multi process access, add the flag bit during initialization MMKV.MULTI_PROCESS_MODE:
MMKV mmkv = MMKV.mmkvWithID("InterProcessKV", MMKV.MULTI_PROCESS_MODE); mmkv.encode("bool", true);
1.4 supported data types
1) The following Java language basic types are supported:
boolean,int,long,float,double,byte[].
2) The following Java classes and containers are supported:
String, set < string >, any type that implements Parcelable.
1.5 SharedPreferences migration
1) MMKV provides the importFromSharedPreferences() function to easily migrate data.
2) MMKV also implements two interface s, SharedPreferences and SharedPreferences.Editor, which only need two or three lines of code during migration, and other CRUD operation codes do not need to be changed
private void testImportSharedPreferences() { //SharedPreferences preferences = getSharedPreferences("myData", MODE_PRIVATE); MMKV preferences = MMKV.mmkvWithID("myData"); // Migrate old data { SharedPreferences old_man = getSharedPreferences("myData", MODE_PRIVATE); preferences.importFromSharedPreferences(old_man); old_man.edit().clear().commit(); } // Same as before 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", "hello, imported"); HashSet<String> set = new HashSet<String>(); set.add("W"); set.add("e"); set.add("C"); set.add("h"); set.add("a"); set.add("t"); editor.putStringSet("string-set", set); // No need to call commit() //editor.commit(); }