一文了解DataStore(Preferences)

前言

  1. 本篇主要介绍DataStore,包含介绍,使用等。
  2. 本篇会介绍DataStore两种实现Preferences DataStore(主要介绍)和Proto DataStore(后续介绍)。
  3. 本篇也会介绍到DataStore和SharedPreferences的不同之处,以及如何进行迁移。

简介

  • 首先,DataStore是Jetpack一部分,是一种数据存储解决方案。
  • 其次,DataStore使用协程及flow以异步、一致的方式实现数据的存储。
  • 最后是DataStore的实现,分为Preferences DataStore和Proto DataStore:
    • Preferences DataStore 类似于SharedPreferences,键值对存储,本篇的主要介绍。
    • Proto DataStore 将数据作为自定义数据类型的实例进行存储,基于Google protobuf实现。

DataStore和SharedPreferences(SP)

  • SP存在的问题:
    • 内存浪费问题,加载的数据会一直存在在内存中。
    • get方法可能会阻塞主线程。
    • apply方法虽然为异步,也可能会发生ANR。
    • SP也无法保证类型安全。
    • SP不支持跨进程。
  • DataStore的特点:
    • 基于协程和Flow实现,保证了主线程的安全性。
    • 以事务的方式进行处理,保证了操作的原子性、一致性、隔离性及持久性。
    • Preferences DataStore可以支持SP的迁移,保证数据的完整性。
  • 说明:
    • 此处只是列出SP存在的问题,并没有SP一无是处的的说法,DataStore在SP的基础上解决了不少的问题,但是也没有说SP存在的问题已经全部解决了。
    • 至少,DataStore在SP的基础上解决了如类型安全、阻塞导致anr等问题,确实这方面优于SP。

Preferences DataStore

1. 依赖引入及扩展

  • 依赖引入
implementation 'androidx.datastore:datastore-preferences:1.0.0'
  • 扩展属性,对Contex扩展属性,方便使用。
val Context.dataStore by preferencesDataStore(name = "data_store")

2. 基本使用:

编码
            //存储
            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区别也不大,事实上使用起来区别也确实不大。
  • 区别在于key值不再是String,而是Preferences.Key<String>,当然这是存储string的key,存储别的类型key也不一样。
  • 有一点就是必须在协程中使用,因为edit方法是suspend方法,读取的时候data返回值为flow,操作起来也是在协程中。

3. 更新:

代码1(也就是再编辑一遍就覆盖了)如下:
  //存储
            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 调用update
             //存储
            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覆盖,也可以update。

3. DataStore支持的存储类型:

DataStore支持的存储类型从key上就可以看出,主要有七种,key类型以及调用方法如下,一眼就能看出来,就不一一
解释了:
  • 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的迁移

迁移编码:
  • 主要是在扩展进行迁移,传入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文件出现,如下:


微信截图_20220804152313.png
验证编码:
  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,直接读取:mydata123456
分析:
  • 对比可以看出,迁移之后sp文件被删除,出现datastore文件。
  • 编码验证说明已经迁移成功,sp之前存储的值,我们在datastore直接读取了出来。
  • 只有在我们使用dataStore.data.first()的时候,才会进行文件的迁移。

总结

  • 本篇主要介绍了DataStore的实现分类。
  • 本篇也介绍了DataStore在sp的基础上做了那些优化。
  • 介绍了DataStore的使用,支持数据类型,以及SP到DataStore的迁移。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,290评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,107评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,872评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,415评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,453评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,784评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,927评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,691评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,137评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,472评论 2 326
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,622评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,289评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,887评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,741评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,316评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,490评论 2 348

推荐阅读更多精彩内容