SharedPreferences和MMKV使用

概述

本文主要簡述SharedPreferences存儲的使用及優(yōu)劣勢剩辟,以及MMKV內(nèi)容。

一珍德、SharedPreferences

SharedPreferences(以下使用SP簡稱)是在Android中的一種輕量級的存儲方式尉剩,支持開發(fā)者將基本類型數(shù)據(jù)以鍵值對的形式進行存儲面粮。SP具有在應(yīng)用內(nèi)數(shù)據(jù)可以共享,使用簡單方便的優(yōu)點。

SP會將數(shù)據(jù)以文件的形式進行存儲竹宋,具體路徑:

/data/data/<packagename>/shared_prefs/

下面對于SP的使用進行簡單說明劳澄。

使用

使用SP首先需要需要獲取SP對象,可以通過Context.getSharedPreferences(key, Context.MODE_PRIVATE)獲取到SP對象蜈七。

注意:Mode目前只有Context.MODE_PRIVATE秒拔,表示此文件是私有數(shù)據(jù),只能夠被應(yīng)用本身訪問飒硅,寫入覆蓋砂缩。其余的在新版API中均已廢棄。

1. 存儲數(shù)據(jù)

示例代碼如下:

var sp = this.getSharedPreferences("test",Context.MODE_PRIVATE)
        var edit = sp.edit()
        edit.putBoolean("flag",true)
        edit.putInt("temp",1)      //統(tǒng)一put完數(shù)據(jù)再提交三娩,否則可能會空異常
        edit.apply()  //edit.commit()

commit()apply()都可以提交SP存儲庵芭,但是兩者有所區(qū)別:

  1. apply()立刻更改內(nèi)存中的SP值,但是會異步的將更新寫入磁盤雀监,無返回值
  2. commit()則是會同步的寫入的磁盤双吆,需要注意其調(diào)用的線程(不要放在主線程),有返回值会前,返回是否成功的寫入存儲好乐。
2. 取數(shù)據(jù)

示例代碼如下:

        var sp = this.getSharedPreferences("test",Context.MODE_PRIVATE)
        var result = sp.getBoolean("flag",false)       //第二個參數(shù)是沒有獲取到數(shù)據(jù)的默認值

獲取到SP對象之后直接get即可,使用方便瓦宜。

二蔚万、MMKV

MMKV是騰訊開源的一款基于mmap內(nèi)存映射的鍵值對組件,底層序列化次用了prorobuf實現(xiàn)歉提,性能高且穩(wěn)定性良好笛坦,能夠很好的取代SP存儲。

1. SP的缺點和MMKV的優(yōu)勢

SP雖然簡單易用苔巨,但是在開發(fā)過程中依然存在不少缺點版扩,具體如下:

  1. 多進程共享。系統(tǒng)自帶的SP存儲對于多進程幾乎不支持侄泽,并且官方文檔上明確指出SP不能使用在多進程上礁芦,如果要實現(xiàn)SP存儲支持多進程,必須由我們手動去封裝ContentProvider實現(xiàn)悼尾,實現(xiàn)較復(fù)雜并且性能低下柿扣。
  2. 數(shù)據(jù)加密。SP存儲實際上是將鍵值對數(shù)據(jù)放到本機文件中進行存儲闺魏,如果需要數(shù)據(jù)安全需要自己加密未状。
  3. 效率一般。SP是以xml進行存儲的析桥,大量數(shù)據(jù)不能使用該方式存儲司草。
  4. 只支持基本數(shù)據(jù)類型艰垂,支持存儲的數(shù)據(jù)類型有booleans, floats, ints, longs, and strings。

針對如上的幾個缺點埋虹,MMKV都進行了改進:

  1. MMKV支持多進行共享猜憎。MMKV是基于mmap內(nèi)存映射的方式,而mmap共享內(nèi)存本質(zhì)上是多進程共享的搔课,因此MMKV是支持多進行共享并且效率較高胰柑。
  2. 數(shù)據(jù)加密。MMKV采用了AES CFB-128算法進行加密解密爬泥。
  3. MMKV采用了跨平臺的protobuf進行序列化和反序列化柬讨,比起SP的xml存放方式更加高效。
  4. 支持從SP遷移急灭。MMKV對于SP遷移做了很多支持姐浮,項目內(nèi)如果想由SP遷移到MMKV十分方便。
  5. 支持更多的數(shù)據(jù)類型葬馋,不但支持boolean卖鲤、int、long畴嘶、float蛋逾、double、byte[]窗悯,還支持String区匣,Set<String>以及實現(xiàn)了Parcelable的類型。

