DataStore
是Android Jetpack
中的一个组件,它是一个数据存储的解决方案,跟SharedPreferences
一样,采用key-value
形式存储。DataStore
支持Kotlin
协程和Flow
操作,如果当前使用SharedPreferences
,可以考虑迁移到DataStore
。Jetpack DataStore
是经过改进的新版数据存储解决方案,旨在取代 SharedPreferences
,让应用能够以异步、事务方式存储数据。跟SharedPreferences
一样,它比较适合小数据和简单操作,如果不是,应该使用数据库存储。
DataStore
提供了两种不同实现方式,Preferences DataStore
和Proto DataStore
。Preferences DataStore
不需要预先定义,但是不支持类型安全。Proto DataStore
需要预先使用protocol buffers定义数据,但是类型安全。下面有三者之间的比较,该图片作者Florina Muntenescu
。
// Preferences DataStore
implementation "androidx.datastore:datastore-preferences:1.0.0-alpha04"
// Proto DataStore
implementation "androidx.datastore:datastore-core:1.0.0-alpha04"
implementation "com.google.protobuf:protobuf-java:3.14.0"
val dataStore: DataStore = context.createDataStore(
name = "user"
)
val NAME = preferencesKey("username")
dataStore.edit {
it[NAME] = name
}
val getName = dataStore.data
.map {
it[NAME]
}
Protocol Buffers v3.14.0的下载地址,以windows 64位环境为例,选择protoc-3.14.0-win64.zip
下载。下载完成后解压,将protoc-3.14.0-win64\bin
的绝对路径添加到系统环境变量中。如果添加到系统环境变量中,可以点此网址:WINDOWS如何配置Path环境变量。打开命令行工具,输入protoc --version
查看版本成功,则表示配置成功。
>protoc --version
libprotoc 3.14.0
在项目的app/src/main/proto/
路径下新建user.proto文件,第一行一定要写上syntax
,选择proto
版本,不能是空白行。
syntax = "proto3";
option java_package = "com.hs.datastoresample.data.bean.user";
option java_multiple_files = true;
message User{
string username = 1;
}
打开命令行工具,输入格式如下
protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/addressbook.proto
例如:
protoc -I=项目路径\app\src\main\proto\ --java_out=项目路径\app\src\main\ 项目路径\app\src\main\proto\user.proto
执行完后,将会在java目录com.hs.datastoresample.data.bean.user
包下自动生成三个文件。
object UserSerializer: Serializer {
override val defaultValue: User
get() = User.getDefaultInstance()
override fun readFrom(input: InputStream): User {
try {
return User.parseFrom(input)
}catch (e: InvalidProtocolBufferException){
throw CorruptionException("Cannot read proto.", e)
}
}
override fun writeTo(t: User, output: OutputStream) {
t.writeTo(output)
}
}
val dataStore = context.createDataStore(
fileName = FILENAME,
serializer = UserSerializer
)
dataStore.updateData {
it.toBuilder()
.setUsername(name)
.build()
}
val getName = dataStore.data
.map {
it.username
}
最后附上完整代码的Github地址:DataStoreSample,如果觉得不错的话,欢迎Star。