-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
android_advance
MMKV is an efficient, small, easy-to-use mobile key-value storage framework used in the WeChat application. It's currently available on both Android, iOS/macOS, Win32 and POSIX.
There're some settings on MMKV that tune things to suit your need.
-
By default, MMKV prints log to logcat, which is not convenient for diagnosing online issues. You can set up MMKV log redirecting on App startup. Implement interface
MMKVHandler
, add some code like these:@Override public boolean wantLogRedirecting() { return true; } @Override public void mmkvLog(MMKVLogLevel level, String file, int line, String func, String message) { String log = "<" + file + ":" + line + "::" + func + "> " + message; switch (level) { case LevelDebug: //Log.d("redirect logging MMKV", log); break; case LevelInfo: //Log.i("redirect logging MMKV", log); break; case LevelWarning: //Log.w("redirect logging MMKV", log); break; case LevelError: //Log.e("redirect logging MMKV", log); break; case LevelNone: //Log.e("redirect logging MMKV", log); break; } }
As for a logging tool, we recommend using xlog, which also comes from the WeChat team.
-
You can turn off MMKV's logging once and for all (which we strongly disrecommend).
You should never turn MMKV's log off unless you have very strong evidence that it makes your App slow.MMKV.setLogLevel(MMKVLogLevel.LevelNone);
-
By default MMKV stores all key values in plain text on file, relying on Android's sandbox to make sure the file is encrypted. Should you worry about information leaking, you can choose to encrypt MMKV.
String cryptKey = "My-Encrypt-Key"; MMKV kv = MMKV.mmkvWithID("MyID", MMKV.SINGLE_PROCESS_MODE, cryptKey);
-
You can change the encryption key later as you like. You can also change an existing MMKV instance from encrypted to unencrypted, or vice versa.
final String mmapID = "testAES_reKey1"; // an unencrypted MMKV instance MMKV kv = MMKV.mmkvWithID(mmapID, MMKV.SINGLE_PROCESS_MODE, null); // change from unencrypted to encrypted kv.reKey("Key_seq_1"); // change encryption key kv.reKey("Key_seq_2"); // change from encrypted to unencrypted kv.reKey(null);
-
By default, MMKV stores file inside
$(FilesDir)/mmkv/
. You can customize MMKV's root directory on App startup:String dir = getFilesDir().getAbsolutePath() + "/mmkv_2"; String rootDir = MMKV.initialize(dir); Log.i("MMKV", "mmkv root: " + rootDir);
-
You can even customize any MMKV instance's location:
String relativePath = getFilesDir().getAbsolutePath() + "/mmkv_3"; MMKV kv = MMKV.mmkvWithID("testCustomDir", relativePath);
Note: It's recommended to store MMKV files inside your App's sandbox path. DO NOT store them on external storage(aka SD card). If you have to do it, you should follow Android's scoped storage enforcement.
-
Some Android devices with API level 19 might have problems when installing/updating APK, aka missing libmmkv.so. As a result, you might face
java.lang.UnsatisfiedLinkError
crash. There's an open-source project ReLinker that fixes this problem. You can use it to load MMKV:String dir = getFilesDir().getAbsolutePath() + "/mmkv"; MMKV.initialize(dir, new MMKV.LibLoader() { @Override public void loadLibrary(String libName) { ReLinker.loadLibrary(MyApplication.this, libName); } });
-
Typically, when a
String
orbyte[]
value is getting from MMKV, there's a memory copying from native to JVM. And if that value is passed to another native library(JNI) immediately, another memory-copying from JVM to native happens. The whole process wastes too much if that value's size is large. Here comes the Native Buffer to the rescue.
Native Buffer is a memory buffer created in native, wrapped asNativeBuffer
in Java, which can be passed to another native library transparently. This process saves memory-copying to & from JVM. Example code:int sizeNeeded = kv.getValueActualSize("bytes"); NativeBuffer nativeBuffer = MMKV.createNativeBuffer(sizeNeeded); if (nativeBuffer != null) { int size = kv.writeValueToNativeBuffer("bytes", nativeBuffer); Log.i("MMKV", "size Needed = " + sizeNeeded + " written size = " + size); // pass nativeBuffer to another native library // ... // destroy when you're done MMKV.destroyNativeBuffer(nativeBuffer); }
-
By default, MMKV discards all data when there's a CRC check fail, or file length is not correct, which might happen on accidentally shutdown. You can tell MMKV to recover as much data as possible. The repair rate is not promised, though. And you might get unexpected key values from recovery. Implement interface
MMKVHandler
, add some code like these:@Override public MMKVRecoverStrategic onMMKVCRCCheckFail(String mmapID) { return MMKVRecoverStrategic.OnErrorRecover; } @Override public MMKVRecoverStrategic onMMKVFileLengthError(String mmapID) { return MMKVRecoverStrategic.OnErrorRecover; }
-
You can use MMKV's backup & restore API to backup your data to somewhere else, and restore them later.
String backupRootDir = getFilesDir().getAbsolutePath() + "/mmkv_backup_3"; // backup one instance boolean ret = MMKV.backupOneToDirectory(mmapID, backupRootDir, null); // backup all instances long count = MMKV.backupAllToDirectory(backupRootDir); // restore one instance ret = MMKV.restoreOneMMKVFromDirectory(mmapID, backupRootDir, otherDir); // restore all instances count = MMKV.restoreAllFromDirectory(backupRootDir);
-
Starting from v1.3.0, you can upgrade MMKV to auto key expiration. Note that this is a breaking change. Once upgraded to auto key expiration, the file is not valid for any older version of MMKV (<= v1.2.16) to operate correctly.
-
Global Expiration. The most simple way to do it is to turn on auto key expiration for all keys in the whole file.
// expire in a day mmkv.enableAutoKeyExpire(MMKV.ExpireInDay); // MMKV.ExpireInDay = 24 * 60 * 60
Or, if you prefer, you can enable auto key expiration without setting a global expiration duration. In this case, each key is not expired by default.
// enable auto key expiration without global duration mmkv.enableAutoKeyExpire(MMKV.ExpireNever); // MMKV.ExpireNever = 0
-
Individual Expiration. You can set a special expiration duration for a key, regardless with the file has a global duration or not. Note that you have to enable auto key expiration first.
// enable auto key expiration with an hour duration mmkv.enableAutoKeyExpire(MMKV.ExpireInHour); // MMKV.ExpireInHour = 60 * 60 // set a key with the file's global expiration duration, aka MMKV.ExpireInHour mmkv.encode("key_1", "some value"); // set a special key that expires in two hours mmkv.encode("key_2", "some value", 2 * 60 * 60); // set a special key that never expires mmkv.encode("key_3", "some value", MMKV.ExpireNever);
Or, if you prefer, you can enable auto key expiration without setting a global expiration duration. In this case, each key is not expired by default.
// enable auto key expiration without global duration mmkv.enableAutoKeyExpire(MMKV.ExpireNever); // MMKV.ExpireNever = 0 // set a key that never expires mmkv.encode("key_1", "some value"); // set a special key that expires in an hour mmkv.encode("key_2", "some value", MMKV.ExpireInHour);
-
The expire duration is counted in seconds. MMKV has some pre-defined duration for your convenience. You can use any other duration you prefer. For example, expiration in a week is
7 * 24 * 60 * 60
.ExpireNever = 0; ExpireInMinute = 60; ExpireInHour = 60 * 60; ExpireInDay = 24 * 60 * 60; ExpireInMonth = 30 * 24 * 60 * 60; ExpireInYear = 365 * 30 * 24 * 60 * 60;
MMKV is published under the BSD 3-Clause license. For details check out the LICENSE.TXT.
Check out the CHANGELOG.md for details of change history.
If you are interested in contributing, check out the CONTRIBUTING.md, also join our Tencent OpenSource Plan.
To give clarity of what is expected of our members, MMKV has adopted the code of conduct defined by the Contributor Covenant, which is widely used. And we think it articulates our values well. For more, check out the Code of Conduct.
Check out the FAQ first. Should there be any questions, don't hesitate to create issues.
User privacy is taken very seriously: MMKV does not obtain, collect or upload any personal information. Please refer to the MMKV SDK Personal Information Protection Rules for details.
- In English
- 中文
- In English
- 中文
- In English
- 中文
-
In English
-
中文
-
Golang