一、简介
Protobuf 全称:Protocol Buffers,是 Google 推出的一种与平台无关、语言无关、可扩展的轻便高效的序列化数据存储格式,类似于我们常用的 xml 和 json。
二、特点
Protobuf 用两个字总结:小,快。用 Protobuf 序列化后的大小是 json 的十分之一,是 xml 格式的二十分之一,而且性能是他们的 5~100 倍。
通常情况下,我们使用 xml 或者 json 进行数据通信是没什么问题的,但是在高性能和大数据通信的情况下,如果有办法压缩数据量,提高传输效率,显然会给用户带来更快更流畅的体验,因此做 LiveChat 自研,Protobuf 成为我们进行数据传输的第一选择。
三、语法
Protobuf 常用关键字介绍
Protobuf 基本数据类型
基本数据类型默认值
protobuf文本示例:
java
//指定Protobuf版本
syntax = "proto3";
//指定包名
package com.example.testprotobuf;
//指定生成的类所在的包名位置
option java_package = "com.example.testprotobuf.internal";
option java_outer_classname = "AudioAcousticMngtProto";
message BandGain {
uint32 bandID = 1;
int32 gain = 2;
}
message Equalizer {
//repeated相当于集合类
repeated BandGain bandGainList = 1;
}
message Equalizerstruct {
uint32 bandnumber = 1;
uint32 groupID = 2;
Equalizer equalizer = 3;
}
message ProtoInt8 {
int32 value = 1;
}
message ProtoUint8 {
uint32 value = 1;
}
message ProtoBool {
bool value = 1;
}
message ProtoString {
string value = 1;
}
//注意:
//1、一个 Protobuf 文件里面可以添加多个消息类,也可以进行嵌套
//2、上面的 1,2,3,4 并不是给字段赋值,而是给每个字段定义一个唯一的编号。这些编号用于二进制格式中标识你的字段,并且在使用你的消息类型后不应更改
//3、1-15 的字段编号只占一个字节进行编码,16-2047 的字段编号占两个字节,包括字段编号和字段类型,因此建议更多的使用 1-15 的字段编号
//4、可以指定最小字段编号为 1,最大字段编号为 2^29 - 1 或 536870911。另外不能使用 19000-19999 的标识号,因为 protobuf 协议实现对这些进行了预留,同样,也不能使用任何以前保留(reserved) 的字段编号
四、具体使用
java
//配置环境:
//app目录下得build.gradle:
plugins {
id 'com.android.application'
id 'com.google.protobuf'
}
android {
......
sourceSets {
main {
//实际测试指不指定无所谓,不影响 Java 文件生成
proto {
srcDir 'src/main/proto'
}
}
}
}
protobuf {
//配置 protoc 编译器
protoc {
artifact = 'com.google.protobuf:protoc:3.21.7'
}
//配置生成目录,编译后会在 build 的目录下生成对应的java文件
generateProtoTasks {
all().each { task ->
task.builtins {
remove java
}
task.builtins {
java {}
}
}
}
}
dependencies {
implementation 'com.google.protobuf:protobuf-java:3.21.7'
//....
}
java
//根目录下:build.gradle:
plugins {
id 'com.android.application' version '8.0.2' apply false
id 'com.android.library' version '8.0.2' apply false
id 'com.google.protobuf' version '0.9.3' apply false
}
java
//java代码:示例序列化的过程
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public byte[] toByteArray() {
AudioAcousticMngtProto.BandGain bandGain = AudioAcousticMngtProto.BandGain.newBuilder().setGain(1).setBandID(2).build();
AudioAcousticMngtProto.Equalizer equalizer = AudioAcousticMngtProto.Equalizer.newBuilder().addBandGainList(bandGain).build();
AudioAcousticMngtProto.Equalizerstruct proto_output = AudioAcousticMngtProto.Equalizerstruct.newBuilder().setBandnumber(3)
.setGroupID(3)
.setEqualizer(equalizer)
.build();
return proto_output.toByteArray();
}
public static AudioAcousticMngtProto.Equalizerstruct fromByteArray(byte[] data) {
AudioAcousticMngtProto.Equalizerstruct equalizerstruct =null;
try {
return equalizerstruct = AudioAcousticMngtProto.Equalizerstruct.parseFrom(data);
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
return equalizerstruct;
}
}