1, SharedPreferences
Unlike the way files are stored, if you want to save a relatively small set of key values, you should use the SharedReferences API. The SharedReferences object points to a file containing key value pairs and provides simple read and write methods.
This article starts with SharedReferences and gradually introduces Preference and MMKV.
1.1 get SharedPreferences object
To use SharedPreferences to store data, you first need to get the SharedPreferences object. Android mainly provides two methods to get SharedPreferences objects.
getSharedPreferences() method in Context class
This method receives two parameters:
-
The first parameter is used to specify the name of the SharedPreferences file. If the specified file does not exist, one will be created. The SharedPreferences files are stored in / data / data / < package name > / shared_ In the prefs / directory.
-
The second parameter is used to specify the operation mode. At present, there is only mode_ The private mode is optional. It is the default operation mode and has the same effect as passing in 0 directly. It means that only the current application can read and write this SharedPreferences file.
getPreferences() method in Activity class
This method is very similar to the getSharedPreferences() method in Context, but it only receives an operation mode parameter, because when using this method, the currently active class name will be automatically used as the file name of SharedPreferences.
Note: mode has been deprecated since API level 17_ WORLD_ Readable and MODE_WORLD_WRITEABLE mode. If used, a SecurityException is thrown.
The getSharedPreferences() method in the Context class is used here:
public class SPUtils { //File name saved in the phone public static final String FILE_NAME = "scc_data"; private static final SPUtils spUtils = new SPUtils(); public static SPUtils getInstance() { return spUtils; } private SPUtils() { } private SharedPreferences getSP() { return AppGlobalUtils.getApplication().getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); } }
File saving path: / data / data / com scc. datastorage/shared_ prefs/scc_ data. xml
1.2 write data
Pass the key and value to be written through methods such as putInt() and putString(). Then call apply() or commit() to save the changes.
private void putSp() { SPUtils.getInstance().put("name","Scc"); SPUtils.getInstance().put("age",20); } /** * For the method of saving data, we need to get the specific type of saved data, and then call different saving methods according to the type * If only individual types such as String are used, the method can be written separately */ public void put(String key, Object value) { if(MStringUtils.isNullOrEmpty(key)){ return; } SharedPreferences.Editor editor = getSP().edit(); if (value instanceof String) { editor.putString(key, (String)value); } else if (value instanceof Integer) { editor.putInt(key, (Integer) value); } else if (value instanceof Boolean) { editor.putBoolean(key, (Boolean) value); } else if (value instanceof Float) { editor.putFloat(key, (Float) value); } else if (value instanceof Long) { editor.putLong(key, (Long) value); } SharedPreferencesCompat.apply(editor); }
1.3 reading data
Call getInt() and getString() to get data from SharedPreference and provide the key of the required value. If the key does not exist, you can also choose to return the default value.
private void getSp() { Log.e("SP","SpString:"+SPUtils.getInstance().getString("name")); Log.e("SP","SpInt:"+SPUtils.getInstance().getInt("age")); } //Get String type data public String getString(String key) { if (MStringUtils.isNullOrEmpty(key)) { return ""; } return getSP().getString(key, ""); } //Get Int type data public Integer getInt(String key) { if (MStringUtils.isNullOrEmpty(key)) { return 0; } return getSP().getInt(key, 0); }
1.4 deleting data
Call the remove() method to delete the data from SharedPreference and provide the key for the desired value.
private void removeSp() { SPUtils.getInstance().remove("name"); Log.e("SP","Remove:"+SPUtils.getInstance().getString("name")); Log.e("SP","SpInt:"+SPUtils.getInstance().getInt("age")); } //Remove the corresponding value of a key value public void remove(String key) { if (!MStringUtils.isNullOrEmpty(key)) { SharedPreferences.Editor editor = getSP().edit(); editor.remove(key); SharedPreferencesCompat.apply(editor); } }
Then let's look at SCC_ data. Content of XML:
Some simple key value pairs can be stored using shared preference, such as login account, password and some basic user information.
2, Jetpack Preferences
By default, Preference uses SharedReferences to save values. The SharedReferences API allows simple key value pairs to be read and written to saved files across application operations. The Preference Library uses a private SharedReferences instance, so only your application can access it.
Since I rarely use Jetpack Preferences here, I won't introduce them here. Those who are interested can go there Check the official documents by yourself, hey hey.
3, MMKV - high performance general key value component based on mmap
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. It has been ported to Android / macOS / Win32 / POSIX platform and is open source.
3.1 MMKV advantages
-
Very efficient: MMKV uses mmap to keep memory synchronization with files. The operating system is responsible for writing memory back to files. There is no need to worry about data loss caused by crash. Use protobuf to encode / decode values and make full use of Android to achieve the best performance.
-
Multi process Concurrency: MMKV supports concurrent read-write access between processes.
-
Easy to use: you can use MMKV at any time. All changes are saved immediately without synchronization or application calls. Similar to SharedReferences, it can be used directly
-
A few files (small): MMKV contains process locks, encoding / decoding helpers, mmap logic, and so on. It's neat.
3.2 performance comparison (excerpted from MMKV official)
We compare MMKV with SharedPreferences and SQLite and repeat the learning operation 1k times. The relevant test code is in. The result becomes Android/MMKV/mmkvdemo / chart.
(the test operation machine is Huawei Mate 20 Pro 128G and Android 10, each group is repeated 1k times, and the time unit is ms)
It can be seen from the single performance process that the shared preferences & SQLite on MMKV has similar or superior performance in reading performance.
Multi process performance: MMMKV far exceeds multiprocesssharedpreferences & SQLite & SQLite in both write performance and read performance. MMKV is the best choice for Android multi process key value storage components.
3.3 Android access guide
3.3.1 import dependency
In your project's app_module corresponds to build Add the following dependencies to gradle:
dependencies { implementation 'com.tencent:mmkv:1.2.12' }
3.3.2 initialization
The use of MMKV is very simple. All changes take effect immediately without calling sync and apply. Initialize MMKV when App starts, and set the root directory of MMKV (files/mmkv /), preferably in Application:
public void onCreate() { super.onCreate(); //Initialize MMKV String rootDir = MMKV.initialize(this); Log.e("SP","mmkv root: " + rootDir); }
3.3.3 write data
private void putMMKV() { MMKVUtils.getInstance().encode("name","mmkv-Scc"); MMKVUtils.getInstance().encode("age",40); } //For the method of saving data, we need to get the specific type of saved data, and then call different saving methods according to the type public void encode(String key, Object object) { if (object instanceof String) { mmkv.encode(key, (String) object); } else if (object instanceof Integer) { mmkv.encode(key, (Integer) object); } else if (object instanceof Boolean) { mmkv.encode(key, (Boolean) object); } else if (object instanceof Float) { mmkv.encode(key, (Float) object); } else if (object instanceof Long) { mmkv.encode(key, (Long) object); } else if (object instanceof Double) { mmkv.encode(key, (Double) object); } else if (object instanceof byte[]) { mmkv.encode(key, (byte[]) object); } else { mmkv.encode(key, object.toString()); } } //Save any Parcelable type public void encode(String key, Parcelable parcelable) { Log.e("mmkv","Parcelable.start"+parcelable.getClass()); boolean isTrue = mmkv.encode(key, parcelable); Log.e("mmkv","Parcelable.end"+isTrue); }
You will find that it is basically the same as the SharedReferences above. Of course, MMKV storage supports far more data types than SharedReferences. Supported data types
-
The following Java language base types are supported:
-
boolean,int,long,float,double,byte[]
-
-
The following Java classes and containers are supported:
-
String,Set<String>
-
Any Parcelable type
-
3.3.4 reading data
private void getMMKV() { Log.e("SP","MMKVString:"+MMKVUtils.getInstance().decodeString("name")); Log.e("SP","MMKVInt:"+MMKVUtils.getInstance().decodeInt("age")); } public String decodeString(String key) { return mmkv.decodeString(key, ""); } public Integer decodeInt(String key) { return mmkv.decodeInt(key, 0); }
3.3.5 removing data
private void removeMMKV() { MMKVUtils.getInstance().removeValueForKey("name"); Log.e("SP","Remove:"+MMKVUtils.getInstance().decodeString("name")); Log.e("SP","MMKVInt:"+MMKVUtils.getInstance().decodeInt("age")); } //Remove a key pair public void removeValueForKey(String key) { mmkv.removeValueForKey(key); } //Remove multiple key pairs at the same time public void removeValuesForKeys(String[] strings) { mmkv.removeValuesForKeys(strings); } //Clear all key s public void clearAll() { mmkv.clearAll(); }
3.3.6 add data extension
-
Different businesses need different storage. You can create your own instances separately.
-
If the business needs multi process access, the flag bit mmkv is added during initialization MULTI_ PROCESS_ MODE
3.4 Huawei mobile phones should use Tencent MMKV framework with caution
Problem Description:
Replace the native SharedPreference with MMKV. On some Huawei phones, the configuration file will be lost inexplicably, and the whole application will be like reinstallation.
Huawei mobile phones use Tencent MMKV framework with caution
Then you can customize the file storage path.
Default path: / data / data / com scc. Datastorage (your package name) / files/mmkv
//Custom file path. String dir = getFilesDir().getAbsolutePath()+"mmkv-z2"; String dirPath = MMKV.initialize(this,dir); //mmkv source code public static String initialize(Context context, String rootDir) { MMKVLogLevel logLevel = MMKVLogLevel.LevelInfo; return initialize(context, rootDir, (MMKV.LibLoader)null, logLevel); }
3.5 SharedPreferences migration
-
MMKV provides the importFromSharedPreferences() function to easily migrate data.
-
MMKV also implements SharedPreferences and SharedPreferences The two interface s of editor only need two or three lines of code during migration, and other CRUD operation codes do not need to be changed.
private void importSharedPreferences() { //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); //There is no need to call {commit() //editor.commit(); }
3.6 macOS / Win32 / POSIX platform
Other platforms can access the official documents by themselves.
4, Related links
Android data full solution processing