本文主要是介绍Jetpack DataStore,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- Jetpack DataStore
- 概述
- DataStore 对比 SP
- 添加依赖库
- Preferences DataStore
- 路径
- 创建 Preferences DataStore
- 获取数据
- 保存数据
- 修改数据
- 删除数据
- 清除全部数据
- Proto DataStore
- 配置
- AndroidStudio安装插件
- 配置proto文件
- 创建序列化器
- 创建 Proto DataStore
- 获取数据
- 保存数据
- 修改数据
- 删除Map数据
- 清除数据
- 代码下载
Jetpack DataStore
概述
Jetpack DataStore 是一种数据存储解决方案,允许您使用协议缓冲区存储键值对或类型化对象。DataStore 使用 Kotlin 协程和 Flow 以异步、一致的事务方式存储数据。
DataStore 提供两种不同的实现:Preferences DataStore 和 Proto DataStore。
- Preferences DataStore 使用键存储和访问数据。此实现不需要预定义的架构,也不确保类型安全。
- Proto DataStore 将数据作为自定义数据类型的实例进行存储。此实现要求您使用协议缓冲区来定义架构,但可以确保类型安全。
DataStore 官方文档
Proto3 语法入门
Proto3 官方语法指南
DataStore 对比 SP
SharedPreference(简称SP) 是一个轻量级的数据存储方式,使用方便,以键值对的形式存储在本地。
SP的缺点:
- SP不能保证类型安全。如果存的数据和取的数据的类型不一致时会报异常。
- SP加载的数据会一直停留在内存中。
- 不支持多进程。
- 读写性能差,可能阻塞UI线程,可能引起ANR。
DataStore优点:
- 读写性能高。基于协程和Flow保证了UI线程的安全性。
- 从一定程度上保证类型安全。
添加依赖库
project/build.gradle
buildscript { dependencies {// Proto DataStoreclasspath 'com.google.protobuf:protobuf-gradle-plugin:0.8.19'}
}
module/build.gradle
plugins {id 'com.android.application'id 'kotlin-android'id 'com.google.protobuf'
}dependencies {// Preferences DataStoreimplementation "androidx.datastore:datastore-preferences:1.0.0"implementation "androidx.datastore:datastore-core:1.0.0"// Proto DataStoreimplementation 'androidx.datastore:datastore-core:1.0.0'implementation 'com.google.protobuf:protobuf-javalite:3.10.0'implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.5.0"}protobuf {protoc {artifact = "com.google.protobuf:protoc:3.14.0"}// 为该项目中的 Protobufs 生成 java Protobuf-lite 代码。generateProtoTasks {all().each { task ->task.builtins {java {option 'lite'}}}}
}
Preferences DataStore
路径
DataStore 生成的缓存文件存放在 /data/data/<包名>/files/datastore
目录下:
创建 Preferences DataStore
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "user_info")
获取数据
lifecycleScope.launch {dataStore.edit { preferences ->// 先通过 stringPreferencesKey() 方法获取指定Keyval nameKey = stringPreferencesKey("name")val ageKey = intPreferencesKey("age")val sexKey = booleanPreferencesKey("sex")// 通过Key获取值val name = preferences[nameKey]val age = preferences[ageKey]val sex = preferences[sexKey]logE("name:$name age:$age sex:$sex")}
}
保存数据
dataStore.edit { preferences ->preferences[stringPreferencesKey("name")] = "小明"preferences[intPreferencesKey("age")] = 18preferences[booleanPreferencesKey("sex")] = true
}
修改数据
dataStore.edit { preferences ->preferences[stringPreferencesKey("name")] = "小黑"preferences[intPreferencesKey("age")] = 28preferences[booleanPreferencesKey("sex")] = false}
删除数据
dataStore.edit { preferences ->val removeValue = preferences.remove(stringPreferencesKey("name"))logE("remove:$removeValue")
}
清除全部数据
dataStore.edit { preferences ->preferences.clear()
}
Proto DataStore
配置
AndroidStudio安装插件
配置proto文件
先新建 proto 目录:
再创建 person.proto 文件,并写入:
syntax = "proto3";option java_package = "com.example.datastoredemo"; //设置生成的类所在的包
option java_multiple_files = true; //可能会有多个文件。message PersonPreferences {string name = 1; //String类型int32 age = 2; //int类型bool sex = 3; //boolean类型repeated string address = 4; //String[]数组map<string, string> fruits = 5; //Map类型
}
创建序列化器
object PersonSerializer : Serializer<PersonPreferences> {override val defaultValue: PersonPreferencesget() = PersonPreferences.getDefaultInstance()override suspend fun writeTo(t: PersonPreferences, output: OutputStream) {t.writeTo(output)}override suspend fun readFrom(input: InputStream): PersonPreferences {try {return PersonPreferences.parseFrom(input)} catch (exception: InvalidProtocolBufferException) {throw CorruptionException("Cannot read proto.", exception)}}
}
创建 Proto DataStore
val Context.personDataStore: DataStore<PersonPreferences> by dataStore(fileName = "person.pb", serializer = PersonSerializer
)
获取数据
lifecycleScope.launch {personDataStore.data.first().let { preferences ->val name = preferences.nameval age = preferences.ageval sex = preferences.sexval address = preferences.addressListval fruits = preferences.fruitsMaplogE("name:$name age:$age sex:$sex address:$address fruits:$fruits")}
}
保存数据
preferences.toBuilder().setName("小白").setAge(28).setSex(true).addAddress("广东省").addAddress("广州市").addAddress("黄埔区").putFruits("apple", "苹果").putFruits("banner", "香蕉").putFruits("cherry", "樱桃").build()
preferences.toBuilder().setName("小白").setAge(28).setSex(true).addAllAddress(listOf("广东省", "广州市", "黄埔区")).putAllFruits(mapOf("apple" to "苹果", "banner" to "香蕉", "cherry" to "樱桃")).build()
修改数据
personDataStore.updateData { preferences -preferences.toBuilder().setName("小黑").setAge(38).setSex(false).setAddress(0, "湖南省").setAddress(1, "长沙市").setAddress(2, "芙蓉区").putFruits("apple", "苹果1号").build()
}
删除Map数据
personDataStore.updateData { preferences ->preferences.toBuilder().removeFruits("apple") // 删除map数据.build()}
清除数据
personDataStore.updateData { preferences ->// 清除所有数据preferences.toBuilder().clear().build()// 依次清除数据preferences.toBuilder().clearName().clearAge().clearSex().clearAddress().clearFruits().build()
}
personDataStore.updateData { preferences ->// 清除所有数据preferences.toBuilder().clear().build()// 依次清除数据preferences.toBuilder().clearName().clearAge().clearSex().clearAddress().clearFruits().build()
}
代码下载
这篇关于Jetpack DataStore的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!