Android Protobuf实例教程
原文链接:https://android.jlelse.eu/simple-android-protobuf-tutorial-with-actual-code-bfb581299f47
寻找可能比JSON更好的东西?查看Google Protocol Buffers(简称Protobuf)。
已经有大量与JSON比较的文章了。
http://blog.codeclimate.com/blog/2014/06/05/choose-protocol-buffers/
https://auth0.com/blog/beating-json-performance-with-protobuf/
这里我将分享一个示例代码演示如何创建一个从网络服务读取Protobuf数据的Android应用。
如何工作
首先我解释下代码如系统如何在Android Studio环境里运行的。如图所示。
为了支持Protobuf,首先创建PROTO文件。该文件描述了共享数据的基本格式,并且该文件可在使用它的各种实体(例如,Webservice,客户端应用,Android)之间共享(或复制)。它可被视为整个实体的协议。
然后PROTO文件用于生成指定语言(例如Android使用的Java)的Proto类。这是通过PROTOC工具完成的。可在Android Studio外部执行此命令,并将生成的文件拷贝到代码里使用。但是使用Gradle Plugin for Protobuf,就可以在Android Studio中自动进行配置和转换。
一旦生成java文件,就可以引入Proto类并在App代码中使用数据模型对象了。
示例应用
PROTO文件
下面我写了一个包含一些String和INteger成员变量的PROTO文件。更多关于proto语法的信息,请参考google开发者文档.
syntax = "proto3";
package tutorial;
message Person {
string name = 1;
int32 id = 2;
string email = 3;
string phone = 4;
}
文件保存在工程的app/src/main/proto文件夹。
Gradle环境
项目的根build.gradle文件中,添加以下classpath在dependencies部分。
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.3'
在应用的build.gradle文件中,添加以下implementation在dependencies部分。
implementation 'com.google.protobuf:protobuf-lite:3.0.0'
文件顶部添加插件
apply plugin: 'com.google.protobuf'
为了从PROTO文件生成Proto类,添加如下代码到build.gradle。
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.0.0'
}
plugins {
javalite {
artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
}
}
generateProtoTasks {
all().each { task ->
task.builtins {
remove java
}
task.plugins {
javalite { }
}
}
}
}
到这,gradle环境准备完毕。如果想定制一些功能(例如,修改生成文件的位置等),可查看Gradle Plugin for Protobuf。
应用代码
gradle环境建立好后,可编译应用代码,并访问Proto的Java类。现在剩下的部分就是从服务器获取数据了。
可作为普通的网络服务数据完成(例如类似获取JSON数据)。我使用Okhttp执行一个简单的网络提取。
当获取到数据后,使用Proto数据模型类获取输入流。在我们的例子里,他是Person类(在PROTO文件中定义)。
Request request = new Request.Builder().url(url).build();
Call call = okHttpClient.newCall(request);
Response response = call.execute();
if (response.isSuccessful()) {
ResponseBody responseBody = response.body();
if (responseBody != null) {
return Person.parseFrom(responseBody.byteStream());
}
}
得到Person对象后,就可以使用getEmail(),getName()等方法…就像PROTO文件定义那样。为了简单,我只在示例代码中转换成String并打印到TextView。