Protobuf在Android上面的應用
背景
平時移動端和端之間的資料傳輸基本都是用的json或者xml,對於Protobuf之前一直有聽說過,相比於json和xml有諸多好處,例如資料量小,序列化和反序列化速度快等,所以我們也來嘗試一下Protobuf。
Quick Start
在系統的根目錄的build.gradle
中新增外掛
dependencies { classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.2' }
-
踩坑tips
這裡有個坑,AndroidStudio3.0以上一定要採用0.8.2及以上的版本,否則編譯階段會報錯
接下來是模組中的build.gradle
的配置,首先新增外掛
apply plugin: 'com.google.protobuf'
然後新增配置
android { protobuf { protoc { artifact = 'com.google.protobuf:protoc:3.0.0' } plugins { javalite { artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0' } } generateProtoTasks { all().each { task -> task.builtins { remove java } task.builtins { java { } cpp { } } } } } }
還有一個程式碼目錄的配置
sourceSets { main { java { srcDir 'src/main/java' } proto { srcDir 'src/main/proto' } } }
我們的.proto
檔案就放在這個目錄下就好了
最後新增依賴
compile 'com.google.protobuf:protobuf-java:3.5.1'
-
踩坑tips
這裡也有個很有意思的問題,之前我用的是protobuf-lite版本
compile "com.google.protobuf:protobuf-lite:3.0.0"
然而當我使用的時候發現找不到
proto
例項轉化為位元組流的方法toByteArray()
等方法,google了一下,也有不少人遇到同樣的問題。最後通過這個問題的答案中找到靈感ofollow,noindex">protobuf找不到toByteArray()方法 應該是依賴有問題,然後就到了還是不要用精簡版,最後問題解決。
至此,protobuf的執行環境已經完全搭建好了。網上有一些文章講的是自己編譯protobuf然後進行依賴,這種方式當然也可以,讀者有興趣的可以自行嘗試。
Demo
那麼該如何寫呢,我們先來個最簡單的Pojo類的例子。在上面定義好的proto
目錄下面建立一個.proto
檔案,內容如下
syntax = "proto3"; option java_package = "com.xxx.xxx"; option java_outer_classname = "BaseProto"; message Person { string name = 1; int32 id = 2; string email = 3; string phone = 4; }
看起來還是比較容易理解的,如果上面環境搭建沒有問題的話,同步一下專案之後,我們就會生成這個Person類了,下面以一個最簡單的序列化和反序列化過程來說明一下這個類的使用方法
try { BaseProto.Person.Builder builder = BaseProto.Person.newBuilder(); builder.setEmail("[email protected]"); builder.setName("xx"); builder.setId(1); builder.setPhone("13xxxxxxxxx"); File file = new File(Environment.getExternalStorageDirectory() + File.separator + "proto_persion"); if(!file.exists()) { file.createNewFile(); } //序列化 FileOutputStream outputStream = new FileOutputStream(file); builder.build().writeTo(outputStream); //反序列化 InputStream inputStream = new FileInputStream(file); BaseProto.Person person1 = BaseProto.Person.parseFrom(inputStream); } catch (IOException e) { e.printStackTrace(); }
BaseProto
就是上面.proto
中定義的java_outer_classname
,Person
類通過構建者模式來完成例項化,可以通過writeTo(OutputStream output)
方法來講位元組流寫入到對應的檔案,然後通過parseFrom
即可完成反序列化,總得來說,用起來還是比較方便的。
後記
protobuf從一個google內部使用的工具,發展到今天,肯定還是有其可取的優點的。只不過現在泛用性肯定還是比不上json和xml,不過作為一個專案可優化的點,學習一下還是可以的。