android java protocol buffer,Android开发之在Windows上Protocol Buffer的接入

本文介绍了在Android开发中如何使用Protocol Buffers(protobuf),特别是针对Android优化的JavaNano版本。首先,定义.proto文件来描述数据结构,然后使用protobuf编译器生成Java代码。在Windows上编译.proto文件,通过设置编译选项可以生成JavaNano类,这些类支持直接字段访问和Parcelable接口。最后,文章阐述了protobuf API的基本用法,包括序列化和反序列化操作,并建议不要继承protobuf生成的类,而是使用包装类进行扩展。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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文件十分简单。

protocol 编译器是用C++写的,C++开发者可以在github protoc-3.0.0-beta-3-win32.zip。(这里获取各个OS下的编译器。)

解压下载好的protoc-3.0.0-beta-3-win32.zip,将解压后的目录名添加到Windows的PATH环境变量。

调出Windows的命令行,输入protoc --version,出现以下画面,说明编译器可以使用了。

47cd56f5e915?t=1512789862048

protoc --version

生成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

47cd56f5e915?t=1512789862048

--javanano_out

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

47cd56f5e915?t=1512789862048

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{

.......

}

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

optional_field_style={default,accessors,reftypes} (default: default)

设置成员变量的访问方式。default就是public直接访问,accessors就是set/get方法,reftypes使用基本类型的包装类来定义字段类型(例如Interger代替原本的int,空值为null,可以避免空值==0时的歧义。)。

enum_style={c,java} (default: c)

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类都提供了方法去读写二进制格式的数据。

byte[] toByteArray();

序列化message,并返回一个包含了message的原始数据的byte数组。

static SearchRequest parseFrom(byte[] data);

从一个给定的byte数组中,反序列化出来一个message对象。

void writeTo(OutputStream output);

序列化message,并写到一个OutputStream上。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值