Android Studio使用ProtocolBuffers
protobuf的java庫比較大,為滿足android移動裝置在記憶體、效能等各方面的要求,google也推出了android定製版protobuf-lite庫。
使用步驟
- 在 .proto 檔案中定義訊息格式。
語法學習可參考官方文件。
語法有syntax2 syntax3的區分,可在書寫schema的時候宣告用哪個版本,3相對2來說有更好的壓縮特性。 - 使用 Protocol Buffer 編譯器編譯生成所需的java檔案。
編譯器生成及用法參見http://www.jianshu.com/p/e8712962f0e9
每次手動執行 Protocol Buffers 編譯器將 .proto 檔案轉換為Java檔案顯然有點太麻煩,因此google提供了一個Android Studio gradle外掛 protobuf-gradle-plugin ,以便於在我們專案的編譯期間自動地執行 Protocol Buffers 編譯器。 -
使用Java Protocol Buffer API讀寫訊息。
整個使用過程如下圖下面就以Demo展示protobuf-gradle-plugin+protobuf-lite庫實現訊息序列化和反序列化的過程。
gradle整合protobuf-gradle-plugin
app module的gradle指令碼如下:
apply plugin: 'com.android.application'
apply plugin: 'com.google.protobuf' //在gradle指令碼開始處宣告依賴的外掛
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0'//配置plugin的版本資訊
}
}
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.dy.testprotocolbuffer"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
//編寫編譯任務,呼叫plugin編譯生成java檔案
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.0.0'//編譯器版本
}
plugins {
javalite {
artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'//指定當前工程使用的protobuf版本為javalite版,以生成javalite版的java類
}
}
generateProtoTasks.generatedFilesBaseDir = "$projectDir/src/main/java" //指定編譯生成java類的存放位置
generateProtoTasks {
all().each { task ->
task.plugins {
javalite {
outputSubDir = '' //指定存放位置的二級目錄,這裡未指定
}
}
}
}
}
//指定原始.proto檔案的位置
android {
sourceSets {
main {
java {
srcDirs 'src/main/java'
}
proto {
srcDirs 'src/main/proto'
}
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.1.0'
compile 'com.google.protobuf:protobuf-lite:3.0.0' //依賴protobuf-lite庫
}
工程目錄如下:
關於protobuf-gradle-plugin的更多用法可參考官方文件https://github.com/google/protobuf-gradle-plugin
schema編寫(.proto檔案)
我們將以下Json示例轉為pb格式:
{
"data":[
{
"datatype":1,
"itemdata":
{//共有欄位45個
"sname":"\u5fae\u533b",
"packageid":"330611",
…
"tabs":[
{
"type":1,
"f":"abc"
},
…
]
}
},
…
],
"hasNextPage":true,
"dirtag":"soft"
}
schema編寫如下:
syntax = "proto2";
package com.dy.messagepackdemo.protobuffer.model;
option java_package = "com.dy.messagepackdemo.protobuffer.model";
option java_outer_classname = "ResponsePB";
message Tab {
required int32 type = 1;
optional string f = 2;
}
message ItemData {
required string sname = 1;
required string packageid = 2;
...
repeated Tab tabs = 45;
}
message DataItem {
required int32 datatype = 1;
required ItemData itemdata = 2;
}
message ResponsePB {
repeated DataItem data = 1;
required bool hasNextPage = 2;
required string dirtag = 3;
}
這個schema已經將上面json示例的層次結構體現的很明顯了。簡單解釋一下各引數的意義及用法:
- syntax指定用哪個版本的語法,proto3比2有更好的壓縮特性
- package指定編譯生成java類的包名
- java_outer_classname指定java類的類名
- 修飾符:required表示必填,optional可選,repeated表示重複的list
- 每個層級內的資料要按順序編號,也就是上一篇文中講的field_number
- 每個結構體是一個message,message之間可以互相引用。
編譯
build工程,可以看到在java包下生成了debug目錄(由於當前是debug模式),再下面就是我們想要的包及schema編譯後的java檔案。
使用編譯生成的java類,就可以進行資料的序列化和反序列化了。
序列化操作
構造一個response資料並寫入檔案
public static void writeResponseToPbFile(String pbfilepath, ResponseJson responseJson) {
File fproto = new File(pbfilepath);
if (!fproto.exists()) {
try {
fproto.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
//build response
//構造builder
ResponsePB.Response.Builder responseBuilder = ResponsePB.Response.newBuilder();
//填充資料
responseBuilder.setHasNextPage(resultJson.hasNextPage);
responseBuilder.setDirtag(resultJson.dirtag);
...//此處省略若干行
//結束 build
ResponsePB.Response response = responseBuilder.build();
//寫檔案
try {
FileOutputStream foProto = new FileOutputStream(fproto);
response.writeTo(foProto);
foProto.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
用法很簡單,生成物件的構造器builder,用提供的各種Set方法填充資料,最後build,二進位制資料就生成了。用法跟普通的pojo類沒有區別。
反序列化
將檔案中的資料解析到Response物件中
public static void parseXinruiPb(byte[] bytes) {
ResponsePB.Response response = ResponsePB.Response.parseFrom(bytes);
boolean hasNextPage = response.getHasNextPage();
String dirtag = response.getDirtag();
...
}
用起來也非常簡單,parseFrom搞定。 值得一提的是,由於protobuf的儲存結構決定了它在進行資料解析的時候必須將整個資料完整解析一遍才能得到你想要的資料,也就是資料傳輸過程中所謂的封包-解析過程,這與json解析的過程類似,區別在於它對key鍵的特殊編碼,省去了字元匹配的過程。
更高階的用法--動態編譯
Protobuf 提供了 google::protobuf::compiler 包來完成動態編譯的功能。感興趣的同學可以自行研究。
相關文章
- 使用protocolbuffers優缺點分析Protocol
- Android studio使用小技巧Android
- 使用Android studio建立apkAndroidAPK
- Android Studio3.3的使用Android
- Android Studio中jni的使用Android
- Android Studio 2.0 to Android Studio 3.0Android
- Now in Android:02 - 歡迎使用 Android Studio 4.0 !Android
- Android Studio使用離線GradleAndroidGradle
- Android studio的安裝與使用Android
- Android Studio 快捷鍵使用總結Android
- 最全面的Android Studio使用教程Android
- Android Studio 使用 Gradle 打包 JarAndroidGradleJAR
- Android學習系列(41)--Android Studio簡單使用Android
- 在Android Studio中使用Lambda表示式Android
- Android Studio 使用Gradle多渠道打包AndroidGradle
- Android StudioAndroid
- android studio安裝教程|android studio漢化包Android
- 使用命令列建立Android Studio專案命令列Android
- 關於Android Studio使用Git的總結AndroidGit
- Android Studio: Kotlin使用DataBinding異常AndroidKotlin
- Android Studio中如何支援使用Lambda表示式Android
- Android Studio使用gradle向Maven私服提交AndroidGradleMaven
- Android Studio 3 0 如何生成 aar 並使用?Android
- 工具使用之Android Studio快捷鍵-mac版AndroidMac
- 使用 Gradle 管理你的 Android Studio 工程GradleAndroid
- android--Android Studio使用terminal終端(命令視窗)Android
- Android Studio 使用教程(二十一)之Android Studio 查詢功能(搜尋功能)及快捷鍵Android
- Android Studio工具Android
- Android Studio 初探Android
- Android studio jniAndroid
- Android Studio配置Android
- Android Studio使用筆記(1)使用android studio時避免每次啟動都進行網路gradle sync的方法Android筆記Gradle
- Android Studio|IntelliJ IDEA Git使用小技巧AndroidIntelliJIdeaGit
- 使用更新補丁對Android Studio進行更新。Android
- Butterknife 註解框架在 Android Studio 上的使用框架Android
- Android Studio 使用WiFi除錯(支援AS 2 3以上)AndroidWiFi除錯
- Android Studio除錯功能使用總結【轉】Android除錯
- Android Studio 使用正式簽名進行除錯Android除錯