Android 原型数据存储-嵌套类型
好的,我一直在Kotlin试验原始数据存储,我有一个问题。我正在使用以下.proto文件:Android 原型数据存储-嵌套类型,android,kotlin,protocol-buffers,Android,Kotlin,Protocol Buffers,好的,我一直在Kotlin试验原始数据存储,我有一个问题。我正在使用以下.proto文件: syntax = "proto3"; option java_package = "com.example.protodatastore"; option java_multiple_files = true; message Person{ string name = 1; int32 age = 2; messag
syntax = "proto3";
option java_package = "com.example.protodatastore";
option java_multiple_files = true;
message Person{
string name = 1;
int32 age = 2;
message Address{
string street = 3;
int32 number = 4;
}
Address address = 5;
}
这是我的序列化程序类:
class MyPreferencesSerializer: Serializer<Person> {
override fun readFrom(input: InputStream): Person {
try {
return Person.parseFrom(input)
}catch (exception: InvalidProtocolBufferException){
throw CorruptionException("Cannot read proto.", exception)
}
}
override fun writeTo(t: Person, output: OutputStream) {
t.writeTo(output)
}
}
class MyPreferencesRepository(context: Context) {
private val dataStore: DataStore<Person> = context.createDataStore(
"my_pref",
serializer = MyPreferencesSerializer()
)
val readProto: Flow<Person> = dataStore.data
.catch { exception ->
// dataStore.data throws an IOException when an error is encountered when reading data
if (exception is IOException) {
Log.e("TAG", exception.message.toString())
emit(Person.getDefaultInstance())
} else {
throw exception
}
}
suspend fun updateValue(name: String){
dataStore.updateData {preferences->
preferences.toBuilder().setName(name).build()
}
}
}
类MyPreferencesSerializer:序列化程序{
覆盖趣味readFrom(输入:InputStream):Person{
试一试{
返回Person.parseFrom(输入)
}捕获(异常:InvalidProtocolBufferException){
抛出CorruptionException(“无法读取proto.”,异常)
}
}
重写fun writeTo(t:Person,output:OutputStream){
t、 写入(输出)
}
}
和我的存储库:
class MyPreferencesSerializer: Serializer<Person> {
override fun readFrom(input: InputStream): Person {
try {
return Person.parseFrom(input)
}catch (exception: InvalidProtocolBufferException){
throw CorruptionException("Cannot read proto.", exception)
}
}
override fun writeTo(t: Person, output: OutputStream) {
t.writeTo(output)
}
}
class MyPreferencesRepository(context: Context) {
private val dataStore: DataStore<Person> = context.createDataStore(
"my_pref",
serializer = MyPreferencesSerializer()
)
val readProto: Flow<Person> = dataStore.data
.catch { exception ->
// dataStore.data throws an IOException when an error is encountered when reading data
if (exception is IOException) {
Log.e("TAG", exception.message.toString())
emit(Person.getDefaultInstance())
} else {
throw exception
}
}
suspend fun updateValue(name: String){
dataStore.updateData {preferences->
preferences.toBuilder().setName(name).build()
}
}
}
class MyPreferencesRepository(上下文:上下文){
私有val数据存储:数据存储=context.createDataStore(
“我的首选”,
serializer=MyPreferencesSerializer()
)
val readProto:Flow=dataStore.data
.catch{异常->
//在读取数据时遇到错误时,dataStore.data会引发IOException
if(异常为IOException){
Log.e(“标记”,exception.message.toString())
emit(Person.getDefaultInstance())
}否则{
抛出异常
}
}
suspend fun updateValue(名称:String){
dataStore.updateData{preferences->
preferences.toBuilder().setName(name.build())
}
}
}
因此,在我的updateValue()方法中,我可以设置“name”字段的名称,但我没有地址消息字段(如street和number)的设置器。编译器只向我显示getter。在姓名和年龄字段的另一侧,我有setter。如何为这两个地址字段使用setter:street和number
还有一个问题。
因此,基本上,对于Proto数据存储,我们正在序列化/反序列化自定义对象及其所有字段,而不仅仅是单一的基本类型,如string、int等
如何为这两个地址字段使用setter:street和number
您的代码看起来不错,请尝试clean
和rebuildproject
,因为proto在编译时生成类
还有一个问题。因此,基本上,对于Proto数据存储,我们正在序列化/反序列化自定义对象及其所有字段,而不仅仅是单一的基本类型,如string、int等
是的,原始数据存储非常适合于小型或简单的数据集,不支持部分更新或引用完整性。由于它使用序列化/反序列化来写入/读取数据,因此会产生性能问题
如果要存储大型复杂对象,请使用房间
我观察到的关于原始数据存储的一些痛苦的事情:
class MyPreferencesSerializer: Serializer<Person> {
override fun readFrom(input: InputStream): Person {
try {
return Person.parseFrom(input)
}catch (exception: InvalidProtocolBufferException){
throw CorruptionException("Cannot read proto.", exception)
}
}
override fun writeTo(t: Person, output: OutputStream) {
t.writeTo(output)
}
}
class MyPreferencesRepository(context: Context) {
private val dataStore: DataStore<Person> = context.createDataStore(
"my_pref",
serializer = MyPreferencesSerializer()
)
val readProto: Flow<Person> = dataStore.data
.catch { exception ->
// dataStore.data throws an IOException when an error is encountered when reading data
if (exception is IOException) {
Log.e("TAG", exception.message.toString())
emit(Person.getDefaultInstance())
} else {
throw exception
}
}
suspend fun updateValue(name: String){
dataStore.updateData {preferences->
preferences.toBuilder().setName(name).build()
}
}
}
- 为每个要保存的对象创建序列化程序
- 为每个对象创建模式(额外的工作)
- 我找不到任何解决方案来构建一个可以在任何地方使用的泛型类
- 任何时候你在模式中改变,你必须重建项目等