Jetpack DataStore詳解

DataStore出現(xiàn)的原因

Jetpack DataStore is a data storage solution that allows you to store key-value pairs or typed objects with protocol buffers. DataStore uses Kotlin coroutines and Flow to store data asynchronously, consistently, and transactionally.
If you're currently using SharedPreferences to store data, consider migrating to DataStore instead.


?官方文檔給出的定義如上所示

  • 首先它的作用就是以key-value的形式去存儲(chǔ)數(shù)據(jù)
  • 它用的是kotlin的Flow實(shí)現(xiàn),以事務(wù)方式處理數(shù)據(jù)。
  • 最關(guān)鍵的一句話就是如果你的項(xiàng)目當(dāng)前使用的是Sp,那么建議做一次遷移伐谈。

DataStore的實(shí)現(xiàn)方式

DataStore provides two different implementations: Preferences DataStore and Proto DataStore.

  • Preferences DataStore stores and accesses data using keys. This implementation does not require a predefined schema, and it does not provide type safety.
  • Proto DataStore stores data as instances of a custom data type. This implementation requires you to define a schema using protocol buffers, but it provides type safety.

?文檔中給出DataStore的兩種實(shí)現(xiàn)方式:

  • Preferences DataStore 顧名思義忠聚,以鍵值對(duì)的方式存儲(chǔ)在本地。
  • Proto DataStore 通過(guò)protocol buffers將對(duì)象序列化存儲(chǔ)在本地柳弄。

DataStore的使用

  • 在項(xiàng)目當(dāng)中集成舶胀,添加所需依賴
// Preferences DataStore
    implementation "androidx.datastore:datastore-preferences:1.0.0-alpha03"
// Proto DataStore
    implementation "androidx.datastore:datastore-core:1.0.0-alpha03"
  • 創(chuàng)建一個(gè)DataStore對(duì)象
private val DATASTORE_NAME = "hy_datastore"
var dateStore: DataStore<Preferences> = mContext.createDataStore(name = DATASTORE_NAME)
  • 將對(duì)象存入DataStore中
    通過(guò)mDataStorePre.edit()將數(shù)據(jù)存入DataStore中
public suspend fun DataStore<Preferences>.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) }
    }
}

可以看到edit()方法是一個(gè)suspend函數(shù)概说,所以只能在協(xié)程體中進(jìn)行調(diào)用。以掛起的方式進(jìn)行運(yùn)行嚣伐,做到不阻礙主線程糖赔。

private suspend fun saveDate(data: String) {
        mDataStorePre.edit { mutablePreferences ->
            mutablePreferences[KEY_TEST_DATASTORE] = ""
        }
    }
  • 從DataStore中讀取對(duì)象
private suspend fun getDate(data: String): String {
        var value = mDataStorePre.data.map { preferences ->
            preferences[KEY_TEST_DATASTORE] ?: ""
        }
        return value.first()
    }

可以看到DataStore的key不同于spkey,DataStore的keyPreferences.Key<T>類型轩端,只支持Int放典,Long,Boolean基茵,F(xiàn)loat奋构,String,Double

public inline fun <reified T : Any> preferencesKey(name: String): Preferences.Key<T> {
    return when (T::class) {
        Int::class -> {
            Preferences.Key<T>(name)
        }
        String::class -> {
            Preferences.Key<T>(name)
        }
        Boolean::class -> {
            Preferences.Key<T>(name)
        }
        Float::class -> {
            Preferences.Key<T>(name)
        }
        Long::class -> {
            Preferences.Key<T>(name)
        }
        Double::class -> {
            Preferences.Key<T>(name)
        }
        Set::class -> {
            throw IllegalArgumentException("Use `preferencesSetKey` to create keys for Sets.")
        }
        else -> {
            throw IllegalArgumentException("Type not supported: ${T::class.java}")
        }
    }
}
除此外的類型將會(huì)拋出異常。
  • 通過(guò)mDataStorePre.data我們將獲取到的是一個(gè)Flow<T>的對(duì)象拱层,每當(dāng)數(shù)據(jù)變化的時(shí)候都會(huì)重新發(fā)出弥臼。
  • 異常的捕獲我們通過(guò)catch來(lái)捕獲,如下所示:
