美文网首页
MMKV基本用法

MMKV基本用法

作者: 加油小李 | 来源:发表于2022-11-17 00:02 被阅读0次

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.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.tanjiajun.mmkvdemo.R
import com.tanjiajun.mmkvdemo.data.model.UserData
import com.tanjiajun.mmkvdemo.utils.*
import com.tencent.mmkv.MMKV

class 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"
}
}

相关文章

  • MMKV基本用法

    MMKV是基于mmap内存映射的key-value组件,底层序列化/反序列化使用protobuf实现,性能高,稳定...

  • MMKV 高性能的数据存取框架解读

    MMKV 目标 了解MMKV MMKV的基本应用 MMKV的原理概念 多进程设计思想 性能对比 源码解读 简介 M...

  • MMKV介绍与使用-用来替代android SharePrefe

    最近微信开源了MMKV项目如下https://github.com/Tencent/MMKV MMKV是基于mma...

  • 源码浅析 - MMKV iOS 1.0 (deprecated)

    本篇内容已过期 请移步:MMKV 1.1.1 MMKV(官方介绍) MMKV 是基于 mmap 内存映射的 key...

  • 轻量级数据存储 -- MMKV

    一、使用 MMKV使用 二、原理 MMKV原理 三、封装 四、迁移

  • MMKV——2.原理

    1.MMKV——1.使用2.MMKV——2.原理 1. mmap高性能存取的基石 MMKV通过mmap 内存映射文...

  • 定时器

    setTimeout和clearTimeout基本用法 setInterval和clearInterval基本用法...

  • MMKV——1.使用

    1.MMKV——1.使用2.MMKV——2.原理 前言 MMKV是有腾讯开发的高性能key-value组件,可以完...

  • 2019-11-16

    E战到底DAY14 SUMIF和SUMIFS函数 一.基本用法 SUMIF基本用法 SUMIFS基本用法 SUMI...

  • MMKV 源码详解

    MMKV 简介 MMKV——基于 mmap 的高性能通用 key-value 组件[https://github....

网友评论

      本文标题:MMKV基本用法

      本文链接:https://www.haomeiwen.com/subject/agaexdtx.html