DataStore?definition
One of the primary benefits of DataStore is the asynchronous API.aimed at replacing SharedPreferences.Data is stored asynchronously, consistently, and transactionally, overcoming most of the drawbacks of SharedPreferences.
另外,DataStore能存储基本的键值对,也能存储数据对象类型。
0.Setup
//添加依赖
implementation("androidx.datastore:datastore:1.0.0")
implementation("androidx.datastore:datastore-preferences:1.0.0")
1.Preferences DataStore(SharedPreferences)
- Create a Preferences DataStore
// At the top level of your kotlin file:
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
- Read from a Preferences DataStore
val EXAMPLE_COUNTER = intPreferencesKey("example_counter")
val exampleCounterFlow: Flow<Int> = context.dataStore.data
? .map { preferences ->
? ? // No type safety.
? ? preferences[EXAMPLE_COUNTER] ?: 0
}
- Write to a Preferences DataStore
suspend fun incrementCounter() {
? context.dataStore.edit { settings ->
? ? val currentCounterValue = settings[EXAMPLE_COUNTER] ?: 0
? ? settings[EXAMPLE_COUNTER] = currentCounterValue + 1
? }
}
2.Proto DataStore
- 在build.gradle(:app)添加如下设置
plugins {
id "com.google.protobuf" version "0.8.12"
}
android{
sourceSets {
main {
proto {
// proto 文件默认路径是 src/main/proto
// 可以通过 srcDir 修改 proto 文件的位置
srcDir 'src/main/proto'
}
}
}
}
dependencies{
implementation "androidx.datastore:datastore-core:1.0.0"
implementation "com.google.protobuf:protobuf-javalite:3.10.0"
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.10.0"
}
// Generates the java Protobuf-lite code for the Protobufs in this project. See
// https://github.com/google/protobuf-gradle-plugin#customizing-protobuf-compilation
// for more information.
generateProtoTasks {
all().each { task ->
task.builtins {
java {
option 'lite'
}
}
}
}
// 默认生成目录 $buildDir/generated/source/proto 通过 generatedFilesBaseDir 改变生成位置
// generatedFilesBaseDir = "$projectDir/src/main"
}
在src/main/proto/创建一个.proto文件内容如下:
syntax = "proto3";
//包名+文件名
option java_package = "com.example.application";
option java_multiple_files = true;
message Settings {
int32 example_counter = 1;
}
//定义proto类的序列化器
object SettingsSerializer : Serializer<Settings> {
? override val defaultValue: Settings = Settings.getDefaultInstance()
? override suspend fun readFrom(input: InputStream): Settings {
? ? try {
? ? ? return Settings.parseFrom(input)
? ? } catch (exception: InvalidProtocolBufferException) {
? ? ? throw CorruptionException("Cannot read proto.", exception)
? ? }
? }
? override suspend fun writeTo(
? ? t: Settings,
? ? output: OutputStream) = t.writeTo(output)
}
//定义datastore对象
//The?filename?parameter tells DataStore which file to use to store the data
val Context.settingsDataStore: DataStore<Settings> by dataStore(
? fileName = "settings.pb",
? serializer = SettingsSerializer
)
- Read from a Proto DataStore
val exampleCounterFlow: Flow<Int> = context.settingsDataStore.data
? .map { settings ->
? ? // The exampleCounter property is generated from the proto schema.
? ? settings.exampleCounter
? }
- Write to a Proto DataStore
suspend fun incrementCounter() {
? context.settingsDataStore.updateData { currentSettings ->
? ? currentSettings.toBuilder()
? ? ? .setExampleCounter(currentSettings.exampleCounter + 1)
? ? ? .build()
? ? }
}
Migrate from SharedPreferences to DataStore
val dataStore: DataStore<Preferences> = context.createDataStore(
name = "settings",
migrations = listOf(SharedPreferencesMigration(context, "settings_preferences"))
)
SharedPreferences vs DataStore
Room vs DataStore
If you have a need for partial updates, referential integrity, or support for large/complex datasets, you should consider using Room instead of DataStore. DataStore is ideal for small, simple datasets and does not support partial updates or referential integrity.
https://android-developers.googleblog.com/2020/09/prefer-storing-data-with-jetpack.html
Blogs
相关学习资料
|