一文了解DataStore(Preferences)

前言

  1. 本篇主要介紹DataStore,包含介紹,使用等。
  2. 本篇會(huì)介紹DataStore兩種實(shí)現(xiàn)Preferences DataStore(主要介紹)和Proto DataStore(后續(xù)介紹)。
  3. 本篇也會(huì)介紹到DataStore和SharedPreferences的不同之處,以及如何進(jìn)行遷移。

簡介

  • 首先,DataStore是Jetpack一部分,是一種數(shù)據(jù)存儲(chǔ)解決方案。
  • 其次,DataStore使用協(xié)程及flow以異步、一致的方式實(shí)現(xiàn)數(shù)據(jù)的存儲(chǔ)。
  • 最后是DataStore的實(shí)現(xiàn),分為Preferences DataStore和Proto DataStore:
    • Preferences DataStore 類似于SharedPreferences,鍵值對(duì)存儲(chǔ),本篇的主要介紹。
    • Proto DataStore 將數(shù)據(jù)作為自定義數(shù)據(jù)類型的實(shí)例進(jìn)行存儲(chǔ),基于Google protobuf實(shí)現(xiàn)。

DataStore和SharedPreferences(SP)

  • SP存在的問題:
    • 內(nèi)存浪費(fèi)問題,加載的數(shù)據(jù)會(huì)一直存在在內(nèi)存中。
    • get方法可能會(huì)阻塞主線程。
    • apply方法雖然為異步,也可能會(huì)發(fā)生ANR。
    • SP也無法保證類型安全。
    • SP不支持跨進(jìn)程。
  • DataStore的特點(diǎn):
    • 基于協(xié)程和Flow實(shí)現(xiàn),保證了主線程的安全性。
    • 以事務(wù)的方式進(jìn)行處理,保證了操作的原子性、一致性、隔離性及持久性。
    • Preferences DataStore可以支持SP的遷移,保證數(shù)據(jù)的完整性。
  • 說明:
    • 此處只是列出SP存在的問題,并沒有SP一無是處的的說法,DataStore在SP的基礎(chǔ)上解決了不少的問題,但是也沒有說SP存在的問題已經(jīng)全部解決了。
    • 至少,DataStore在SP的基礎(chǔ)上解決了如類型安全、阻塞導(dǎo)致anr等問題,確實(shí)這方面優(yōu)于SP。

Preferences DataStore

1. 依賴引入及擴(kuò)展

  • 依賴引入
implementation 'androidx.datastore:datastore-preferences:1.0.0'
  • 擴(kuò)展屬性,對(duì)Contex擴(kuò)展屬性,方便使用。
val Context.dataStore by preferencesDataStore(name = "data_store")

2. 基本使用:

編碼
            //存儲(chǔ)
            dataStore.edit { edit ->
                edit[stringPreferencesKey("data")] = "123456"
            }
            //讀取
           val data =  dataStore.data.first()[stringPreferencesKey("data")]
            Log.d(TAG.TAG,"data is $data")
日志
2022-08-04 14:38:15.606 13419-13445/edu.test.demo D/Test-TAG: data is 123456
分析:
  • 一眼看起來貌似和SP區(qū)別也不大,事實(shí)上使用起來區(qū)別也確實(shí)不大。
  • 區(qū)別在于key值不再是String,而是Preferences.Key<String>,當(dāng)然這是存儲(chǔ)string的key,存儲(chǔ)別的類型key也不一樣。
  • 有一點(diǎn)就是必須在協(xié)程中使用,因?yàn)閑dit方法是suspend方法,讀取的時(shí)候data返回值為flow,操作起來也是在協(xié)程中。

3. 更新:

代碼1(也就是再編輯一遍就覆蓋了)如下:
  //存儲(chǔ)
            dataStore.edit { edit ->
                edit[stringPreferencesKey("data")] = "123456"
            }

            //讀取
           val data =  dataStore.data.first()[stringPreferencesKey("data")]
            Log.d(TAG.TAG,"data is $data")

            dataStore.edit { edit ->
                edit[stringPreferencesKey("data")] = "123456789"
            }

            Log.d(TAG.TAG,"data is ${ dataStore.data.first()[stringPreferencesKey("data")]}")
日志如下:
2022-08-04 14:44:25.651 13552-13579/edu.test.demo D/Test-TAG: data is 123456
2022-08-04 14:44:25.657 13552-13579/edu.test.demo D/Test-TAG: data is 123456789
代碼2 調(diào)用update
             //存儲(chǔ)
            dataStore.edit { edit ->
                edit[stringPreferencesKey("data")] = "123456"
            }

            //讀取
           val data =  dataStore.data.first()[stringPreferencesKey("data")]
            Log.d(TAG.TAG,"data is $data")

            dataStore.updateData {
                val mutablePreference = it.toMutablePreferences()
                mutablePreference[stringPreferencesKey("data")] = "123456789"
                mutablePreference.toPreferences()
            }

            Log.d(TAG.TAG,"data is ${ dataStore.data.first()[stringPreferencesKey("data")]}")
分析:
  • 修改和SP也沒有太大的卻別,我們可以直接edit覆蓋,也可以u(píng)pdate。

3. DataStore支持的存儲(chǔ)類型:

DataStore支持的存儲(chǔ)類型從key上就可以看出,主要有七種,key類型以及調(diào)用方法如下,一眼就能看出來,就不一一
解釋了:
  • Preferences.Key<Int> intPreferencesKey
  • Preferences.Key<Double> doublePreferencesKey
  • Preferences.Key<String> stringPreferencesKey
  • Preferences.Key<Boolean> booleanPreferencesKey
  • Preferences.Key<Float> floatPreferencesKey
  • Preferences.Key<Long> longPreferencesKey
  • Preferences.Key<Set<String>> stringSetPreferencesKey

4. SP到DataStore的遷移

遷移編碼:
  • 主要是在擴(kuò)展進(jìn)行遷移,傳入sp的文件名。
val Context.dataStore : DataStore<Preferences> by preferencesDataStore(name = "dataStore_setting",
    produceMigrations = { context ->
        listOf( SharedPreferencesMigration(context, "sp_data"))
    })

遷移之前我們可以看下sp文件,位置為data/data/包名/shared_prefs/sp文件名:


微信截圖_20220804151724.png

遷移之后,sp文件被刪除,datastore文件出現(xiàn),如下:


微信截圖_20220804152313.png
驗(yàn)證編碼:
  val data = dataStore.data.first()[stringPreferencesKey("mydata")]
           Log.d(TAG.TAG,"sp->datastore,直接讀?。?data")
日志如下:
2022-08-04 15:22:24.062 14131-14157/edu.test.demo D/Test-TAG: sp->datastore,直接讀?。簃ydata123456
分析:
  • 對(duì)比可以看出,遷移之后sp文件被刪除,出現(xiàn)datastore文件。
  • 編碼驗(yàn)證說明已經(jīng)遷移成功,sp之前存儲(chǔ)的值,我們?cè)赿atastore直接讀取了出來。
  • 只有在我們使用dataStore.data.first()的時(shí)候,才會(huì)進(jìn)行文件的遷移。

總結(jié)

  • 本篇主要介紹了DataStore的實(shí)現(xiàn)分類。
  • 本篇也介紹了DataStore在sp的基礎(chǔ)上做了那些優(yōu)化。
  • 介紹了DataStore的使用,支持?jǐn)?shù)據(jù)類型,以及SP到DataStore的遷移。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容