一、是什麼
Protocol Buffers,是Google公司開發的一種數據描述語言,是一種平臺無關、語言無關、可擴展且類似於XML能夠將結構化數據序列化,可用於數據存儲、通信協議等方面。
二、爲什麼
- 更簡單
- 數據描述文件只需原來的1/10至1/3
- 解析速度是原來的20倍至100倍
- 減少了二義性
- 生成了更容易在編程中使用的數據訪問類且支持多種編程語言
三、支持的語言
Language | Source |
---|---|
C++ (include C++ runtime and protoc) | src |
Java | java |
Python | python |
Objective-C | objectivec |
C# | csharp |
JavaScript | js |
Ruby | ruby |
Go | golang/protobuf |
PHP | php |
Dart | dart-lang/protobuf |
四、Android 中使用
4.1 添加依賴
protobuf 插件
plugins {
...
// protobuf 插件, AS 3.x 需要 0.8.2 及以上
id 'com.google.protobuf' version '0.8.17'
}
AS 3.x對應的protoBuf版本必須不低於0.8.2,否則報錯 Resolving configuration 'debugCompile' directly is not allowed
模塊添加依賴
android {
...
sourceSets {
main {
// 配置 proto 源文件目錄, 可選的, 默認在 'src/main/proto'
proto {
srcDir 'src/main/proto'
}
}
}
}
dependencies {
...
// protobuf
implementation "com.google.protobuf:protobuf-javalite:3.18.0"
}
protobuf {
// Configures the Protobuf compilation and the protoc executable
protoc {
// Downloads from the repositories
artifact = "com.google.protobuf:protoc:3.14.0"
}
// Generates the java Protobuf-lite code for the Protobufs in this project
generateProtoTasks {
all().each { task ->
task.builtins {
// Configures the task output type
java {
// Java Lite has smaller code size and is recommended for Android
option 'lite'
}
}
}
}
}
4.2 創建源文件
在對應源文件目錄下面,創建文件。
如圖:
文件內容如下:
syntax = "proto3"; // protobuf2 和 protobuf3 有區別
option java_package = "com.xyz.test"; // 指定生成的類的包名
option java_multiple_files = true; // 是否爲每個類單獨生成一個文件
// 類
message Pet {
int32 id = 0x01;
repeated Dog dogs = 0x02;
map<string, Cat> cats = 0x03;
}
message Dog {
string name = 0x01;
int32 age = 0x02;
}
message Cat {
string name = 0x01;
int32 age = 0x02;
string food = 0x03;
}
支持
枚舉 enum
List: repeated
Map: map
更多數據結構請查閱官方文檔。
4.3 編譯源文件
build 之後,生成的代碼如下:
可以點開查看對應代碼。
建議:大型項目中,爲了加快編譯速度,可以將 pb 文件單獨作爲一個模塊。
4.4 序列化與反序列化
val dog1 = Dog.newBuilder().setName("小黑").setAge(5).build()
val dog2 = Dog.newBuilder().setName("旺財").setAge(3).build()
val cat1 = Cat.newBuilder().setName("小花").setAge(4).setFood("貓糧").build()
val cat2 = Cat.newBuilder().setName("貓精").setAge(1000).setFood("人").build()
val pet = Pet.newBuilder().setId(1)
.putCats("凡間", cat1)
.putCats("妖界", cat2)
.addDogs(dog1)
.addDogs(dog2)
.build()
val toByteArray = pet.toByteArray()
val result: Pet? = try {
Pet.parseFrom(petArray)
} catch (ex: InvalidProtocolBufferException) {
Log.d(TAG, "parseData exception: ${ex.message}")
null
}
更多使用方法,請查閱官網文檔和相應的 API