protobuf整合-Android
Google Protocol Buffers 簡稱 Protobuf,類似 json 或 XML,是一種序列化結構數據的機制,但是比它們更小、更快、更簡單。同時支持多語言,跨平台。
目前主要有兩個大版本:proto2 和 proto3。
其中 proto2 支持 Java、Python、 Objective-C、和 C++
。
proto3 增加了對Go、JavaNano、Ruby、和 C#
的支持。
案例
syntax = "proto3";
package tutorial;
import "google/protobuf/timestamp.proto";
//option java_package = "com.katyusha.aron.demo";
package com.katyusha.aron.demo;
option java_outer_classname = "AddressBookProtos";
message Person {
string name = 1;
int32 id = 2;
string email = 3;
enum PhoneType{
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
repeated PhoneNumber phone = 4;
}
message AddressBook {
repeated Person person = 1;
}
rotobuf使用.proto
文件來定義數據格式,並同時提供編譯器將這些文件編譯為各種語言的源碼。
message 格式非常簡單。每種類型的 message 包含一個或者多個唯一編碼字段,每個字段由名稱和值類型組成,值類型可以是數字(整形或者浮點型)、布爾值、字符串、原始字節,甚至是其他的 message(如上例所示)。Protobuf 允許 message 中包含 message,以達到分層嵌套。
值得注意的一點是,每個屬性都有唯一的一個tag
,上面的0,1,2...
等,這些tag
非常重要,是 Prodobuf 編碼時使用的對每個屬性的唯一標識符————Prodobuf 並不使用屬性名(name,id,email...
)來編碼。因而,在定義過一個 message 之后,原則上都不應該再修改每個屬性的tag
,因為一旦修改,可能就會出現新老數據版本解析出錯的問題。
關鍵字
- syntax:聲明版本。例如上面
syntax="proto3"
,如果沒有聲明,則默認是proto2
。 - package:聲明包名.
- import:導入包。類似於java,例如上面導入了
timestamp.proto
包。 - java_package:指定生成的類應該放在什么Java包名下。如果你沒有顯式地指定這個值,則它簡單地匹配由package 聲明給出的Java包名,但這些名字通常都不是合適的Java包名 (由於它們通常不以一個域名打頭)。
- java_outer_classname:定義應該包含這個文件中所有類的類名。如果你沒有顯式地給定java_outer_classname ,則將通過把文件名轉換為首字母大寫來生成。例如上面例子編譯生成的文件名和類名是
AddressBookProtos
。 - message:類似於java中的class關鍵字。
- repeated:用於修飾屬性,表示對應的屬性是個
array
。
Android中使用protobuf
首先創建proto文件,該文件定義了你要使用的數據的數據格式。
通過proto文件,編譯生成proto java class,生成的類中包含你需要的getter/setter,這個java class就類似於我們平常所用的java bean,但其還包含很多很多的別的功能函數。在android中, 我們可以通過集成Gradle Plugin for Protobuf來編譯proto文件。
配置:方法1
- 在項目根的gradle文件中添加如下內容():
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.9'
}
}
- 在app module下的gradle文件中:
apply plugin: 'com.google.protobuf' //最頂端的設置
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.5.1-1'
}
plugins {
javalite {
artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
}
}
generateProtoTasks {
all().each { task ->
task.builtins {
remove java
}
task.plugins {
javalite {}
}
}
}
}
添加依賴
在app module下的gradle的dependencies中
方法1:
implementation 'com.google.protobuf:protobuf-lite:3.0.1'
生成Java文件
項目編譯之后,會在app\build\generated\source\proto\360Debug\javalite
中自動生成Java文件,目錄結構是在/proto
文件中的package 包結構;
優點
- proto文件修改之后,編譯一下自動就更新了,無需多余操作
缺點
- Android項目編譯速度慢了點...
配置:方法2
- 在項目根的gradle文件中添加如下內容():
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.9'
}
}
- 在app module下的gradle文件中:
apply plugin: 'com.google.protobuf' //最頂端的設置
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.5.1'
}
generateProtoTasks {
all().each { task ->
task.builtins {
remove java
}
task.plugins {
javalite {}
}
}
}
}
添加依賴
在app module下的gradle的dependencies中
api 'com.google.protobuf:protobuf-java:3.5.1'
api 'com.google.protobuf:protoc:3.5.1'
生成Java
- 安裝插件 GenProtobuf,
- 設置編譯為java
- 選擇proto文件即可在對應目錄生成Java文件
- 將生成的Java文件復制到相應的文件夾中即可
優勢:
- 代碼快速生成,
- 生成自由