日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MMKV 原理以及使用

發(fā)布時(shí)間:2023/12/20 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MMKV 原理以及使用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

介紹

MMKV是基于mmap內(nèi)存映射的移動(dòng)端通用key-value組件,底層序列化/反序列化使用protobuf實(shí)現(xiàn),性能高,穩(wěn)定性強(qiáng)。從2015年中至今,在iOS微信上使用已有近3年,近期移植到Android平臺(tái),移動(dòng)端全平臺(tái)通用,并全部在Github上開源。

MMKV 原理

內(nèi)存準(zhǔn)備:
  通過 mmap 內(nèi)存映射文件,提供一段可供隨時(shí)寫入的內(nèi)存塊,App 只管往里面寫數(shù)據(jù),由操作系統(tǒng)負(fù)責(zé)將內(nèi)存回寫到文件,不必?fù)?dān)心 crash 導(dǎo)致數(shù)據(jù)丟失。
數(shù)據(jù)組織:
  數(shù)據(jù)序列化方面我們選用 protobuf 協(xié)議,pb 在性能和空間占用上都有不錯(cuò)的表現(xiàn)。考慮到我們要提供的是通用 kv 組件,key 可以限定是 string 字符串類型,value 則多種多樣(int/bool/double 等)。要做到通用的話,考慮將 value 通過 protobuf 協(xié)議序列化成統(tǒng)一的內(nèi)存塊(buffer),然后就可以將這些 KV 對(duì)象序列化到內(nèi)存中。
寫入優(yōu)化: (重點(diǎn)關(guān)注這里!!!)
  標(biāo)準(zhǔn) protobuf 不提供增量更新的能力,每次寫入都必須全量寫入。考慮到主要使用場景是頻繁地進(jìn)行寫入更新,我們需要有增量更新的能力:將增量 kv 對(duì)象序列化后,直接 append 到內(nèi)存末尾;這樣同一個(gè) key 會(huì)有新舊若干份數(shù)據(jù),最新的數(shù)據(jù)在最后;那么只需在程序啟動(dòng)第一次打開 mmkv 時(shí),不斷用后讀入的 value 替換之前的值,就可以保證數(shù)據(jù)是最新有效的。
空間增長: (還有這里!!!)
  使用 append 實(shí)現(xiàn)增量更新帶來了一個(gè)新的問題,就是不斷 append 的話,文件大小會(huì)增長得不可控。例如同一個(gè) key 不斷更新的話,是可能耗盡幾百 M 甚至上 G 空間,而事實(shí)上整個(gè) kv 文件就這一個(gè) key,不到 1k 空間就存得下。這明顯是不可取的。我們需要在性能和空間上做個(gè)折中:以內(nèi)存 pagesize 為單位申請(qǐng)空間,在空間用盡之前都是 append 模式;當(dāng) append 到文件末尾時(shí),進(jìn)行文件重整、key 排重,嘗試序列化保存排重結(jié)果;排重后空間還是不夠用的話,將文件擴(kuò)大一倍,直到空間足夠。
數(shù)據(jù)有效性:
  考慮到文件系統(tǒng)、操作系統(tǒng)都有一定的不穩(wěn)定性,我們另外增加了 crc 校驗(yàn),對(duì)無效數(shù)據(jù)進(jìn)行甄別。在 iOS 微信現(xiàn)網(wǎng)環(huán)境上,我們觀察到有平均約 70萬日次的數(shù)據(jù)校驗(yàn)不通過。

MMKV 使用

依賴:

implementation 'com.tencent:mmkv:1.0.19'

在Application里面初始化:

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);String rootDir = MMKV.initialize(this);//就這么一句話就行System.out.println("mmkv root: " + rootDir); }

支持的數(shù)據(jù)類型:

支持以下 Java 語言基礎(chǔ)類型:
boolean、int、long、float、double、byte[],String、Set<String>,任何實(shí)現(xiàn)了Parcelable的類型,對(duì)象存儲(chǔ)方式是,轉(zhuǎn)化成json串,通過字符串存儲(chǔ),使用的時(shí)候在取出來反序列化.

增:

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的寫入邏輯是:當(dāng)我們覆蓋某個(gè)值的時(shí)候,它并不會(huì)立即刪除前面的值,會(huì)保留,然后每個(gè)key,value有存儲(chǔ)限制,當(dāng)觸發(fā)存儲(chǔ)限制的時(shí)候,才會(huì)執(zhí)行刪除,這樣即使我們頻繁的覆蓋,也不會(huì)引起太多的性能損耗

刪:

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()));

改:

直接在存一遍就是.(執(zhí)行增步驟)

查:

在增的步驟里面,已經(jīng)打印可查的結(jié)果.

kv.decodeBool("bool");kv.decodeInt("int"); .....

如果不同業(yè)務(wù)需要區(qū)別存儲(chǔ),也可以單獨(dú)創(chuàng)建自己的實(shí)例:

MMKV* mmkv = MMKV.mmkvWithID("MyID"); mmkv.encode("bool", true);

SharedPreferences 遷移

MMKV preferences = MMKV.mmkvWithID("myData");// 遷移舊數(shù)據(jù){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);// 無需調(diào)用 commit()//editor.commit();

以上內(nèi)容來自官方github:https://github.com/Tencent/MMKV/wiki/android_setup_cn



作者:鵝鵝鵝曲項(xiàng)向天歌呀
鏈接:https://www.jianshu.com/p/fe8a827ceffe
來源:簡書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

總結(jié)

以上是生活随笔為你收集整理的MMKV 原理以及使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。