找回密码
 立即注册
查看: 208|回复: 0

MMKV基本用法

[复制链接]
发表于 2022-11-18 17:52 | 显示全部楼层 |阅读模式
MMKV是基于mmap内存映射的key-value组件,底层序列化/反序列化使用protobuf实现,性能高,稳定性强,而且Android这边还支持多进程。
不管是单线程还是多线程模型下MMVK的效率都远超sp,sqllite甚至DataStore.

基本用法:
1:在App模块的build.gradle文件里添加:
implementation 'com.tencent:mmkv:1.2.14'

2:在Application里面初始化:
public void onCreate() {      super.onCreate();     String rootDir = MMKV.initialize(this);     System.out.println("mmkv root: " + rootDir);}
CRUD 操作
MMKV 提供一个全面的实例,可以直接使用:
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")));
可以看到,MMKV在使用上还是比较简单的。

删除 & 查询:
MMKV kv = MMKV.defaultMMKV();kv.removeValueForKey("bool");System.out.println("bool: " + kv.decodeBool("bool"));kv.removeValuesForKeys(new String[]{"int", "long"});System.out.println("allKeys: " + Arrays.toString(kv.allKeys()));boolean hasBool = kv.containsKey("bool");
如果不是同业需要分区存储,也可以单独创建自己的实例:
MMKV kv = MMKV.mmkvWithID("MyID");kv.encode("bool", true);
如果业务需要多进程访问,那么在刚开始化的时候加上标志位MMKV.MULTI_PROCESS_MODE:
MMKV kv = MMKV.mmkvWithID("InterProcessKV",MMKV.MULTI_PROCESS_MODE);kv.encode("bool", true);
支持的数据类型

    支持以下Java语言基础类型:
      boolean、int、long、float、double、byte[]

    支持以下Java类和容器:
      String、Set<String>任何发现Parcelable的类型


SharedPreferences 迁移

MMKV提供了importFromSharedPreferences()函数,可以比较方便地迁移数据过来。

