protoBuf是谷歌推出的一种数据传输格式,类似轻量级的xml,今日学习了其使用方法和步骤,并作文以记之
首先,要在项目的gradle里添加protoBuf的classPath依赖
buildscript {
..
dependencies {
..
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.2'
// protobuf插件,AS3.0需要protobuf版本在0.8.2及以上
}
}
AS3.0对应的protoBuf版本必须不低于0.8.2,否则报错Resolving configuration 'debugCompile' directly is not allowed
而后,在对应模块的gradle里,添加如下内容
....
apply plugin: 'com.google.protobuf'
android {
....
sourceSets {
main {
// 配置protobuf源码目录
proto {
srcDir 'src/main/proto'
}
}
}
}
protobuf {
// 配置protoc编译器
protoc {
artifact = 'com.google.protobuf:protoc:3.2.0'
}
plugins {
javalite {
// The codegen for lite comes as a separate artifact
artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
}
}
// 这里配置生成目录,编译后会在build的目录下生成对应的java文件
generateProtoTasks {
all().each { task ->
task.plugins {
javalite {}
}
}
}
}
dependencies {
...
compile 'com.google.protobuf:protobuf-lite:3.0.1'
// protobuf依赖
}
注意,dependecies里也可以添加 compile 'com.google.protobuf:protobuf-java:3.0.0',但是protobuf-java和protobuf-lite只能有一个,否则编译时会报错Multiple dex files define Lcom/google/protobuf/SmallSortedMap$Entry。java的功能更丰富,lite的体积更小,可根据实际情况做出取舍。
这样,protoBuf的环境就完成了,不过为了编写方便,我们可以安装一个protobuf Support插件,帮助我们开发。
安装路径:File->Settings->Plugins,而后点击Browse repositories,搜索插件,安装,重启AS就行。如图所示
现在,我们就可以在src/main目录下创建proto文件夹(这也是gradle里sourceSets里的路径),用来存放proto文件,文件名随意取
直接以官方demo为例,稍加修改(加了个age)
option java_package = "com.example.songzeceng.studyofretrofit.item"; // 输出包名
option java_outer_classname = "PersonProto"; // 输出类名
// 一个message相当于一个类
message Person {
required string name = 1; // require表示必须赋初值,optional则不必
required int32 id = 2; // 32位整型,也就是java里的int
required int32 age = 3; // 1 2 3 4是属性的序号,在同一个大括号内(不包括嵌套),序号唯一
optional string email = 4;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME]; // 默认值
}
// repeated是集合
repeated PhoneNumber phones = 5;
}
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message AddressBook {
// 集合
repeated Person people = 1;
}
而后编译,会在build文件夹里找到生成的java类
我的因为输出包名里加了个item,所以它生成了两个类,其实用哪个都可以
如此,就可以在MainActivity里使用protoBuf生成的类了,一般是用Builder通过get/set来设置属性,build()方法构建对象
PersonProto.Person.Builder builder = PersonProto.Person.newBuilder();
builder.setName("玉面郎君菲尔米诺");
builder.setAge(30);
builder.setId(9);
PersonProto.Person person = builder.build();
对于集合属性,可以通过add()方法设置
在网络请求或文件操作等情况下,也可以通过字节流等方式解析构建对象
对于build出来的对象,我们就可以正常使用了。不过在输出字符串属性,最好通过统一编解码来输出
try {
String name = new String(person.getName().getBytes("utf-8"), "utf-8");
int age = person.getAge();
int id = person.getId();
System.out.println("name:" + name + "--age:" + age + "--id:" + id);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
输出结果如下
最后,如果需要把对象进行转换或写入到输出流,也有相应的方法可以调用
protoBuf的使用大体如此,欢迎在评论区发表意见。
参考文献:
ProtoBuf在Android中的简单使用
Android Studio使用protobuf协议开发