綜上所述蒋院,MMKV有著速度快亏钩,方便易用的優(yōu)勢,下面對其使用進行簡單說明欺旧。

2. 使用

1. 包引入及初始化

首先需要引入MMKV包姑丑,在buil.gradle中添加如下內(nèi)容:

implementation 'com.tencent:mmkv:1.2.7'

然后需要在自定義Application中添加初始化內(nèi)容:

MMKV.initialize(this)
2. MMKV對象獲取

MMKV提供了一個全局的實例,可以直接使用:

var mmkv = MMKV.defaultMMKV()

也可以自定義MMKV對象辞友,設(shè)置自定ID

var mmkv2 = MMKV.mmkvWithID("id")

MMKV默認是支持單進程的栅哀,如果業(yè)務(wù)需要多進程訪問,需要在初始化的時候添加多進程模式參數(shù):

var mmkv3 = MMKV.mmkvWithID("myId",MMKV.MULTI_PROCESS_MODE)
3. 存取方法

使用MMKV的存取比較簡單称龙,方法如下:

//存儲方法
mmkv?.encode(key,data)
//獲取方法
mmkv?.decodeString(key,"defaultValues")

獲取方法需要根據(jù)類型進行自己選擇留拾。

4. 自定義文件目錄

MMKV 默認把文件存放在$(FilesDir)/mmkv/目錄。你可以在 MMKV初始化時自定義根目錄:

val dir = filesDir.absolutePath + "/mmkv_2"
val rootDir = MMKV.initialize(dir)
5. SP遷移

MMKV可以調(diào)用importFromSharedPreferences方法進行SP的數(shù)據(jù)遷移鲫尊,示例代碼如下:
MMKV實現(xiàn)了SharedPreferences痴柔,Editor兩個接口,所以在遷移之后SP的操作代碼可以不用更改疫向。

val mmkv = MMKV.mmkvWithID("myData")
val olderData = DemoApplication.mContext?.getSharedPreferences("myData", MODE_PRIVATE)
mmkv?.importFromSharedPreferences(olderData)
olderData?.edit()?.clear()?.apply()

三竞帽、 MMKV優(yōu)勢及原理

為了能夠理清MMKV的優(yōu)勢扛施,我們首先需要先了解SP的工作原理。

1. SP的工作原理

SP是采用的IO寫入數(shù)據(jù)的屹篓,Linux中存在有虛擬內(nèi)存概念:用戶空間和內(nèi)核空間。
用戶空間是用戶程序代碼運行的地方匙奴,內(nèi)核空間是內(nèi)核代碼運行的地方堆巧。為了減小程序崩潰影響,兩個控件時隔離的泼菌,也就是說即使運行在用戶控件的用戶程序崩潰谍肤,內(nèi)核也不會受到影響。

SP采用了IO讀寫的操作哗伯,以read為例子說明荒揣,具體步驟如下:

  1. 從磁盤讀取數(shù)據(jù),將文件內(nèi)從硬盤拷貝到內(nèi)核空間的緩存區(qū)焊刹。
  2. 然后再將數(shù)據(jù)拷貝到用戶控件供程序使用系任。

從上面兩步中我們可以拷貝過程進行了兩次,如果數(shù)據(jù)量比較大虐块,性能損耗也會隨之提升俩滥。

IO讀寫.png

2. MMKV原理

MMKV的實現(xiàn)原理是mmap(內(nèi)存映射),它是共享內(nèi)存的一種(另一種是System V,可用于跨進程)贺奠,原理如圖所示:

mmap.png

