ProtoBuf是Google的一個開源項目是鬼。作用于數據存儲僧须、數據通信和語言無關平臺無關纲刀,擴展便捷。它是一個靈活皆辽、高效柑蛇、自動化的序列化和結構化數據格式,比XML協議的數據格式更小驱闷,更快和更簡單。你可以定義你想要的數據結構空免,然后使用ProtoBuf提供的編譯器生成相應平臺的源代碼空另,編譯器自動化會生成讀寫你結構化數據代碼,然后可以把源碼應用于各種語言蹋砚,你甚至可以在更新數據結構情況下不破壞已經部署基于老格式編譯程序扼菠。
項目github地址
ProtoBuf英文文檔說明
Android中使用
- Gradle依賴ProtoBuf庫
根目錄gradle引入classpath
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0'
}
- 項目目錄gradle依賴ProtoBuf庫摄杂,依賴后可以自動編譯定義好的proto文件,大大節(jié)省工作量循榆。
apply plugin: 'com.google.protobuf'
protobuf {
protoc {
// Download from repositories
artifact = 'com.google.protobuf:protoc:3.2.0'
}
plugins {
javalite {
// The codegen for lite comes as a separate artifact
artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
}
}
generateProtoTasks {
all().each { task ->
task.plugins {
javalite {}
}
}
}
}
dependencies {
compile "com.google.protobuf:protobuf-lite:3.0.1"
compile 'com.google.protobuf:protobuf-java:3.0.0'
}
定義proto消息文件
創(chuàng)建一個.proto文件析恢,一般做法是在main文件下創(chuàng)建一個proto用于存放pro文件。
這是官方給的實例如何定義proto的文件內容
option java_package = "com.jinwei.test.pb";
option java_outer_classname = "BaseProto";
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
//repeated=集合
repeated PhoneNumber phones = 4;
}
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message AddressBook {
//repeated=集合
repeated Person people = 1;
}
option java_package = "com.jinwei.test.pb";
存放的包名 編譯后源碼生成在bild/generated/source/proto目錄中
option java_outer_classname = "BaseProto";
生成后輸出的類名秧饮,不寫默認是文件名字大寫開頭映挂。
message 消息類似于一個類。
proto的三個修飾符說明
required
對于required的字段而言盗尸,初值是必須要提供的柑船,否則字段的便是未初始化的。在Debug模式的buffer庫下編譯的話泼各,序列化話的時候可能會失敗鞍时,而且在反序列化的時候對于該字段的解析會總是失敗的。所以扣蜻,對于修飾符為required的字段逆巍,請在序列化的時候務必給予初始化。optional
對于optional的字段而言莽使,如果未進行初始化锐极,那么一個默認值將賦予該字段,當然也可以指定默認值吮旅,如上述proto定義中的PhoneType字段類型溪烤。-
repeated
對于repeated的字段而言,該字段可以重復多個庇勃,google提供的這個addressbook例子便有個很好的該修飾符的應用場景檬嘀,即每個人可能有多個電話號碼。在高級語言里面责嚷,我們可以通過數組來實現鸳兽,而在proto定義文件中可以使用repeated來修飾,從而達到相同目的罕拂。當然揍异,出現0次也是包含在內的。其中字段標簽標示了字段在二進制流中存放的位置爆班,這個是必須的衷掷,而且序列化與反序列化的時候相同的字段的Tag值必須對應,否則反序列化會出現意想不到的問題柿菩。
proto中的type在不同編程語言中對應的類型
定義完內容后build下項目戚嗅,生成的源文件會在圖中的這個包中
使用Protocol
在網絡傳輸中使用Proto是通過字節(jié)輸出和輸入,所以生成的源碼會包含相關的編解碼方法,內部已經封裝好了編解碼的一些具體實現懦胞,生成后的pro類文件里面已經自動生成了相應編解碼的方法替久。
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//新構建一個對象
BaseProto.Person.Builder builder = BaseProto.Person.newBuilder();
//通過get set方法來訪問字段
builder.getEmail();
builder.setEmail("email");
builder.setId(1);
}
生成的文件提供了相應的解碼方法