教你使用ProtoBuf,通過gRPC服務在Android上進行網絡請求

教你如何使用ProtoBuf,通過gRPC服務在android上進行網絡請求。

項目地址:

https://github.com/xuexiangjys/Protobuf-gRPC-Android

簡介

ProtoBuf

google公司發佈的一套開源編碼規則,基於二進制流的序列化傳輸,可以轉換成多種編程語言,幾乎涵蓋了市面上所有的主流編程語言,是目前公認的非常高效的序列化技術。

ProtoBuf的Github主頁:

https://github.com/protocolbuffers/protobuf

gRPC

gRPC是一個高性能、開源和通用的RPC框架,面向移動和HTTP/2設計。目前提供C、Java和Go語言版本,分別是grpc、grpc-java、grpc-go。gRPC基於HTTP/2標準設計,帶來諸如雙向流、流控、頭部壓縮、單TCP連接上的多複用請求等特性。這些特性使得其在移動設備上表現更好,更省電和節省空間佔用。gRPC由google開發,是一款語言中立、平臺中立、開源的遠程過程調用系統。

gRPC(Java)的Github主頁:

https://github.com/grpc/grpc-java

爲什麼要使用ProtoBuf和gRPC

簡而言之,ProtoBuf就好比信息傳輸的媒介,類似我們常用的json,而grpc則是傳輸他們的通道,類似我們常用的socket。

ProtoBuf和json

如果用一句話來概括ProtoBuf和JSON的區別的話,那就是:對於較多信息存儲的大文件而言,ProtoBuf的寫入和解析效率明顯高很多,而JSON格式的可讀性明顯要好。網上有一段數據用以對此ProtoBuf和JSON之間的性能差異:

JSON

  
  
  
  1. 總共寫65535Data記錄到文件中,測試結果如下:

  2. 生成的文件尺寸是23,733k

  3. 生成文件的時間是12.80秒。

  4. 從該文件中解析的時間是11.50秒。

ProtoBuf

  
  
  
  1. 總共寫65535Data記錄到文件中,測試結果如下:

  2. 生成的文件尺寸是3760k

  3. 生成文件的時間是0.08秒。

  4. 從該文件中解析的時間是0.07秒。

gRPC

作爲google公司極力推薦的分佈式網絡架構,基於HTTP2.0標準設計,使用用ProtoBuf作爲序列化工具,在移動設備上表現更好,更省電和節省空間佔用。google出品,品質值得信賴。

如何使用

像這種國外的開源框架,還是建議大家先直接閱讀官方文檔,再看國內的文章,這樣纔不容易被誤導。

官方教程:

https://grpc.io/docs/quickstart/android.html

官方示例:

https://github.com/grpc/grpc-java/tree/master/examples/android

環境配置

1.首先需要下載安裝Protobuf Support插件,如下圖:

2.在項目的根目錄的 build.gradle 的 buildscript中加入 protobuf-gradle-plugin插件:

  
  
  
  1. buildscript {

  2. ...

  3. dependencies {

  4. ...

  5. classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.6"

  6. }

  7. }

3.然後在應用Module的 build.gradle 中進行如下配置

  
  
  
  1. apply plugin: 'com.android.application'

  2. apply plugin: 'com.google.protobuf' //引用protobuf-gradle-plugin插件


  3. android {

  4. ...


  5. lintOptions {

  6. abortOnError false

  7. disable 'GoogleAppIndexingWarning', 'HardcodedText', 'InvalidPackage'

  8. textReport true

  9. textOutput "stdout"

  10. }

  11. }


  12. protobuf {

  13. protoc { artifact = 'com.google.protobuf:protoc:3.6.1' }

  14. plugins {

  15. javalite { artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0" }

  16. grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.19.0' // CURRENT_GRPC_VERSION

  17. }

  18. }

  19. generateProtoTasks {

  20. all().each { task ->

  21. task.plugins {

  22. javalite {}

  23. grpc { // Options added to --grpc_out

  24. option 'lite' }

  25. }

  26. }

  27. }

  28. }


  29. dependencies {

  30. //protobuf

  31. implementation 'io.grpc:grpc-okhttp:1.19.0'

  32. implementation 'io.grpc:grpc-protobuf-lite:1.19.0'

  33. implementation 'io.grpc:grpc-stub:1.19.0'

  34. implementation 'javax.annotation:javax.annotation-api:1.2'

  35. }

4.最後將你 .proto協議文件放至 src/main/proto/文件夾下,點擊build進行編譯,如果出現如下圖,則證明環境配置成功!

普通請求

在測試demo中的請求前,請務必先運行服務端的代碼。

1.構建Channel

  
  
  
  1. /**

  2. * 構建一條普通的Channel

  3. *

  4. * @param host 主機服務地址

  5. * @param port 端口

  6. * @return

  7. */

  8. public static ManagedChannel newChannel(String host, int port) {

  9. return ManagedChannelBuilder.forAddress(host, port)

  10. .usePlaintext()

  11. .build();

  12. }

2.構建服務請求API代理

  
  
  
  1. //構建通道

  2. final ManagedChannel channel = gRPCChannelUtils.newChannel(host, port);

  3. //構建服務api代理

  4. mStub = GreeterGrpc.newStub(channel);

3.構建請求實體

  
  
  
  1. //HelloRequest是自動生成的實體類

  2. HelloRequest request = HelloRequest.newBuilder().setName(message).build();

4.執行請求

  
  
  
  1. //進行請求

  2. mStub.sayHello(request, new SimpleStreamObserver<HelloReply>() {

  3. @Override

  4. protected void onSuccess(HelloReply value) {

  5. tvGrpcResponse.setText(value.getMessage());

  6. btnSend.setEnabled(true);

  7. }

  8. @MainThread

  9. @Override

  10. public void onError(Throwable t) {

  11. super.onError(t);

  12. tvGrpcResponse.setText(Log.getStackTraceString(t));

  13. btnSend.setEnabled(true);

  14. }

  15. @Override

  16. public void onCompleted() {

  17. super.onCompleted();

  18. gRPCChannelUtils.shutdown(channel); //關閉通道

  19. }

  20. });

Https請求

與普通請求相比,就在第一步建立通道有所不同,需要設置CA證書,其他步驟都相同。

  
  
  
  1. /**

  2. * 構建一條SSLChannel

  3. *

  4. * @param host 主機服務地址

  5. * @param port 端口

  6. * @param authority 域名

  7. * @param certificates 證書

  8. * @return

  9. */

  10. public static ManagedChannel newSSLChannel(String host, int port, String authority, InputStream... certificates) {

  11. HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory(certificates);

  12. return OkHttpChannelBuilder.forAddress(host, port)

  13. //overrideAuthority非常重要,必須設置調用

  14. .overrideAuthority(authority)

  15. .sslSocketFactory(sslParams.sSLSocketFactory)

  16. .build();

  17. }

聯繫方式

微信公衆號


本文分享自微信公衆號 - 我的Android開源之旅(openandroidxx)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章