找回密码
 立即注册
查看: 217|回复: 0

Android 架构组件 之 Data Store(7) - Proto DataStore实例(2) 定义protobuf 对象

[复制链接]
发表于 2022-11-14 08:53 | 显示全部楼层 |阅读模式
协议缓冲区(Protocol buffers)是一种对 结构化数据 进行 序列化的机制。
只需对数据结构化的方式进行一次定义,
编译器便会生成源代码,轻松 写入和读取 结构化数据。

以下将会介绍 如何定义 proto buff 对象.
1. 创建 proto 文件


有两个用户偏好设置:show_completed 和 sort_order;
目前两者以两种不同的对象来表示。

因此,我们的一个目标是将这两个标志统一到存储在 DataStore 中的一个 UserPreferences 类下。
我们将在 协议缓冲区架构非 Kotlin 中定义该类。
1.1 创建ser_prefs.proto 文件


路径:app/src/main/proto。
在协议缓冲区中:
(1) 每个结构都使用一个 message 关键字进行定义,
(2) 并且结构中的每一个成员都会根据 类型和名称在 消息内 进行定义,
从而获得从 1 开始的排序。

现在,我们来定义一个 UserPreferences 消息,
目前该消息只有一个名为 show_completed 的布尔值。
syntax = "proto3";option java_package = "com.codelab.android.datastore";option java_multiple_files = true;message UserPreferences {  // filter for showing / hiding completed tasks  bool show_completed = 1;}
UserPreferences 类在编译时会从 proto 文件中定义的 message 中生成。
请务必重新构建该项目。
编译后,在目录
app\build\generated\source\proto\debug\java\com\codelab\android\datastore
会有三个文件:
UserPreferences.java
UserPreferencesOrBuilder.java
UserPrefs.java
其中, UserPreferences 会有提供构造方法 以及 get/set show_completed 的方法
1.2 创建序列化器


如需告知 DataStore 如何读取和写入我们在 proto 文件中定义的数据类型,
我们需要实现序列化器(Serializer)。

如果磁盘上没有数据,序列化器还会定义默认返回值。
在 data 包中创建一个名为 UserPreferencesSerializer 的新文件:
// 需要实现3个方法, 是经过 Proto 插件生成的代码object UserPreferencesSerializer : Serializer<UserPreferences>{    override val defaultValue: UserPreferences = UserPreferences.getDefaultInstance()    override suspend fun readFrom(input: InputStream): UserPreferences {        try {            return UserPreferences.parseFrom(input)        } catch (exception: InvalidProtocolBufferException) {            throw CorruptionException("Cannot read proto.", exception) // 这个是父类定义的        }    }    override suspend fun writeTo(t: UserPreferences, output: OutputStream) =t.writeTo(output)}
参考文献:
Proto 语言指南:https://developers.google.com/protocol-buffers/docs/overview
https://developer.android.com/codelabs/android-proto-datastore#5
<hr>2. 附录


生成的 UserPreferences.java的部分代码:
public  final class UserPreferences extends    com.google.protobuf.GeneratedMessageLite<        UserPreferences, UserPreferences.Builder> implements    // @@protoc_insertion_point(message_implements:UserPreferences)    UserPreferencesOrBuilder {  public static final int SHOW_COMPLETED_FIELD_NUMBER = 1;  private boolean showCompleted_;  /**  @java.lang.Override  public boolean getShowCompleted() {    return showCompleted_;  }  private void setShowCompleted(boolean value) {        showCompleted_ = value;  }  public static com.codelab.android.datastore.UserPreferences parseFrom(      java.nio.ByteBuffer data)
--- End ---
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-24 19:31 , Processed in 0.092738 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表