private suspend fun getDate(): String {
        var value = mDataStorePre.data.catch {
            if (it is IOException) {//io異常的話可以發(fā)送一個(gè)emptyPreferences()來(lái)重新使用
                it.printStackTrace()
                emit(emptyPreferences())
            } else {
                throw it
            }
        }
                .map { preferences ->
                    preferences[KEY_TEST_DATASTORE] ?: ""
                }
        return value.first()

    }

遷移Sp到DataStore

只需要在創(chuàng)建的時(shí)候傳入需要遷移的SharedPreferencesMigration如下:

var mDataStorePre: DataStore<Preferences> = mContext.createDataStore(
                name = DATASTORE_NAME,
                migrations = listOf(
                        SharedPreferencesMigration(
                                mContext,
                                SPUtil.NAME
                        )
                )
        )
  • 遷移之后會(huì)自動(dòng)刪除Sp所使用的文件根灯,需要注意的是只從sp遷移一次径缅。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市烙肺,隨后出現(xiàn)的幾起案子纳猪,更是在濱河造成了極大的恐慌,老刑警劉巖桃笙,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兆旬,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡怎栽,警方通過(guò)查閱死者的電腦和手機(jī)丽猬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)熏瞄,“玉大人脚祟,你說(shuō)我怎么就攤上這事∏恳” “怎么了由桌?”我有些...
    開(kāi)封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)邮丰。 經(jīng)常有香客問(wèn)我行您,道長(zhǎng),這世上最難降的妖魔是什么剪廉? 我笑而不...
    開(kāi)封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任娃循,我火速辦了婚禮,結(jié)果婚禮上斗蒋,老公的妹妹穿的比我還像新娘捌斧。我一直安慰自己笛质,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布捞蚂。 她就那樣靜靜地躺著妇押,像睡著了一般。 火紅的嫁衣襯著肌膚如雪姓迅。 梳的紋絲不亂的頭發(fā)上敲霍,一...
    開(kāi)封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音丁存,去河邊找鬼色冀。 笑死,一個(gè)胖子當(dāng)著我的面吹牛柱嫌,可吹牛的內(nèi)容都是我干的锋恬。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼编丘,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼与学!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起嘉抓,我...
    開(kāi)封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤索守,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后抑片,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體卵佛,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年敞斋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了截汪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡植捎,死狀恐怖衙解,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情焰枢,我是刑警寧澤蚓峦,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站济锄,受9級(jí)特大地震影響暑椰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜荐绝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一一汽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧很泊,春花似錦角虫、人聲如沸沾谓。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至昏兆,卻和暖如春枫虏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背爬虱。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工隶债, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人跑筝。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓死讹,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親曲梗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子赞警,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1. 簡(jiǎn)介 DataStore是Google Android Jetpack組件新推出的數(shù)據(jù)存儲(chǔ)解決方案,其主要優(yōu)...
    XFY9326閱讀 6,385評(píng)論 0 3
  • 久違的晴天虏两,家長(zhǎng)會(huì)愧旦。 家長(zhǎng)大會(huì)開(kāi)好到教室時(shí),離放學(xué)已經(jīng)沒(méi)多少時(shí)間了定罢。班主任說(shuō)已經(jīng)安排了三個(gè)家長(zhǎng)分享經(jīng)驗(yàn)笤虫。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,513評(píng)論 16 22
  • 今天感恩節(jié)哎毙沾,感謝一直在我身邊的親朋好友么介。感恩相遇豌骏!感恩不離不棄方面。 中午開(kāi)了第一次的黨會(huì)服猪,身份的轉(zhuǎn)變要...
    迷月閃星情閱讀 10,559評(píng)論 0 11
  • 可愛(ài)進(jìn)取巷送,孤獨(dú)成精醉拓。努力飛翔圈盔,天堂翱翔售滤。戰(zhàn)爭(zhēng)美好罚拟,孤獨(dú)進(jìn)取。膽大飛翔完箩,成就輝煌赐俗。努力進(jìn)取,遙望弊知,和諧家園阻逮。可愛(ài)游走...
    趙原野閱讀 2,723評(píng)論 1 1
  • 在妖界我有個(gè)名頭叫胡百曉秩彤,無(wú)論是何事叔扼,只要找到胡百曉即可有解決的辦法事哭。因?yàn)槭侵缓偞蠹乙杂瀭饔灲形摇皟A城百曉”,...
    貓九0110閱讀 3,256評(píng)論 7 3