buildscript { repositories { jcenter() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:2.2.3' classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0' }}
注意 Gradle版本至少是 2.12 并且Java 7,本例子使用的是2.2.3,protobuf-gradle-plugin使用最新的0.8.0版本。
...apply plugin: 'com.google.protobuf'...protobuf { //这里配置protoc编译器 protoc { artifact = 'com.google.protobuf:protoc:3.0.0-alpha-3' } 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.0' ...}
这里配置的是protobuf-lite最新的3.0.0版本,这个官方推荐给Android中使用的版本。
一般情况下在app/main目录下创建proto目录,用于放置.proto文件。本例中创建了一个book.proto
syntax = "proto2";option java_package = "net.angrycode.bean";package bean;message Book { required int32 id = 1; required string name = 2; optional string desc = 3;}
proto2与proto3的语法不大一样,例如proto3中不需要required和optional修饰字段,而proto2是需要的,这里指定了proto2的语法版本。
这里指定了java_package属性,说明当protoc生成这个java类的包名为net.angrycode.bean
最后使用message定义了一个名为Book
的数据结构,或者说通讯协议。Book
有3个字段其中id
和name
是必须的,而desc
是可选字段。如果必选字段缺失,读写时会发生com.google.protobuf.UninitializedMessageException: Message was missing required fields
异常。
在Android Studio中Build菜单选中Make Project或者Reruild Project可以在app/build目录下生成对应的java文件,例如创建一个Book实例
BookOuterClass.Book book = BookOuterClass.Book.newBuilder() .setId(1) .setName("Prime") .setDesc("Code Book") .build();
proto可以往外写,使用writeTo(OutputStream)方法,可以是本地文件流,也可以是网络流。这里写入文件流
void save() { File dir = Environment.getExternalStorageDirectory(); File file = new File(dir, "book"); try { FileOutputStream outputStream = new FileOutputStream(file); book.writeTo(outputStream); outputStream.close(); } catch (IOException e) { Log.e(TAG, e.getMessage()); } }
proto是二进制传输,故可以读取文件流,或者网络流,这里文件模拟,使用parseFrom(byte[])方法。
void read() { File dir = Environment.getExternalStorageDirectory(); File file = new File(dir, "book"); try { FileInputStream inputStream = new FileInputStream(file); ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] data = new byte[1024]; int len = -1; while ((len = inputStream.read(data)) != -1) { out.write(data, 0, len); out.flush(); } BookOuterClass.Book book = BookOuterClass.Book.parseFrom(out.toByteArray()); out.close(); textView.setText("name:" + book.getName() + ",desc:" + book.getDesc()); } catch (IOException e) { Log.e(TAG, e.getMessage()); } }
https://developers.google.com/protocol-buffers/
https://github.com/google/protobuf
https://github.com/google/protobuf-gradle-plugin