在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    Android Jetpack之DataStore指南

    介紹:

    官方尚未出手之前,存儲(chǔ)鍵值對(duì)等小型數(shù)據(jù)集可能普遍采用兩種方式,SharedPreferences或是MMKV(如果您需要支持大型或復(fù)雜數(shù)據(jù)集、部分更新或參照完整性,請(qǐng)考慮使用 Room,而不是 DataStore。DataStore 非常適合簡(jiǎn)單的小型數(shù)據(jù)集,不支持部分更新或參照完整性。) MMKV這次暫時(shí)不提及,因?yàn)镈atStore本身對(duì)比的也就是SharedPreferences,而且官方也是明確的建議我們遷移到DataStore。 DataStore包含了兩種實(shí)現(xiàn)方式:

    • Preferences DataStore僅使用鍵存儲(chǔ)和訪問(wèn)值數(shù)據(jù)。此實(shí)現(xiàn)不需要預(yù)定義的架構(gòu),并且不提供類型安全性。
    • Proto DataStore將數(shù)據(jù)存儲(chǔ)為自定義數(shù)據(jù)類型的實(shí)例。此實(shí)現(xiàn)要求您使用協(xié)議緩沖區(qū)(protobuf – PB協(xié)議)定義架構(gòu),但它提供類型安全性。

    與SharedPreferences的對(duì)比:

    首先我們來(lái)看官方的一張對(duì)比

    功能

    SharedPreferences

    PreferencesDataStore

    ProtoDataStore

    異步 API

    (僅用于通過(guò)監(jiān)聽(tīng)器讀取已更改的值)

    (通過(guò) Flow 以及 RxJava 2 和 3 Flowable)

    (通過(guò) Flow 以及 RxJava 2 和 3 Flowable)

    同步 API

    (但無(wú)法在界面線程上安全調(diào)用)

    可在界面線程上安全調(diào)用

    1

    (這項(xiàng)工作已在后臺(tái)移至 Dispatchers.IO)

    (這項(xiàng)工作已在后臺(tái)移至 Dispatchers.IO)

    可以提示錯(cuò)誤

    不受運(yùn)行時(shí)異常影響

    2

    包含一個(gè)具有強(qiáng)一致性保證的事務(wù)性 API

    處理數(shù)據(jù)遷移

    類型安全

    使用協(xié)議緩沖區(qū)

    我們先暫時(shí)只看PreferencesDataStore和SharedPreferences 首先同步API和異步API這兩點(diǎn)區(qū)別是沒(méi)有問(wèn)題的。 SharedPreferences:

    • apply()來(lái)完成異步操作:會(huì)立即更改內(nèi)存中的 SharedPreferences 對(duì)象,但會(huì)將更新異步寫(xiě)入磁盤。而且apply()還有個(gè)問(wèn)題就是,雖然他本身是異步的來(lái)完成IO操作,但是在SharedPreferencesImpl.EditorImpl.apply()中會(huì)添加到QueuedWork中,當(dāng)Service或者Activity啟動(dòng)或停止時(shí),具體可見(jiàn)ActivityThread中handleServiceArgs,handleStopService,handlePauseActivity,handleStopActivity均會(huì)執(zhí)行QueuedWork.waitToFinish()等待數(shù)據(jù)寫(xiě)入的完成,因?yàn)橐WC數(shù)據(jù)不會(huì)丟失,但是我們也知道,onPause() 是不適合執(zhí)行耗時(shí)操作的,因?yàn)楫?dāng)你期待另一個(gè)Activity的時(shí)候,會(huì)先onPause當(dāng)前Activity,這很明顯,假如你寫(xiě)入了較多內(nèi)容,然后立馬啟動(dòng)了另一個(gè)Activity,結(jié)果在onPause()被阻塞,就很容易導(dǎo)致ANR。
    • commit()來(lái)實(shí)現(xiàn)同步操作,但應(yīng)避免從主線程調(diào)用它,因?yàn)樗?span id="j7jos8n" class="wpcom_tag_link">可能會(huì)阻塞UI線程,這點(diǎn)沒(méi)什么好說(shuō)的,而且會(huì)返回Boolean值來(lái)表示寫(xiě)入是否成功。

    詳細(xì)的可以查看SharedPreferences.Editor接口提供的注釋,具體的實(shí)現(xiàn)在SharedPreferencesImpl.EditorImpl我這里就不貼源碼了。 回到DataStore,PreferencesDataStore本身是基于攜程Flow來(lái)實(shí)現(xiàn)的,所以異步API這點(diǎn)沒(méi)有任何問(wèn)題,不過(guò)至于同步的使用方式,放到后面來(lái)說(shuō),我們先看普遍的異步使用方式。我就不一一復(fù)述了。

    使用:

    private const val USER_PREFERENCES_NAME = “user_preferences”private val Context.dataStore by preferencesDataStore( name = USER_PREFERENCES_NAME)

    首先是通過(guò)委托拿到DataStore單例.

    public fun preferencesDataStore( name: String, corruptionHandler: ReplaceFileCorruptionHandler? = null, produceMigrations: (Context) -> List = { listOf() }, scope: CoroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob())): ReadOnlyProperty { return PreferenceDataStoreSingletonDelegate(name, corruptionHandler, produceMigrations, scope)}internal class PreferenceDataStoreSingletonDelegate internal constructor( private val name: String, private val corruptionHandler: ReplaceFileCorruptionHandler?, private val produceMigrations: (Context) -> List, private val scope: CoroutineScope) : ReadOnlyProperty { private val lock = Any() @GuardedBy(“lock”) @Volatile private var INSTANCE: DataStore? = null override fun getValue(thisRef: Context, property: KProperty): DataStore { return INSTANCE ?: synchronized(lock) { if (INSTANCE == null) { val applicationContext = thisRef.applicationContext INSTANCE = PreferenceDataStoreFactory.create( corruptionHandler = corruptionHandler, migrations = produceMigrations(applicationContext), scope = scope ) { applicationContext.preferencesDataStoreFile(name) } } INSTANCE!! } }}

    本質(zhì)上還是走的PreferenceDataStoreFactory.create()創(chuàng)建,是一個(gè)非常標(biāo)準(zhǔn)的雙重檢查鎖單例。 來(lái)看一下create()函數(shù)的參數(shù)吧

    • corruptionHandler: 異常處理,當(dāng)反序列化錯(cuò)誤時(shí)會(huì)走到這,可以用于讀取錯(cuò)誤是返回默認(rèn)值或捕獲異常。
    • migrations: 用于遷移SharedPreferences到PreferenceDataStore
    • scope: 協(xié)程的作用域,指定IO操作及數(shù)據(jù)轉(zhuǎn)換的執(zhí)行的協(xié)程作用域
    • produceFile: 基于提供的Context和name創(chuàng)建或讀取對(duì)應(yīng)的文件,默認(rèn)路徑為this.applicationContext.filesDir + datastore/fileName

    推薦做法也是通過(guò)PreferenceDataStoreFactory來(lái)創(chuàng)建DataStore實(shí)例并作為單例注入需要它的類中。

    讀?。?/h1>

    dataStore.data .catch { exception -> // 有異常拋出 if (exception is IOException) { // 使用默認(rèn)空值 emit(emptyPreferences()) } else { // 其他異常則繼續(xù)拋出 throw exception } }.map { preferences -> // 數(shù)據(jù)轉(zhuǎn)化 }.collect { // 收集數(shù)據(jù) }

    emptyPreferences()可以參考上面提到的官方教學(xué)示例,里面會(huì)詳細(xì)介紹PreferenceData的KV 可以看出dataStore返回的是一個(gè)Flow,你可以很方便的轉(zhuǎn)換成你所需要的數(shù)據(jù)。

    寫(xiě)入:

    val INT_KEY = intPreferencesKey(“int_key”)dataStore.edit { preferences -> preferences[INT_KEY] = 1}// 調(diào)用public suspend fun DataStore.edit( transform: suspend (MutablePreferences) -> Unit): Preferences { return this.updateData { // It’s safe to return MutablePreferences since we freeze it in // PreferencesDataStore.updateData() it.toMutablePreferences().apply { transform(this) } }}

    直接調(diào)用edit函數(shù),不過(guò)要注意的是edit可能會(huì)拋出異常。 同時(shí)還有兩點(diǎn)需要注意:

  • 在transform執(zhí)行完之前,在transform里改變的值并不會(huì)馬上更新到DataStore,執(zhí)行完才會(huì),所以在edit()函數(shù)成功返回之前不要認(rèn)為數(shù)據(jù)已經(jīng)寫(xiě)入成功。
  • 不要保存在transform中提供的MutablePreferences的引用,在transform外的對(duì)preferences操作并不會(huì)更新到DataStore,因?yàn)檫@很明顯破壞了原設(shè)計(jì)的原子性與事務(wù)性。
  • 總結(jié):

    總的來(lái)說(shuō)還是很推薦使用DataStore,與協(xié)程的搭配,用起來(lái)也是非常的便利,至于PB協(xié)議的ProtoDataStore,可以參考官方的示例來(lái)實(shí)踐,差別主要是還是集中在PB文件的處理。

    作者:Lowae鏈接:https://juejin.cn/post/7109395564789235720

    鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場(chǎng),版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)聯(lián)系管理員(admin#wlmqw.com)刪除。
    用戶投稿
    上一篇 2022年6月20日 12:58
    下一篇 2022年6月20日 12:58

    相關(guān)推薦

    • TES官宣knight斷開(kāi)連接!網(wǎng)友:左手就是下一個(gè)369

      2022LPL冬季轉(zhuǎn)會(huì)期已經(jīng)正式到來(lái),如果說(shuō)此次轉(zhuǎn)會(huì)期熱度最高的一支隊(duì)伍,無(wú)疑就是在2022全球總決賽中拿到四強(qiáng)成績(jī)的JDG了。因?yàn)閾?jù)目前網(wǎng)上爆料人的消息來(lái)看,JDG很有可能會(huì)通過(guò)…

      2022年11月27日
    • 存儲(chǔ)過(guò)程語(yǔ)法(sql server存儲(chǔ)過(guò)程語(yǔ)法)

      今天小編給各位分享存儲(chǔ)過(guò)程語(yǔ)法的知識(shí),其中也會(huì)對(duì)sql server存儲(chǔ)過(guò)程語(yǔ)法進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問(wèn)題,別忘了關(guān)注本站,現(xiàn)在開(kāi)始吧! oracle存儲(chǔ)過(guò)程基本語(yǔ)法…

      2022年11月26日
    • 男子賭球輸千萬(wàn)跳樓?當(dāng)?shù)鼗貞?yīng)!

      據(jù)浙江省杭州市蕭山區(qū)人民政府新聞辦公室官方微博消息,近日,關(guān)于一則“男子賭球后跳樓”的信息在網(wǎng)上流傳,經(jīng)官方核實(shí), 該信息不實(shí)。11月22日20時(shí)許,蕭山警方接群眾報(bào)警,北干街道某…

      2022年11月26日
    • 《云頂之弈》s8什么時(shí)候上線國(guó)服?s8國(guó)服上線時(shí)間介紹

      云頂之弈的s8版本為怪物來(lái)襲版本,現(xiàn)已正式在美測(cè)服上線了。很多小伙伴可能還不清楚該版本什么時(shí)候在國(guó)服上線吧,今天小編給大家?guī)?lái)云頂之弈s8國(guó)服上線時(shí)間介紹,快來(lái)看一下吧。 s8國(guó)服…

      2022年11月25日
    • 什么是推廣cpa一篇文章帶你看懂CPA推廣渠道

      CPA渠道 CPA指的是按照指定的行為結(jié)算,可以是搜索,可以是注冊(cè),可以是激活,可以是搜索下載激活,可以是綁卡,實(shí)名認(rèn)證,可以是付費(fèi),可以是瀏覽等等。甲乙雙方可以根據(jù)自己的情況來(lái)定…

      2022年11月25日
    • 早報(bào):曼聯(lián)宣布C羅離隊(duì)!

      【曼聯(lián)宣布C羅離隊(duì)】 足壇重磅!曼聯(lián)官方:C羅離隊(duì)達(dá)成一致,即刻生效??! 曼聯(lián)官方發(fā)布重磅公告,C羅將離開(kāi)曼聯(lián),立即生效。 【C羅發(fā)聲】 C羅談離隊(duì):我愛(ài)曼聯(lián),我愛(ài)紅魔球迷,這永遠(yuǎn)…

      2022年11月25日
    • 抖音直播帶貨有哪些方法技巧(抖音直播帶貨有哪些痛點(diǎn))

      如今抖音這個(gè)短視頻的變現(xiàn)能力越來(lái)越突顯了,尤其是在平臺(tái)上開(kāi)通直播,更具有超強(qiáng)的帶貨屬性,已經(jīng)有越來(lái)越多的普通人加入到其中了。不過(guò)直播帶貨雖然很火,但是也不是每個(gè)人都能做好的,那么在…

      2022年11月24日
    • iPhoneSE4價(jià)格或在3000以內(nèi) 蘋(píng)果se4最新消息

      據(jù)相關(guān)爆料,明年即將在春季發(fā)布的iPhoneSE4系列,售價(jià)可能會(huì)在3000元以內(nèi),可能會(huì)使用iPhone SE4與紅米K系列直接競(jìng)爭(zhēng),打算正式進(jìn)入2000元價(jià)位市場(chǎng)??梢钥闯觯纭?/p>

      2022年11月24日
    • 淘寶直播平臺(tái)抽成多少(淘寶直播平臺(tái)抽成比例)

      隨著時(shí)代的發(fā)展,現(xiàn)在直播帶貨已經(jīng)成為主要帶貨方式,其中淘寶是主流帶貨平臺(tái),不少人在上面直播帶貨賺錢,一些小伙伴也想加入,那么淘寶直播平臺(tái)抽成多少?下面小編為大家?guī)?lái)淘寶直播平臺(tái)抽成…

      2022年11月24日
    • 淘寶直播開(kāi)通后帶貨鏈接怎么做(淘寶直播需要開(kāi)通淘寶店鋪嗎)

      直播帶貨無(wú)論是對(duì)于商家來(lái)說(shuō)還是主播收益都是非??捎^的,所以不少平臺(tái)都有直播帶貨功能,一些小伙伴也想加入淘寶直播,那么淘寶直播開(kāi)通后帶貨鏈接怎么做?下面小編為大家?guī)?lái)淘寶直播開(kāi)通后帶…

      2022年11月24日

    聯(lián)系我們

    聯(lián)系郵箱:admin#wlmqw.com
    工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息