教你如何使用ProtoBuf,經過gRPC服務在android上進行網絡請求。html
若是你對此感興趣,那麼請點擊項目地址,一睹爲快把!java
google公司發佈的一套開源編碼規則,基於二進制流的序列化傳輸,能夠轉換成多種編程語言,幾乎涵蓋了市面上全部的主流編程語言,是目前公認的很是高效的序列化技術。android
ProtoBuf的Github主頁:github.com/protocolbuf…git
gRPC是一個高性能、開源和通用的RPC框架,面向移動和HTTP/2設計。目前提供C、Java和Go語言版本,分別是grpc、grpc-java、grpc-go。gRPC基於HTTP/2標準設計,帶來諸如雙向流、流控、頭部壓縮、單TCP鏈接上的多複用請求等特性。這些特性使得其在移動設備上表現更好,更省電和節省空間佔用。gRPC由google開發,是一款語言中立、平臺中立、開源的遠程過程調用系統。github
gRPC(Java)的Github主頁:github.com/grpc/grpc-j…編程
簡而言之,ProtoBuf就比如信息傳輸的媒介,相似咱們經常使用的json,而grpc則是傳輸他們的通道,相似咱們經常使用的socket。json
若是用一句話來歸納ProtoBuf和JSON的區別的話,那就是:對於較多信息存儲的大文件而言,ProtoBuf的寫入和解析效率明顯高不少,而JSON格式的可讀性明顯要好。網上有一段數據用以對此ProtoBuf和JSON之間的性能差別:api
總共寫65535條Data記錄到文件中,測試結果以下:
生成的文件尺寸是23,733k。
生成文件的時間是12.80秒。
從該文件中解析的時間是11.50秒。
複製代碼
總共寫65535條Data記錄到文件中,測試結果以下:
生成的文件尺寸是3760k。
生成文件的時間是0.08秒。
從該文件中解析的時間是0.07秒。
複製代碼
做爲google公司極力推薦的分佈式網絡架構,基於HTTP2.0標準設計,使用用ProtoBuf做爲序列化工具,在移動設備上表現更好,更省電和節省空間佔用。google出品,品質值得信賴。bash
像這種國外的開源框架,仍是建議你們先直接閱讀官方文檔,再看國內的文章,這樣纔不容易被誤導。微信
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); //關閉通道
}
});
複製代碼
與普通請求相比,就在第一步創建通道有所不一樣,須要設置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();
}
複製代碼