教你如何使用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
總共寫65535條Data記錄到文件中,測試結果如下:
生成的文件尺寸是23,733k。
生成文件的時間是12.80秒。
從該文件中解析的時間是11.50秒。
ProtoBuf
總共寫65535條Data記錄到文件中,測試結果如下:
生成的文件尺寸是3760k。
生成文件的時間是0.08秒。
從該文件中解析的時間是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
插件:
buildscript {
...
dependencies {
...
classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.6"
}
}
3.然後在應用Module的 build.gradle 中進行如下配置
apply plugin: 'com.android.application'
apply plugin: 'com.google.protobuf' //引用protobuf-gradle-plugin插件
android {
...
lintOptions {
abortOnError false
disable 'GoogleAppIndexingWarning', 'HardcodedText', 'InvalidPackage'
textReport true
textOutput "stdout"
}
}
protobuf {
protoc { artifact = 'com.google.protobuf:protoc:3.6.1' }
plugins {
javalite { artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0" }
grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.19.0' // CURRENT_GRPC_VERSION
}
}
generateProtoTasks {
all().each { task ->
task.plugins {
javalite {}
grpc { // Options added to --grpc_out
option 'lite' }
}
}
}
}
dependencies {
//protobuf
implementation 'io.grpc:grpc-okhttp:1.19.0'
implementation 'io.grpc:grpc-protobuf-lite:1.19.0'
implementation 'io.grpc:grpc-stub:1.19.0'
implementation 'javax.annotation:javax.annotation-api:1.2'
}
4.最後將你 .proto
協議文件放至 src/main/proto/
文件夾下,點擊build進行編譯,如果出現如下圖,則證明環境配置成功!
普通請求
在測試demo中的請求前,請務必先運行服務端的代碼。
1.構建Channel
/**
* 構建一條普通的Channel
*
* @param host 主機服務地址
* @param port 端口
* @return
*/
public static ManagedChannel newChannel(String host, int port) {
return ManagedChannelBuilder.forAddress(host, port)
.usePlaintext()
.build();
}
2.構建服務請求API代理
//構建通道
final ManagedChannel channel = gRPCChannelUtils.newChannel(host, port);
//構建服務api代理
mStub = GreeterGrpc.newStub(channel);
3.構建請求實體
//HelloRequest是自動生成的實體類
HelloRequest request = HelloRequest.newBuilder().setName(message).build();
4.執行請求
//進行請求
mStub.sayHello(request, new SimpleStreamObserver<HelloReply>() {
@Override
protected void onSuccess(HelloReply value) {
tvGrpcResponse.setText(value.getMessage());
btnSend.setEnabled(true);
}
@MainThread
@Override
public void onError(Throwable t) {
super.onError(t);
tvGrpcResponse.setText(Log.getStackTraceString(t));
btnSend.setEnabled(true);
}
@Override
public void onCompleted() {
super.onCompleted();
gRPCChannelUtils.shutdown(channel); //關閉通道
}
});
Https請求
與普通請求相比,就在第一步建立通道有所不同,需要設置CA證書,其他步驟都相同。
/**
* 構建一條SSLChannel
*
* @param host 主機服務地址
* @param port 端口
* @param authority 域名
* @param certificates 證書
* @return
*/
public static ManagedChannel newSSLChannel(String host, int port, String authority, InputStream... certificates) {
HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory(certificates);
return OkHttpChannelBuilder.forAddress(host, port)
//overrideAuthority非常重要,必須設置調用
.overrideAuthority(authority)
.sslSocketFactory(sslParams.sSLSocketFactory)
.build();
}
聯繫方式
微信公衆號
本文分享自微信公衆號 - 我的Android開源之旅(openandroidxx)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。