让你易上手的Jetpack DataStore教程

1.什么是DataStore

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

DataStore一共有两种类型:Preferences DataStore和Proto 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 datafungetText(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 datafunsaveText(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

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中设置默认值即可。

dataclassDataModel(
    val name: String? = "1",
    val age: Int? = 1
)
3.3 创建Serializer

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

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

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

    overrideval defaultValue: DataModelPreference
        get() = DataModelPreference.getDefaultInstance()
}
3.4 创建DataStore的实例

利用Context.createDataStore()扩展函数去创建DataStore<T>的实例。

当然,T是预定义架构中定义的那个数据类型DataModelPreference。

往参数fileName中传入要保存的数据文件的名称,需要注意的是文件类型是pb.

privateval datastore: DataStore<DataModelPreference> = createDataStore(
    fileName = PROTO_DATA_FILE_NAME,
    serializer = DataModelSerializer
)
3.5 从Proto DataStore中读取数据

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

fungetText(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中的数据。

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值