Doris232 发表于 2022-11-14 08:53

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

协议缓冲区(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 tasksbool 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的部分代码:
publicfinal 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.Overridepublic boolean getShowCompleted() {    return showCompleted_;}private void setShowCompleted(boolean value) {      showCompleted_ = value;}public static com.codelab.android.datastore.UserPreferences parseFrom(      java.nio.ByteBuffer data)
--- End ---
页: [1]
查看完整版本: Android 架构组件 之 Data Store(7) - Proto DataStore实例(2) 定义protobuf 对象