Jetpack DataStore 你總要了解一下吧?

      網友投稿 1205 2022-05-29

      一、DataStore 介紹

      DataStore 是 Android Jetpack 中的一個組件,它是一個數據存儲的解決方案,跟 SharedPreferences 一樣,采用key-value形式存儲。DataStore 保證原子性,一致性,隔離性,持久性。尤其是,它解決了 SharedPreferences API 的設計缺陷。Jetpack DataStore 是經過改進的新版數據存儲解決方案,旨在取代 SharedPreferences,讓應用能夠以異步、事務方式存儲數據。

      注意:DataStore 比較適合小數據和簡單操作,并且無法局部的更新數據。如果你需要支持大型或復雜的數據集、部分更新或引用完整性,請考慮使用 Room 而不是 DataStore。

      Preferences DataStore 和 Proto DataStore

      Preferences DataStore:與SharedPreferences類似,通過鍵值對存儲數據,此實現不需要預定義模式,也不提供類型安全。

      Proto DataStore:通過Protocol-Buffers定義存儲數據類型以及結構,保證類型安全。

      一、DataStore 介紹

      DataStore 是 Android Jetpack 中的一個組件,它是一個數據存儲的解決方案,跟 SharedPreferences 一樣,采用key-value形式存儲。DataStore 保證原子性,一致性,隔離性,持久性。尤其是,它解決了 SharedPreferences API 的設計缺陷。Jetpack DataStore 是經過改進的新版數據存儲解決方案,旨在取代 SharedPreferences,讓應用能夠以異步、事務方式存儲數據。

      注意:DataStore 比較適合小數據和簡單操作,并且無法局部的更新數據。如果你需要支持大型或復雜的數據集、部分更新或引用完整性,請考慮使用 Room 而不是 DataStore。

      Preferences DataStore 和 Proto DataStore

      Preferences DataStore:與SharedPreferences類似,通過鍵值對存儲數據,此實現不需要預定義模式,也不提供類型安全。

      Proto DataStore:通過Protocol-Buffers定義存儲數據類型以及結構,保證類型安全。

      本文重點了解Preferences DataStore。

      二、Preferences DataStore

      與SharedPreferences類似,通過鍵值對存儲數據,此實現不需要預定義模式,也不提供類型安全。

      2.1 添加依賴

      在你項目的app_module對應的build.gradle中添加如下依賴:

      dependencies { //Typed DataStore (Typed API surface, such as Proto) implementation "androidx.datastore:datastore:1.0.0" // //可選 - RxJava2 support // implementation "androidx.datastore:datastore-rxjava2:1.0.0" // //可選 - RxJava3 support implementation "androidx.datastore:datastore-rxjava3:1.0.0" //Preferences DataStore (SharedPreferences like APIs) implementation "androidx.datastore:datastore-preferences:1.0.0" // // 可選 - RxJava2 support // implementation "androidx.datastore:datastore-preferences-rxjava2:1.0.0" // // 可選 - RxJava3 support implementation "androidx.datastore:datastore-preferences-rxjava3:1.0.0" }

      2.2 使用 Preferences DataStore 存儲鍵值對

      首先看看 DataStore 源碼,DataStore 是一個接口。

      package androidx.datastore.core import kotlinx.coroutines.flow.Flow import java.io.IOException /** * DataStore數據存儲提供了一種安全、持久的方式來存儲少量數據,如 preferences 和應用程序狀態。 * 數據存儲提供了ACID保證。它是線程安全的,并且不阻塞。特別是,它解決了SharedReferences API的這些設計缺陷: * 1. Synchronous API encourages StrictMode violations * 2. apply() and commit() have no mechanism of signalling errors * 3. apply() will block the UI thread on fsync() * 4. Not durable – it can returns state that is not yet persisted * 5. No consistency or transactional semantics * 6. Throws runtime exception on parsing errors * 7. Exposes mutable references to its internal state */ public interface DataStore { public val data: Flow public suspend fun updateData(transform: suspend (t: T) -> T): T }

      以上可以看出 DataStore 是基于 協程 和 Flow 實現的。

      data 是一個 Flow 對象。

      updateData() 用于更新對象。

      并且查看 DataStore 的其他相關源碼你會發現他們都是基于Kotlin語言開發。Google 對于推 Kotlin 那是相當執著。

      2.2.1 創建 DataStore

      使用 preferencesDataStore(Kotlin) 創建Datastore 的實例。

      如果你使用 RxJava,要使用 RxPreferenceDataStoreBuilder。

      必需的 name 參數是 Preferences DataStore 的名稱。

      這里我們使用的是RxJava:

      RxDataStore dataStore = new RxPreferenceDataStoreBuilder(this, /*name=*/ "datastore_sc").build(); //創建使用的key Preferences.Key nameKey = PreferencesKeys.stringKey("name"); Preferences.Key ageKey = PreferencesKeys.intKey("age");

      默認路徑:/data/data/com.scc.datastorage/files/datastore/datastore_sc.preferences_pb

      這里創建了兩個key,分別是 String 類型和 Int 類型。

      2.2.1 DataStore 寫入數據

      //關于 nameKey 和 ageKey 請看上面代碼。 putString(nameKey, "name-Scc"); putInteger(ageKey, 25); //2022/1/25 功能:存入String類型的數據 private void putString(Preferences.Key nameKey, String value) { dataStore.updateDataAsync(new Function>() { @Override public Single apply(Preferences preferences) throws Throwable { MutablePreferences mutablePreferences = preferences.toMutablePreferences(); mutablePreferences.set(nameKey, value); return Single.just(mutablePreferences); } }); } //2022/1/25 功能:存入Integer類型的數據 private void putInteger(Preferences.Key ageKey, Integer value) { dataStore.updateDataAsync(new Function>() { @Override public Single apply(Preferences preferences) throws Throwable { MutablePreferences mutablePreferences = preferences.toMutablePreferences(); mutablePreferences.set(ageKey, value); return Single.just(mutablePreferences); } }); }

      這里寫入的兩種類型,這樣更加仿版理解和你寫成自己的工具類,因為使用 DataStore 比較少實踐少就不提供工具類了,以免誤導大家。

      2.2.3 DataStore 讀取數據

      getString(nameKey); getInteger(ageKey); //2022/1/25 功能:獲取String類型數據 private void getString(Preferences.Key nameKey) { Log.e("DataStore", nameKey.toString()); Flowable example = dataStore.data().map(new Function() { @Override public String apply(Preferences preferences) { Log.e("DataStore.apply", preferences.get(nameKey)); return preferences.get(nameKey); } }); Log.e("DataStore.Flowable", example.first("default").blockingGet()); } //2022/1/25 功能:獲取Integer類型數據 private void getInteger(Preferences.Key ageKey) { Log.e("DataStoreKey", ageKey.toString()); Flowable example = dataStore.data().map(new Function() { @Override public Integer apply(Preferences preferences) { Log.e("DataStore.apply", preferences.get(ageKey).intValue() + ""); return preferences.get(ageKey); } }); Log.e("DataStore.Flowable", example.first(12).blockingGet().toString()); }

      三、Proto DataStore

      Jetpack DataStore 你總要了解一下吧?

      通過Protocol-Buffers定義存儲數據類型以及結構,保證類型安全。

      Proto DataStore 實現使用 DataStore 和 Protocol-Buffers 將類型化對象持久保存到磁盤。

      什么是 Protocol-Buffers?

      Protocol-Buffers是谷歌的語言中立、平臺中立、可擴展的機制,用于序列化結構化數據——比如XML,但更小、更快、更簡單。您只需定義一次數據的結構化方式,然后就可以使用特殊生成的源代碼,輕松地在各種數據流之間以及使用各種語言編寫和讀取結構化數據。

      3.1 定義架構

      Proto DataStore 需要app/src/main/proto/目錄中的 proto 文件中的預定義模式。此架構定義了您在 Proto DataStore 中持久保存的對象的類型。

      syntax = "proto3"; option java_multiple_files = true; option java_package = "com.scc.datastorage.proto"; option java_outer_classname = "User"; message User{ string name = 1; int32 age = 2; }

      .proto 文件以包聲明開頭,這有助于防止不同項目之間的命名沖突。

      java_multiple_files:可以為每個生成的類生成一個單獨的 .java 文件。

      java_package:指定生成的類應該使用什么 Java 包名稱。如果您沒有明確指定,它只會匹配包聲明給出的包名。

      java_outer_classname:定義了類名。如果沒有設置這個 options ,它將通過將文件名轉換為大寫駝峰式來生成。例如,默認情況下,“my_proto.proto”將使用“MyProto”作為包裝類名稱。

      定義 message:

      可以使用許多標準的簡單數據類型可用作字段類型,包括 bool、int32、float、double 和 string。

      可以使用許多標準的簡單數據類型可用作字段類型,包括 bool、int32、float、double 和 string。

      還可以通過使用其他 message 類型作為字段類型來為你的消息添加進一步的結構。

      還可以通過使用其他 message 類型作為字段類型來為你的消息添加進一步的結構。

      每個元素上的 "= 1"、"= 2" 標記標識該字段在二進制編碼中使用的唯一 "tag"。

      更多關于 的內容可以去官網找找 protobuf 語言指南。

      注意:存儲對象的類是在編譯時從 proto 文件中定義的message生成的。確保你 rebuild 你的項目。

      3.2 創建 Proto DataStore

      1.定義一個實現 Serializer 的類,其中 T 是 proto 文件中定義的類型。

      2.使用 dataStore 創建的屬性委托來創建 DataStore 的實例,其中 T 是 proto 文件中定義的類型。

      寫到這里 proto 文件中定義的類無法生成,也嘗試了很多辦法,不知道什么情況。后續步驟可參照官網,其他方法和Preferences DataStore類似。就不占用篇幅了。

      相關鏈接

      官方文檔 DataStore;

      個人感覺 DataStore 還是沒有 SP 和 MMKV 好用,推薦使用 MMKV 畢竟上線好幾年了,而且是大廠推出,相對穩定一些,有些個人自己實現了 SP 的功能,但是萬一有 Bug 或者突然不繼續維護了是不是就尷尬了。

      Android Java

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:Spark 與 Python 簡介 – PySpark 初學者
      下一篇:RDS快速入門【玩轉華為云】
      相關文章
      国产精品亚洲A∨天堂不卡| 久久亚洲中文字幕精品一区| 亚洲精品无码精品mV在线观看| 亚洲色精品三区二区一区| 亚洲av无码久久忘忧草| 亚洲国产日韩在线人成下载| 亚洲黄色网址大全| 精品日韩亚洲AV无码一区二区三区 | 亚洲综合色自拍一区| 亚洲精品NV久久久久久久久久| 在线看亚洲十八禁网站| 国产AV日韩A∨亚洲AV电影 | 亚洲av日韩精品久久久久久a| 亚洲欧美日韩中文二区| 亚洲大尺度无码无码专线一区| 亚洲人av高清无码| 久久亚洲精品无码网站| 国产精品亚洲а∨天堂2021| 亚洲av无码成人精品区一本二本| 亚洲av无码专区青青草原| 亚洲AV电影天堂男人的天堂| 久久亚洲AV成人无码国产电影 | 国产成人人综合亚洲欧美丁香花| 最新亚洲人成网站在线观看| 国产亚洲综合视频| 亚洲无码高清在线观看| 亚洲中文字幕无码久久综合网| 精品国产亚洲一区二区三区 | 久久久久久久综合日本亚洲| 亚洲AV永久无码精品成人| 亚洲人成电影亚洲人成9999网| 亚洲美女在线观看播放| 亚洲人成在线精品| 亚洲免费综合色在线视频| 亚洲AV蜜桃永久无码精品| 狠狠综合久久综合88亚洲| 亚洲av中文无码乱人伦在线r▽| 亚洲精品无码不卡| 亚洲人成在线播放| 国产精品亚洲综合一区在线观看 | 久久精品亚洲男人的天堂|