眾所周知,xml 和 json 常見(jiàn)的订晌、應(yīng)用廣泛的序列化和反序列化協(xié)議虏辫,而 google 自家出產(chǎn)的 Protobuf 也是具備了優(yōu)秀協(xié)議所需要的眾多典型特征。
- 標(biāo)準(zhǔn)的 IDL 和 IDL編譯器锈拨,這使得對(duì)工程師非常友好
- 序列化數(shù)據(jù)非常簡(jiǎn)潔砌庄,與 xml 相比,其序列化后的數(shù)據(jù)大小約 xml 的1/3到1/10
- 解析速度非侈仁啵快娄昆,對(duì)比 xml,是其的20-100倍
- 提供了友好的動(dòng)態(tài)庫(kù)缝彬,使用簡(jiǎn)單萌焰,反序列化只需要一行代碼
那在 android 如何簡(jiǎn)單快捷地使用 protobuf 呢
android 提供了一個(gè)插件 protobuf gradle plugin,在構(gòu)建時(shí)生成序列化文件
- 根目錄 build.gradle 配置 protobuf gradle plugin
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0'
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.8'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
- 項(xiàng)目 build.gradle 配置 protobuf
apply plugin: 'com.google.protobuf' //聲明插件
. . .
android {
. . .
sourceSets {
main {
java {
srcDir 'src/main/java'
}
proto {
srcDir 'src/main/protoBean' // proto 文件位置
}
}
}
}
protobuf { //配置 proto 編譯器
protoc {
artifact = 'com.google.protobuf:protoc:3.5.1' //注意 這里版本號(hào)需要與 protobuf-java lib 一致
}
//這里配置生成目錄跌造,編譯后會(huì)在 build\generated\source\proto 的目錄下生成對(duì)應(yīng)的java文件
generateProtoTasks {
all().each { task ->
task.builtins {
remove java
}
task.builtins {
java {}
}
}
}
}
dependencies{
. . .
implementation 'com.google.protobuf:protobuf-java:3.5.1' //依賴(lài) protobuf-java lib
}
- proto 文件杆怕,即需要序列化的文件
syntax = "proto3";
option java_package = "com.wjc.jcdemolist.demo.protoBuf";
option java_outer_classname = "_StudentSerializable";
message _Student {
//指定字段的類(lèi)型 定義字段的編號(hào)族购,在Protocol Buffers中壳贪,字段的編號(hào)非常重要
// 字段名僅僅是作為參考和生成代碼用。需要注意的是字段的編號(hào)區(qū)間范圍寝杖,
//其中19000 ~ 19999被Protocol Buffers作為保留字段
string name = 1;
string sax = 2;
int32 age = 3;
//required指定該字段必須賦值违施,禁止為空(在v3中該約束被移除);optional指定字段為可選字段瑟幕,可以為空磕蒲,
//對(duì)于optional字段還可以使用[default]指定默認(rèn)值,如果沒(méi)有指定只盹,則會(huì)使用字段類(lèi)型的默認(rèn)值
repeated _Course course = 4; //使用repeated指定字段為集合
}
//在一個(gè)proto文件中可以同時(shí)定義多個(gè)message類(lèi)型辣往,生成代碼時(shí)根據(jù)生成代碼的目標(biāo)語(yǔ)言不同,
//處理的方式不太一樣殖卑,如Java會(huì)針對(duì)每個(gè)message類(lèi)型生成一個(gè).java文件
message _Course {
string name = 1;
float score = 2;
}
proto 語(yǔ)法這里就不說(shuō)講啦站削,如需要詳情了解,自個(gè)百度吧
注意在項(xiàng)目 build.gradle 中孵稽,需要把這個(gè)文件路徑放入配置中
- 生成 protobuf.java 代碼
android studio 下 Build -> Rebuild Project 后许起,在 build \ generated \ source \ proto 會(huì)生成對(duì)應(yīng) protobuf java 代碼
生了 protobuf java 十偶,那如何用呢,請(qǐng)看下面
public static byte[] serialize() {
_StudentSerializable._Course.Builder courseBuilder = _StudentSerializable._Course.newBuilder()
.setName("中文").setScore(149);
_StudentSerializable._Student.Builder studentBuilder = _StudentSerializable._Student.newBuilder();
studentBuilder.setName("Jc").setAge(16).setSax("man").addCourse(courseBuilder);
_StudentSerializable._Student student = studentBuilder.build();
return student.toByteArray();
}
public static _StudentSerializable._Student deserialize(byte[] bs) {
try {
return _StudentSerializable._Student.parseFrom(bs);
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
return null;
}
使用起來(lái)园细,是很簡(jiǎn)單吧惦积,序列化使用 builder 模式,而反序列化一行代碼就行了