目錄
深入學(xué)習(xí)DataStore(一),Google為什么放棄SharedPreferences
深入學(xué)習(xí)DataStore(二),使用 Preferences DataStore存儲(chǔ)數(shù)據(jù)
深入學(xué)習(xí)DataStore(三),遷移 SharedPreferences 到 DataStore
深入學(xué)習(xí)DataStore(四),如何使用Proto DataStore數(shù)據(jù)存儲(chǔ)
Jetpack DataStore是一種用來(lái)替換SharedPreferences新型數(shù)據(jù)存儲(chǔ)解決方案
Jetpack DataStore是以 Kotlin協(xié)程
和Flow
功能為基礎(chǔ)提供了兩種方式
- Proto DataStore 存儲(chǔ)類(lèi)的對(duì)象,通過(guò) protocol buffers 將對(duì)象序列化存儲(chǔ)在本地
- Preferences DataStore 以鍵值對(duì)的形式存儲(chǔ)在本地和SharedPreferences類(lèi)似,基于 Flow 實(shí)現(xiàn)的撵术,不會(huì)阻塞主線(xiàn)程蛋铆,并且保證類(lèi)型安全
為什么Google要替換SharedPreferences
其實(shí)SharedPreferences作為一種輕量級(jí)的數(shù)據(jù)存儲(chǔ)方式,使用起來(lái)也非常方便,以鍵值對(duì)的形式存儲(chǔ)在本地级乍,初始化 SharedPreference 的時(shí)候优质,會(huì)將整個(gè)文件內(nèi)容加載內(nèi)存中竣贪,因此會(huì)帶來(lái)以下問(wèn)題:
-
getXXX()
獲取值的形式有可能會(huì)導(dǎo)致主線(xiàn)程阻塞 - SharedPreferences不能保證類(lèi)型安全, 加載的數(shù)據(jù)會(huì)一直留在內(nèi)存中,浪費(fèi)內(nèi)存
-
apply()
方法雖然是異步的巩螃,可能會(huì)發(fā)生 ANR -
apply()
方法無(wú)法獲取到操作成功或者失敗的結(jié)果
(1)為什么getXXX()方法會(huì)導(dǎo)致主線(xiàn)程阻塞
因?yàn)間etXXX()都是同步的演怎,在主線(xiàn)程調(diào)用 get 方法時(shí),同步方法內(nèi)調(diào)用了 wait() 方法避乏,會(huì)一直等待 getSharedPreferences() 方法開(kāi)啟的線(xiàn)程讀取完數(shù)據(jù)才能繼續(xù)往下執(zhí)行爷耀,如果數(shù)據(jù)量讀取的小,并沒(méi)有什么影響,如果讀取的文件較大會(huì)導(dǎo)致主線(xiàn)程阻塞
具體大家可以查看haredPreferences源碼
frameworks/base/core/java/android/app/SharedPreferencesImpl.java
(2)SharedPreferences不能保證類(lèi)型安全,并且一直會(huì)留在內(nèi)存中
看一個(gè)例子
val key = "DataStore"
val sp = getSharedPreferences("文件名", Context.MODE_PRIVATE)
sp.edit { putInt(key, 0) } // 使用 Int 類(lèi)型的數(shù)據(jù)覆蓋相同的 key
sp.getString(key, ""); // 使用相同的 key 讀取 Sting 類(lèi)型的數(shù)據(jù)
使用 Int 類(lèi)型的數(shù)據(jù)覆蓋掉相同的 key,然后使用相同的 key 讀取 Sting 類(lèi)型的數(shù)就會(huì)造成ClassCastException
異常
而通過(guò) getSharedPreferences() 方法加載的數(shù)據(jù)淑际,最后會(huì)將數(shù)據(jù)存儲(chǔ)在靜態(tài)的成員變量中畏纲。
(3)apply()方法是異步的,可能會(huì)發(fā)生ANR
異步的提交為什么會(huì)發(fā)生ANR呢,這里有一個(gè)關(guān)于這個(gè)問(wèn)題的文章分析
剖析 SharedPreference apply 引起的 ANR 問(wèn)題
DataStore帶來(lái)了哪些改變呢?
與其說(shuō)DataStore相對(duì)SharedPreference的改變,不如說(shuō)是Preferences DataStore,因?yàn)镻references DataStore主要是替換SharedPreference的,并且解決了SharedPreference所有問(wèn)題
- DataStore 是基于 Flow 實(shí)現(xiàn)的扇住,所以保證了在主線(xiàn)程的安全性
- 以事務(wù)方式處理更新數(shù)據(jù),事務(wù)有四大特性(原子性盗胀、一致性艘蹋、 隔離性、持久性)
- 沒(méi)有 apply() 和 commit() 等等數(shù)據(jù)持久的方法
- 自動(dòng)完成 SharedPreferences 遷移到 DataStore票灰,保證數(shù)據(jù)一致性女阀,不會(huì)造成數(shù)據(jù)損壞
- 可以監(jiān)聽(tīng)到操作成功或者失敗結(jié)果
目前DataStore已經(jīng)發(fā)布alpha01版本
具體可以參看JetPack DataStore