在Linux中霜旧,每個進程都有著屬于自己的進程控制塊(PCB)和地址空間,通過頁面將進程的虛擬地址和物理地址進行映射儡率。mmap方法會把文件內(nèi)容映射到一段虛擬內(nèi)存上挂据,通過對此段內(nèi)存的讀取和修改,實現(xiàn)對文件的讀取和修改儿普。
在mmap之后崎逃,并不會將文件內(nèi)容直接加載到物理頁上,只是在虛擬內(nèi)存中分配了地址空間箕肃,當首次訪問這段地址時婚脱,才會去通過查找頁表,但是此時虛擬內(nèi)存對應(yīng)的頁上沒有在物理內(nèi)存中緩存勺像,則會造成“缺頁”障贸,將文件對應(yīng)內(nèi)容加載到物理內(nèi)存上。

相對于普通的IO讀寫吟宦,mmap具有如下優(yōu)勢:

  1. 對文件的讀取操作跨過了頁緩存篮洁,減少了數(shù)據(jù)的拷貝次數(shù),操作內(nèi)存就相當于操作文件殃姓,提高了文件讀取效率袁波。
  2. 實現(xiàn)了用戶空間和內(nèi)核空間的高效交互方式瓦阐,修改能夠直接反映在映射的區(qū)域內(nèi),從而被對方空間及時獲取篷牌。

當然還有如下的缺點:

  1. 即使文件很小睡蟋,甚至于只有幾個字節(jié),但是內(nèi)存的最小粒度是頁枷颊,因此會占用整頁的大小戳杀,在連續(xù)mmap小文件,會造成內(nèi)容空間的浪費夭苗。
  2. 對于變長文件不適合信卡,文件無法完成拓展。

Protobuf協(xié)議

SP存儲采用的是xml文件的形式去存儲鍵值對题造,而MMKV是通過protobuf協(xié)議來實現(xiàn)的傍菇,存儲方式為增量更新,也就是不需要每次修改數(shù)據(jù)都要重新將所有的數(shù)據(jù)寫入文件界赔,速度上和大小上都優(yōu)于xml丢习。

protobuf是Google開源的一個序列化框架,類似于xml仔蝌,json泛领,最大的特點是基于二進制,比一般的xml表示同樣的內(nèi)容要短小的多敛惊。想要了解學(xué)習(xí)的朋友可以在Protobuf官網(wǎng)學(xué)習(xí)一下渊鞋,在此不再做更多的說明。

總結(jié)

相對于SP而言瞧挤,MMKV無論是在速度上還是在文件大小上都更具有優(yōu)勢锡宋,是一個很方便易用的框架。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末特恬,一起剝皮案震驚了整個濱河市执俩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌癌刽,老刑警劉巖役首,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異显拜,居然都是意外死亡衡奥,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進店門远荠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來矮固,“玉大人,你說我怎么就攤上這事譬淳〉抵罚” “怎么了盹兢?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長守伸。 經(jīng)常有香客問我绎秒,道長,這世上最難降的妖魔是什么尼摹? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任替裆,我火速辦了婚禮,結(jié)果婚禮上窘问,老公的妹妹穿的比我還像新娘。我一直安慰自己宜咒,他們只是感情好惠赫,可當我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著故黑,像睡著了一般儿咱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上场晶,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天混埠,我揣著相機與錄音,去河邊找鬼诗轻。 笑死钳宪,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的扳炬。 我是一名探鬼主播吏颖,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼恨樟!你這毒婦竟也來了半醉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤劝术,失蹤者是張志新(化名)和其女友劉穎缩多,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體养晋,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡衬吆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了匙握。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咆槽。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖圈纺,靈堂內(nèi)的尸體忽然破棺而出秦忿,到底是詐尸還是另有隱情麦射,我是刑警寧澤,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布灯谣,位于F島的核電站潜秋,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏胎许。R本人自食惡果不足惜峻呛,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望辜窑。 院中可真熱鬧钩述,春花似錦、人聲如沸穆碎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽所禀。三九已至方面,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間色徘,已是汗流浹背恭金。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留褂策,地道東北人横腿。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像辙培,于是被迫代替她去往敵國和親蔑水。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,455評論 2 359

推薦閱讀更多精彩內(nèi)容