Android开发之在Windows上Protocol Buffer的接入

1 Introduction

Protocol Buffers是在网络通讯或者数据存储时用到的一种语言无关、平台无关、可扩展的序列化结构数据格式。类似于XML,不过比XML更小、更快、更简单。
你首先要定义自己想要的数据结构(在 .proto 文件中定义数据结构信息),经过Protocol Buffers 编译后生成.java代码文件,就可以根据.java里的数据对象来进行读写操作。

下面谈谈在Android开发中如何接入protocol buffers。

2 JavaNano

protocol buffers支持多种语言环境下的使用。Java虽然是Android开发的绝对主流开发语言,但是protobuf还是针对Android开发这种性能资源有限的系统专门提供了一个JavaNano版本(而不是直接使用protobuf的Java版本进行编译),在代码量和运行时开销上都比较友好(详细介绍点这)。

3 Usage

3.1 Defining A Message Type

即编写.protol文件,通常这部分工作由后台完成,毕竟是后端来决定在网络连接中,传输什么字段给客户端或者客户端提交什么字段给服务器。类似于定义json的字段结构。
示例:

syntax = "proto3";//指定protocol buffer版本

message SearchRequest {//这是一个message的定义,包含了三个属性,每个属性有一个字段名和类型
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

message SearchResponse {
 ...//一些字段的定义
}

3.2 What's Generated From Your .proto?

运行protocol buffer 编译器去编译.proto文件,可以根据你选择的语言生成相应的代码文件。
编译Java语言版本的时候,编译器会为每一个message生成.java类文件,每个类还对应一个Builder提供给开发者去构建实例。值得注意的是,我们在Android上使用的protobuf JavaNano与protobuf Java相比,去除了一些复杂的特性。比如刚刚提到的Builder,还有Descriptors都被去掉。同时通过直接访问类的public成员变量的方式取代了set/get方法。

3.3 Compile on Windows

在Windwos上编译.protol文件十分简单。

  1. protocol 编译器是用C++写的,C++开发者可以在github google/protobuf下载源码编译出来。对于非C++开发者,也可以直接下载现成的编译器protoc-3.0.0-beta-3-win32.zip。(这里获取各个OS下的编译器。
  2. 解压下载好的protoc-3.0.0-beta-3-win32.zip,将解压后的目录名添加到Windows的PATH环境变量
  3. 调出Windows的命令行,输入protoc --version,出现以下画面,说明编译器可以使用了。
    protoc --version
  4. 生成Java类
    protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/message.proto
    上面的$SRC_DIR表示存放message.proto文件的路径,$DST_DIR表示生成java类存放的路径。-I=$SRC_DIR可以省略,如果message.proto文件与protoc.exe在同一个目录下。
    例如:
protoc -I=D:\ --javanano_out=E:\ D:\message.proto
--javanano_out

这里我的message.proto文件放在D盘,指定编译生成的java类放到E盘。

Message.java

可以看到编译出来的java类文件已经安静地躺在我的E盘中。这个类就和我们平时使用的Bean类的用法一毛一样了。

3.4 Compile Options

有一些常用的编译选项可以在message.proto文件中预先定义:

option java_package = "com.android.develop";  //指定java类的包名
 
option java_multiple_files = true; //message.proto文件中的每个message都生成一个对应的.java。设为fasle时只导出一个.java类文件,所有message都以内部类的形式出现
 
option java_outer_classname = "MessageBean";//当只生成一个.java文件时,指定类名, java_multiple_files =true时,这个属性无效。
 
message SearchRequest {
  int32 page_number = 2;
  int32 result_per_page = 3;
}

message OtherMessages{
.......
}

命令行编译时,还有以下选项可以用:

  1. optional_field_style={default,accessors,reftypes} (default: default)
    设置成员变量的访问方式。default就是public直接访问,accessors就是set/get方法,reftypes使用基本类型的包装类来定义字段类型(例如Interger代替原本的int,空值为null,可以避免空值==0时的歧义。)。
  2. enum_style={c,java} (default: c)
  3. parcelable_messages={true,false} (default: false)
    开启了这个选项后,编译生成的java类自动实现Parcelable接口,最常用的Intent传值就可以直接使用这些对象。

使用示例:
protoc --javanano_out=optional_field_style=accessors,parcelable_messages=true:d:\ D:\protoc-3.0.0-beta-3-win32\message.proto
这时,编译出来的java类,就是通过set/get方法访问private的成员变量,同时也已经实现了Parcelable接口。

3.5 The Protocol Buffer API

每一个编译后生成的protobuf Message类都提供了方法去读写二进制格式的数据。

  1. byte[] toByteArray();
    序列化message,并返回一个包含了message的原始数据的byte数组。
  2. static SearchRequest parseFrom(byte[] data);
    从一个给定的byte数组中,反序列化出来一个message对象。
  3. void writeTo(OutputStream output);
    序列化message,并写到一个OutputStream上。
  4. static SearchRequest parseFrom(InputStream input);
    从一个InputStream读取并反序列化出message对象。

3.6 Protocol Buffers and O-O Design

官方推荐使用包装类的形式来对生成的ProtoBuf Message java类进行封装及扩展,而不是继承它们。因为继承并重写父类方法的时候将会破坏ProtoBuf Message类的内在机制。

You should never add behaviour to the generated classes by inheriting from them. This will break internal mechanisms and is not good object-oriented practice anyway.

4 Links

  1. 官方指南
  2. google/protobuf/README.md
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容

  • 由于工程项目中拟采用一种简便高效的数据交换格式,百度了一下发现除了采用 xml、JSON 还有 ProtoBuf(...
    黄海佳阅读 48,637评论 1 23
  • 前面翻译了谷歌的Proto3 语言指南 这一篇讲实战应用先总结一下 Protocol Buffer 一、什么是Pr...
    黄海佳阅读 4,119评论 1 1
  • 因为https://blog.csdn.net/urdfmqcul2/article/details/787889...
    苏大盒子阅读 4,407评论 1 1
  • 0 是整型的0 / 字符的00.0是实数的0'\0'是字符的0 NULL是指针的0 '0'是字符 的48 asci...
    SmallTwo阅读 440评论 0 0
  • 昨晚和阿甘小酌了几瓶啤酒,撸了两手烤串,絮絮叨叨的讲起了许多少年往事,回到酒店房间开了几局农药,不知是酒量渐虚,还...
    杨小烨阅读 136评论 0 0