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]