MMKV还额外实现了一个遍SharedPreferences、SharedPreferences.Editor这两个界面,在迁移的时候只需要三行代码即可,其他CRUD操作代码都不能用改。

  • private void testImportSharedPreferences() {    //SharedPreferences preferences = getSharedPreferences("myData", MODE_PRIVATE);    MMKV preferences = MMKV.mmkvWithID("myData");    // 迁移旧数据    {        SharedPreferences old_man = getSharedPreferences("myData", MODE_PRIVATE);        preferences.importFromSharedPreferences(old_man);        old_man.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", "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);    // 无需调用 commit()    //editor.commit();}

高级用法
封装MMKV
创建 Preferences.kt文件

  •     package com.vvkj.mmkvdemo.utils    import android.os.Parcelable    import com.tencent.mmkv.MMKV    import kotlin.properties.ReadWriteProperty    import kotlin.reflect.KProperty    private inline fun <T> MMKV.delegate(    key: String? = null,    defaultValue: T,    crossinline getter: MMKV.(String, T) -> T,    crossinline setter: MMKV.(String, T) -> Boolean    ): ReadWriteProperty<Any, T> =    object : ReadWriteProperty<Any, T> {    override fun getValue(thisRef: Any, property: KProperty<*>): T =        getter(key ?: property.name, defaultValue)    override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {        setter(key ?: property.name, value)    }}    fun MMKV.boolean(      key: String? = null,      defaultValue: Boolean = false    ): ReadWriteProperty<Any, Boolean> =      delegate(key, defaultValue, MMKV::decodeBool,             MMKV::encode)      fun MMKV.int(key: String? = null, defaultValue: Int = 0):               ReadWriteProperty<Any, Int> =      delegate(key, defaultValue, MMKV::decodeInt, MMKV::encode)  fun MMKV.long(key: String? = null, defaultValue: Long = 0L): ReadWriteProperty<Any, Long> =delegate(key, defaultValue, MMKV::decodeLong, MMKV::encode)    fun MMKV.float(key: String? = null, defaultValue: Float = 0.0F):           ReadWriteProperty<Any, Float> =delegate(key, defaultValue, MMKV::decodeFloat, MMKV::encode)    fun MMKV.double(key: String? = null, defaultValue: Double = 0.0): ReadWriteProperty<Any, Double> =delegate(key, defaultValue, MMKV::decodeDouble, MMKV::encode)  private inline fun <T> MMKV.nullableDefaultValueDelegate(    key: String? = null,    defaultValue: T?,    crossinline getter: MMKV.(String, T?) -> T,    crossinline setter: MMKV.(String, T) -> Boolean      ): ReadWriteProperty<Any, T> =    object : ReadWriteProperty<Any, T> {    override fun getValue(thisRef: Any, property: KProperty<*>): T =        getter(key ?: property.name, defaultValue)    override fun setValue(thisRef: Any, property: KProperty<*>,         value: T) {        setter(key ?: property.name, value)    }}    fun MMKV.byteArray(      key: String? = null,      defaultValue: ByteArray? = null  ): ReadWriteProperty<Any, ByteArray> =nullableDefaultValueDelegate(key, defaultValue, MMKV::decodeBytes, MMKV::encode)    fun MMKV.string(key: String? = null, defaultValue: String? = null):           ReadWriteProperty<Any, String> =nullableDefaultValueDelegate(key, defaultValue, MMKV::decodeString, MMKV::encode)    fun MMKV.stringSet(    key: String? = null,    defaultValue: Set<String>? = null    ): ReadWriteProperty<Any, Set<String>> =nullableDefaultValueDelegate(key, defaultValue, MMKV::decodeStringSet, MMKV::encode)  inline fun <reified T : Parcelable> MMKV.parcelable(  key: String? = null,  defaultValue: T? = null): ReadWriteProperty<Any, T> =            object : ReadWriteProperty<Any, T> {                override fun getValue(thisRef: Any, property: KProperty<*>): T =        decodeParcelable(key ?: property.name, T::class.java, defaultValue)    override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {        encode(key ?: property.name, value)    }}

调用方法:
import android.os.Bundleimport android.util.Logimport androidx.appcompat.app.AppCompatActivityimport com.tanjiajun.mmkvdemo.Rimport com.tanjiajun.mmkvdemo.data.model.UserDataimport com.tanjiajun.mmkvdemo.utils.*import com.tencent.mmkv.MMKVclass MainActivity : AppCompatActivity() {private val mmkv: MMKV by lazy { MMKV.defaultMMKV() }private var boolean by mmkv.boolean(key = "boolean", defaultValue = false)private var int by mmkv.int(key = "int", defaultValue = 0)private var long by mmkv.long("long", 0L)private var float by mmkv.float(key = "float", defaultValue = 0.0F)private var double by mmkv.double(key = "double", defaultValue = 0.0)private var byteArray by mmkv.byteArray(key = "byteArray")private var string by mmkv.string(key = "string")private var stringSet by mmkv.stringSet(key = "stringSet")private var parcelable by mmkv.parcelable<UserData>("parcelable")override fun onCreate(savedInstanceState: Bundle?) {    super.onCreate(savedInstanceState)    setContentView(R.layout.activity_main)    boolean = true    int = 100    long = 100L    float = 100F    double = 100.0    byteArray = ByteArray(100).apply {        for (i in 0 until 100) {            set(i, i.toByte())        }    }    string = "李书生"    stringSet = HashSet<String>().apply {        for (i in 0 until 100) {            add("第($i)个")        }    }    parcelable = UserData(name = "李书生", gender = "男", age = 26)    Log.i(TAG, "boolean:$boolean")    Log.i(TAG, "int:$int")    Log.i(TAG, "long:$long")    Log.i(TAG, "float:$float")    Log.i(TAG, "double:$double")    Log.i(TAG, "byteArray:$byteArray")    Log.i(TAG, "string:$string")    Log.i(TAG, "stringSet:$stringSet")    Log.i(TAG, "parcelable:$parcelable")}private companion object {    const val TAG = "Lishusheng"}}
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-24 19:37 , Processed in 0.087133 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表