前言
- 本篇主要介紹DataStore,包含介紹,使用等。
- 本篇會(huì)介紹DataStore兩種實(shí)現(xiàn)Preferences DataStore(主要介紹)和Proto DataStore(后續(xù)介紹)。
- 本篇也會(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的遷移。