Android開發(fā)之在Windows上Protocol Buffer的接入

1 Introduction

Protocol Buffers是在網(wǎng)絡通訊或者數(shù)據(jù)存儲時用到的一種語言無關(guān)、平臺無關(guān)、可擴展的序列化結(jié)構(gòu)數(shù)據(jù)格式。類似于XML,不過比XML更小、更快、更簡單。
你首先要定義自己想要的數(shù)據(jù)結(jié)構(gòu)(在 .proto 文件中定義數(shù)據(jù)結(jié)構(gòu)信息),經(jīng)過Protocol Buffers 編譯后生成.java代碼文件,就可以根據(jù).java里的數(shù)據(jù)對象來進行讀寫操作。

下面談談在Android開發(fā)中如何接入protocol buffers。

2 JavaNano

protocol buffers支持多種語言環(huán)境下的使用。Java雖然是Android開發(fā)的絕對主流開發(fā)語言,但是protobuf還是針對Android開發(fā)這種性能資源有限的系統(tǒng)專門提供了一個JavaNano版本(而不是直接使用protobuf的Java版本進行編譯),在代碼量和運行時開銷上都比較友好(詳細介紹點這)。

3 Usage

3.1 Defining A Message Type

即編寫.protol文件,通常這部分工作由后臺完成,畢竟是后端來決定在網(wǎng)絡連接中,傳輸什么字段給客戶端或者客戶端提交什么字段給服務器。類似于定義json的字段結(jié)構(gòu)。
示例:

syntax = "proto3";//指定protocol buffer版本

message SearchRequest {//這是一個message的定義,包含了三個屬性,每個屬性有一個字段名和類型
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

message SearchResponse {
 ...//一些字段的定義
}

3.2 What's Generated From Your .proto?

運行protocol buffer 編譯器去編譯.proto文件,可以根據(jù)你選擇的語言生成相應的代碼文件。
編譯Java語言版本的時候,編譯器會為每一個message生成.java類文件,每個類還對應一個Builder提供給開發(fā)者去構(gòu)建實例。值得注意的是,我們在Android上使用的protobuf JavaNano與protobuf Java相比,去除了一些復雜的特性。比如剛剛提到的Builder,還有Descriptors都被去掉。同時通過直接訪問類的public成員變量的方式取代了set/get方法。

3.3 Compile on Windows

在Windwos上編譯.protol文件十分簡單。

  1. protocol 編譯器是用C++寫的,C++開發(fā)者可以在github google/protobuf下載源碼編譯出來。對于非C++開發(fā)者,也可以直接下載現(xiàn)成的編譯器protoc-3.0.0-beta-3-win32.zip。(這里獲取各個OS下的編譯器。
  2. 解壓下載好的protoc-3.0.0-beta-3-win32.zip,將解壓后的目錄名添加到Windows的PATH環(huán)境變量
  3. 調(diào)出Windows的命令行,輸入protoc --version,出現(xiàn)以下畫面,說明編譯器可以使用了。
    protoc --version
  4. 生成Java類
    protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/message.proto
    上面的$SRC_DIR表示存放message.proto文件的路徑,$DST_DIR表示生成java類存放的路徑。-I=$SRC_DIR可以省略,如果message.proto文件與protoc.exe在同一個目錄下。
    例如:
protoc -I=D:\ --javanano_out=E:\ D:\message.proto
--javanano_out

這里我的message.proto文件放在D盤,指定編譯生成的java類放到E盤。

Message.java

可以看到編譯出來的java類文件已經(jīng)安靜地躺在我的E盤中。這個類就和我們平時使用的Bean類的用法一毛一樣了。

3.4 Compile Options

有一些常用的編譯選項可以在message.proto文件中預先定義:

option java_package = "com.android.develop";  //指定java類的包名
 
option java_multiple_files = true; //message.proto文件中的每個message都生成一個對應的.java。設為fasle時只導出一個.java類文件,所有message都以內(nèi)部類的形式出現(xiàn)
 
option java_outer_classname = "MessageBean";//當只生成一個.java文件時,指定類名, java_multiple_files =true時,這個屬性無效。
 
message SearchRequest {
  int32 page_number = 2;
  int32 result_per_page = 3;
}

message OtherMessages{
.......
}

命令行編譯時,還有以下選項可以用:

  1. optional_field_style={default,accessors,reftypes} (default: default)
    設置成員變量的訪問方式。default就是public直接訪問,accessors就是set/get方法,reftypes使用基本類型的包裝類來定義字段類型(例如Interger代替原本的int,空值為null,可以避免空值==0時的歧義。)。
  2. enum_style={c,java} (default: c)
  3. parcelable_messages={true,false} (default: false)
    開啟了這個選項后,編譯生成的java類自動實現(xiàn)Parcelable接口,最常用的Intent傳值就可以直接使用這些對象。

使用示例:
protoc --javanano_out=optional_field_style=accessors,parcelable_messages=true:d:\ D:\protoc-3.0.0-beta-3-win32\message.proto
這時,編譯出來的java類,就是通過set/get方法訪問private的成員變量,同時也已經(jīng)實現(xiàn)了Parcelable接口。

3.5 The Protocol Buffer API

每一個編譯后生成的protobuf Message類都提供了方法去讀寫二進制格式的數(shù)據(jù)。

  1. byte[] toByteArray();
    序列化message,并返回一個包含了message的原始數(shù)據(jù)的byte數(shù)組。
  2. static SearchRequest parseFrom(byte[] data);
    從一個給定的byte數(shù)組中,反序列化出來一個message對象。
  3. void writeTo(OutputStream output);
    序列化message,并寫到一個OutputStream上。
  4. static SearchRequest parseFrom(InputStream input);
    從一個InputStream讀取并反序列化出message對象。

3.6 Protocol Buffers and O-O Design

官方推薦使用包裝類的形式來對生成的ProtoBuf Message java類進行封裝及擴展,而不是繼承它們。因為繼承并重寫父類方法的時候?qū)茐腜rotoBuf Message類的內(nèi)在機制。

You should never add behaviour to the generated classes by inheriting from them. This will break internal mechanisms and is not good object-oriented practice anyway.

4 Links

  1. 官方指南
  2. google/protobuf/README.md
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • 由于工程項目中擬采用一種簡便高效的數(shù)據(jù)交換格式,百度了一下發(fā)現(xiàn)除了采用 xml、JSON 還有 ProtoBuf(...
    黃海佳閱讀 49,166評論 1 23
  • 前面翻譯了谷歌的Proto3 語言指南 這一篇講實戰(zhàn)應用先總結(jié)一下 Protocol Buffer 一、什么是Pr...
    黃海佳閱讀 4,412評論 1 1
  • 因為https://blog.csdn.net/urdfmqcul2/article/details/787889...
    蘇大盒子閱讀 4,802評論 1 1
  • 0 是整型的0 / 字符的00.0是實數(shù)的0'\0'是字符的0 NULL是指針的0 '0'是字符 的48 asci...
    SmallTwo閱讀 517評論 0 0
  • 昨晚和阿甘小酌了幾瓶啤酒,擼了兩手烤串,絮絮叨叨的講起了許多少年往事,回到酒店房間開了幾局農(nóng)藥,不知是酒量漸虛,還...
    楊小燁閱讀 170評論 0 0

友情鏈接更多精彩內(nèi)容