让你易上手的Jetpack DataStore教程

1.什么是DataStore

Jetpack DataStore是一种数据存储解决方案,允许使用协议缓存区来存储key-value值或者序列化对象。谷歌的建议是如果当前使用的是SharedPreferences的话,可以考虑迁移到DataStore

DataStore一共有两种类型:Preferences DataStoreProto DataStore

  • Preferences DataStore: 使用键存储和访问数据。此实现不需要预定义的架构,也不确保类型安全。
  • Proto DataStore: 将数据作为自定义数据类型的实例进行存储。此实现要求您使用协议缓冲区来定义架构,但可以确保类型安全。

2.Preferences DataStore

2.1 引入库

根据个人的需求把以下的依赖加入到Gradle文件中。

// Typed DataStore (Typed API surface, such as Proto)
dependencies {
  implementation "androidx.datastore:datastore:1.0.0-alpha07"

  // optional - RxJava2 support
  implementation "androidx.datastore:datastore-rxjava2:1.0.0-alpha07"

  // optional - RxJava3 support
  implementation "androidx.datastore:datastore-rxjava3:1.0.0-alpha07"
}
// Alternatively - use the following artifact without an Android dependency.
dependencies {
  implementation "androidx.datastore:datastore-core:1.0.0-alpha07"
}

2.2 创建Preferences DataStore

首先我们需要创建Preferences DataStore的实例。我们可以用属性委托的方式创建DataStore<Preferences>的实例,如下面的代码。比较推荐的方法是在Kotlin文件顶层创建实例,这样便可以在应用内轻松的调用。 此外如果当前的项目使用的是Rxjava的情况,则需要使用RxPreferencesDataStoreBuilder来创建。

val dataStore: DataStore<Preferences> = createDataStore(
    name = DATA_STORE_KEY
)

2.3 从Preferences DataStore中读取内容

为了读取内容,我们需要根据内容的属性使用特定的Key。下列代码是当内容为String的情况下,需要调用stringPreferencesKey方法。

val textKey = stringPreferencesKey(MainActivity.DATA_STORE_TEXT_KEY)

然后把Key传入给DataStore的实例就可以读到数据内容了。

    // read data
    fun getText(dataStore: DataStore<Preferences>) {
        viewModelScope.launch(Dispatchers.IO) {
            val textKey = stringPreferencesKey(MainActivity.DATA_STORE_TEXT_KEY)
            dataStore.edit { settings ->
                val text = settings[textKey]
                textLiveData.postValue(text)
            }
        }
    }

2.4 将内容写入Preferences DataSotre

写入内容和读取内容的方式类似。直接看代码吧!

    // store data
    fun saveText(dataStore: DataStore<Preferences>, content: String) {
        viewModelScope.launch(Dispatchers.IO) {
            val textKey = stringPreferencesKey(MainActivity.DATA_STORE_TEXT_KEY)
            dataStore.edit { settings ->
                settings[textKey] = content
            }
        }
    }  

2.5 Screenshot

1_ANsuBmvVkRupFQGkob2GEA.gif

3. Proto DataStore

Proto DataStore实现使用DataStore和协议缓冲区将类型化的对象保留在磁盘上。换句话来说,就是可以存储自定义类。

3.1 定义架构

首先,我们需要在路径为app/src/main/proto的目录下一个proto文件中创建预定义架构。关于具体的protobuf语言的使用方法,可以查看这里

我写的例子中的预定义架构的代码如下。

syntax = "proto3";

option java_package = "com.example.datastoredemo";
option java_multiple_files = true;

message DataModelPreference {
  string name = 1;
  int32 age = 2;
}

简而言之,你需要修改java_package为你的项目路径,还需要写入你想要自定义的数据结构。

3.2 创建Data Model

我们需要创建一个与预定义结构中的数据结构相同的数据模型。如果想要让Proto DataStore中有默认的值,可以在Data Model中设置默认值即可。

data class DataModel(
    val name: String? = "1",
    val age: Int? = 1
)

3.3 创建Serializer

下一步,我们需要创建一个Serializer。我们要继承自Serializer同时需要重写一些方法。 具体的代码如下。 需要注意的是,Serializer中的DataModelPreference应该与预定义架构中定义的数据结构相同。

object DataModelSerializer : Serializer<DataModelPreference> {
    override fun readFrom(input: InputStream): DataModelPreference {
        try {
            return DataModelPreference.parseFrom(input)
        } catch (exception: InvalidProtocolBufferException) {
            throw CorruptionException("Cannot read proto.", exception)
        }
    }

    override fun writeTo(t: DataModelPreference, output: OutputStream) {
        t.writeTo(output)
    }

    override val defaultValue: DataModelPreference
        get() = DataModelPreference.getDefaultInstance()
}

3.4 创建DataStore的实例

利用Context.createDataStore()扩展函数去创建DataStore<T>的实例。
当然,T是预定义架构中定义的那个数据类型DataModelPreference
往参数fileName中传入要保存的数据文件的名称,需要注意的是文件类型是pb.

private val datastore: DataStore<DataModelPreference> = createDataStore(
    fileName = PROTO_DATA_FILE_NAME,
    serializer = DataModelSerializer
)

3.5 从Proto DataStore中读取数据

利用DataSotre.data从存储的object中读取数据,以Flow形式返回。这里需要注意的是,一定要使用IO线程,不然会造成UI卡顿。

    fun getText(dataStore: DataStore<DataModelPreference>) {
        viewModelScope.launch(Dispatchers.IO) {
            dataModelFlow = dataStore.data.map { pref ->
                Log.d("AAAA", "name: ${pref.name} age: ${pref.age}")
                DataModel(pref.name, pref.age)
            }
        }
    }

3.6 保存数据到Proto DataStore

利用DataStore.update方法来保存或者更新Proto DataStore中的数据。

    fun getText(dataStore: DataStore<DataModelPreference>) {
        viewModelScope.launch(Dispatchers.IO) {
            dataModelFlow = dataStore.data.map { pref ->
                DataModel(pref.name, pref.age)
            }
        }
    }

3.7 Screenshot

1_ndGMoIE4A7p6wmCQzqUcmQ.gif

作者:HyejeanMOON
原文链接:(https://juejin.cn/post/6949561129630859272)

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
在这里插入图片描述
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

全套视频资料:

一、面试合集

在这里插入图片描述
二、源码解析合集
在这里插入图片描述

三、开源框架合集
在这里插入图片描述
欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值