欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

Android上使用grpc的方法教程

前言

創(chuàng)新互聯(lián)主要從事成都網(wǎng)站建設(shè)、成都做網(wǎng)站、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)巨鹿,十余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來(lái)電咨詢建站服務(wù):18982081108

最近的一個(gè)項(xiàng)目使用到了grpc實(shí)現(xiàn)跨平臺(tái)的遠(yuǎn)程調(diào)用,在安卓端使用的時(shí)候遇到了一些坑,這里記錄一下。

首先根據(jù)grpc android的官方Demo配置grpc依賴,測(cè)試它的hello world工程。

編譯谷歌官方的helloworld工程

添加rotobuf-gradle-plugin插件

首先添加rotobuf-gradle-plugin插件,他是用來(lái)從proto文件自動(dòng)生成java代碼的:

//Project的build.gradle中添加rotobuf-gradle-plugin插件
buildscript {
 ...
 dependencies {
 ...
 classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.0"
 ...
 }
 ...
}
//App的build.gradle中添加下面配置
apply plugin: 'com.google.protobuf'

protobuf {
 protoc {
 artifact = 'com.google.protobuf:protoc:3.0.0'
 }
 plugins {
 javalite {
  artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0"
 }
 grpc {
  artifact = 'io.grpc:protoc-gen-grpc-java:1.0.0' // CURRENT_GRPC_VERSION
 }
 }
 generateProtoTasks {
 all().each { task ->
  task.plugins {
  javalite {}
  grpc {
   // Options added to --grpc_out
   option 'lite'
  }
  }
 }
 }
}

添加proto文件并自動(dòng)生成java代碼

在src/main/目錄下創(chuàng)建一個(gè)proto目錄,并將官方的helloworld.proto放到proto目錄下

之后只需要rebuild一下就能看到build/generated/source/proto/目錄下根據(jù)helloworld.proto生成了幾個(gè)Java類

Android上使用grpc的方法教程

添加安卓端grpc的依賴

//App的build.gradle中添加下面配置
 dependencies {
 ...
 compile 'io.grpc:grpc-okhttp:1.1.2'
 compile 'io.grpc:grpc-protobuf-lite:1.1.2'
 compile 'io.grpc:grpc-stub:1.1.2'
 compile 'javax.annotation:javax.annotation-api:1.2'
 ...
}
configurations.all {
 resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.1'
 }

我這個(gè)時(shí)候報(bào)了這個(gè)錯(cuò)誤

Warning:Conflict with dependency ‘com.google.code.findbugs:jsr305'. Resolved versions for app (3.0.0) and test app (2.0.1) differ. See http://g.co/androidstudio/app-test-app-conflict for details.

這是因?yàn)?code>com.google.code.findbugs:jsr305的版本不一致導(dǎo)致的

可以在App的build.gradle的android標(biāo)簽中配置一下解決

android {
 ...
 configurations.all {
 resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.1'
 }
 ...
}

編寫(xiě)demo代碼

public class MainActivity extends AppCompatActivity {
 private static final String TAG = "GrpcDemo";

 private static final int PROT = 55055;
 private static final String NAME = "linjw";
 private static final String HOST = "localhost";

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);

 startServer(PROT);
 startClient(HOST, PROT, NAME);
 }

 private void startServer(int port){
 try {
  Server server = ServerBuilder.forPort(port)
   .addService(new GreeterImpl())
   .build()
   .start();
 } catch (IOException e) {
  e.printStackTrace();
  Log.d(TAG, e.getMessage());
 }
 }

 private void startClient(String host, int port, String name){
 new GrpcTask(host, port, name).execute();
 }

 private class GreeterImpl extends GreeterGrpc.GreeterImplBase {
 public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) {
  responseObserver.onNext(sayHello(request));
  responseObserver.onCompleted();
 }

 private HelloReply sayHello(HelloRequest request) {
  return HelloReply.newBuilder()
   .setMessage("hello "+ request.getName())
   .build();
 }
 }

 private class GrpcTask extends AsyncTask<Void, Void, String> {
 private String mHost;
 private String mName;
 private int mPort;
 private ManagedChannel mChannel;

 public GrpcTask(String host, int port, String name) {
  this.mHost = host;
  this.mName = name;
  this.mPort = port;
 }

 @Override
 protected void onPreExecute() {
 }

 @Override
 protected String doInBackground(Void... nothing) {
  try {
  mChannel = ManagedChannelBuilder.forAddress(mHost, mPort)
   .usePlaintext(true)
   .build();
  GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(mChannel);
  HelloRequest message = HelloRequest.newBuilder().setName(mName).build();
  HelloReply reply = stub.sayHello(message);
  return reply.getMessage();
  } catch (Exception e) {
  StringWriter sw = new StringWriter();
  PrintWriter pw = new PrintWriter(sw);
  e.printStackTrace(pw);
  pw.flush();
  return "Failed... : " + System.lineSeparator() + sw;
  }
 }

 @Override
 protected void onPostExecute(String result) {
  try {
  mChannel.shutdown().awaitTermination(1, TimeUnit.SECONDS);
  } catch (InterruptedException e) {
  Thread.currentThread().interrupt();
  }
  Log.d(TAG, result);
 }
 }
}

這段代碼運(yùn)行會(huì)崩潰:

Caused by: io.grpc.ManagedChannelProvider$ProviderNotFoundException: No functional server found. Try adding a dependency on the grpc-netty artifact

猜測(cè)google使用netty替代了okhttp,嘗試換成grpc-netty的依賴:

dependencies {
 ...
 compile 'io.grpc:grpc-netty:1.1.2'
 compile 'io.grpc:grpc-protobuf-lite:1.1.2'
 compile 'io.grpc:grpc-stub:1.1.2'
 compile 'javax.annotation:javax.annotation-api:1.2'
 ...
}

這么編譯會(huì)報(bào)錯(cuò)

com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK META-INF/INDEX.LIST

需要加上下面的配置解決

android {
 ...
 packagingOptions {
 pickFirst 'META-INF/INDEX.LIST'
 pickFirst 'META-INF/LICENSE'
 pickFirst 'META-INF/io.netty.versions.properties'
 }
 ...
}

當(dāng)然,還需要加上INTERNET權(quán)限,要不然運(yùn)行的時(shí)候還是會(huì)崩潰。

最終就能看的下面的打印,這樣安卓grpc的helloworld就成功了。

03-03 00:04:20.000 6137-6137/linjw.com.grpcdemo D/GrpcDemo: hello linjw

使用com.google.protobuf.Any

Any可以攜帶任意類型的數(shù)據(jù),用法相當(dāng)于c語(yǔ)言的void指針。在項(xiàng)目中是很常用的,但是谷歌在javalite的版本不支持Any。

如果在proto文件中使用了Any的話生成java代碼就會(huì)有報(bào)錯(cuò),例如將helloworld的proto文件改成下面的樣子:

// Copyright 2015, Google Inc.
// All rights reserved.
//
// redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

syntax = "proto3";

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";

package helloworld;

import "google/protobuf/any.proto";

// The greeting service definition.
service Greeter {
 // Sends a greeting
 rpc SayHello (google.protobuf.Any) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
 string name = 1;
}

// The response message containing the greetings
message HelloReply {
 string message = 1;
}

報(bào)錯(cuò)如下

google/protobuf/any.proto: File not found.
helloworld.proto: Import “google/protobuf/any.proto” was not found or had errors.
helloworld.proto:44:17: “google.protobuf.Any” is not defined.

使用grpc-jave代替grpc-javalite

但是現(xiàn)在做的這個(gè)項(xiàng)目的linux端實(shí)現(xiàn)已經(jīng)用了Any,要改的話需要耗費(fèi)比較大的精力。幸好嘗試了下,發(fā)現(xiàn)安卓上也能跑支持Any的grpc-java。

首先我們要使用grpc-protobuf依賴替換grpc-protobuf-lite依賴

dependencies {
 ...
 compile 'io.grpc:grpc-netty:1.1.2'
 compile 'io.grpc:grpc-protobuf:1.1.2'
 compile 'io.grpc:grpc-stub:1.1.2'
 compile 'javax.annotation:javax.annotation-api:1.2'
 ...
}

接著修改protobuf-gradle-plugin配置使得自動(dòng)生成java的代碼而不是javalite的代碼

protobuf {
 protoc {
  artifact = 'com.google.protobuf:protoc:3.0.0'
 }
 plugins {
  grpc {
   artifact = 'io.grpc:protoc-gen-grpc-java:1.0.0' // CURRENT_GRPC_VERSION
  }
 }
 generateProtoTasks {
  all().each { task ->
   task.builtins {
    java {}
   }
   task.plugins {
    grpc {}
   }
  }
 }
}

對(duì)應(yīng)的修改helloworld的代碼就能運(yùn)行了

public class MainActivity extends AppCompatActivity {
 private static final String TAG = "GrpcDemo";

 private static final int PROT = 55055;
 private static final String NAME = "linjw";
 private static final String HOST = "localhost";

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  startServer(PROT);
  startClient(HOST, PROT, NAME);
 }

 private void startServer(int port){
  try {
   Server server = ServerBuilder.forPort(port)
     .addService(new GreeterImpl())
     .build()
     .start();
  } catch (IOException e) {
   e.printStackTrace();
   Log.d(TAG, e.getMessage());
  }
 }

 private void startClient(String host, int port, String name){
  new GrpcTask(host, port, name).execute();
 }

 private class GreeterImpl extends GreeterGrpc.GreeterImplBase {
  public void sayHello(Any request, StreamObserver<HelloReply> responseObserver) {
   try {
    responseObserver.onNext(sayHello(request.unpack(HelloRequest.class)));
    responseObserver.onCompleted();
   } catch (InvalidProtocolBufferException e) {
    e.printStackTrace();
   }
  }

  private HelloReply sayHello(HelloRequest request) {
   return HelloReply.newBuilder()
     .setMessage("hello "+ request.getName())
     .build();
  }
 }

 private class GrpcTask extends AsyncTask<Void, Void, String> {
  private String mHost;
  private String mName;
  private int mPort;
  private ManagedChannel mChannel;

  public GrpcTask(String host, int port, String name) {
   this.mHost = host;
   this.mName = name;
   this.mPort = port;
  }

  @Override
  protected void onPreExecute() {
  }

  @Override
  protected String doInBackground(Void... nothing) {
   try {
    mChannel = ManagedChannelBuilder.forAddress(mHost, mPort)
      .usePlaintext(true)
      .build();
    GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(mChannel);
    HelloRequest message = HelloRequest.newBuilder().setName(mName).build();
    HelloReply reply = stub.sayHello(Any.pack(message));
    return reply.getMessage();
   } catch (Exception e) {
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);
    e.printStackTrace(pw);
    pw.flush();
    return "Failed... : " + System.lineSeparator() + sw;
   }
  }

  @Override
  protected void onPostExecute(String result) {
   try {
    mChannel.shutdown().awaitTermination(1, TimeUnit.SECONDS);
   } catch (InterruptedException e) {
    Thread.currentThread().interrupt();
   }
   Log.d(TAG, result);
  }
 }
}

完整的demo代碼可以點(diǎn)這里在我的github中查看(也可以通過(guò)本地下載)

Android方法數(shù)不能超過(guò)65535的問(wèn)題

最后使用grpc,方法數(shù)會(huì)超過(guò)65535,可以使用com.android.support:multidex去解決

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如有疑問(wèn)大家可以留言交流,謝謝大家對(duì)創(chuàng)新互聯(lián)的支持。

文章題目:Android上使用grpc的方法教程
文章轉(zhuǎn)載:http://aaarwkj.com/article28/ihhdjp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計(jì)、用戶體驗(yàn)網(wǎng)站設(shè)計(jì)公司、網(wǎng)站設(shè)計(jì)網(wǎng)站收錄

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化
国产一区二区三区日本精品| 日本久久精品视频一区| 人妻有码中文字幕在线| 日韩 高清 一区二区| 香蕉久草官网视频观看| 国产av一区二区三区中文| 国产精品国产三级国av中文 | 人妻在线中文字幕一区| 国产精品一区久久91| 亚洲日本不卡在线一区二区| 免费看av网站一区二区| 在线观看国产小视频不卡| 欧美日韩美足一区二区| 午夜看片国产操黑丝91网| 日韩精品视频在线不卡| 美女张开腿让男人插进去| 一级黄片电影中文字幕| 日韩精品毛片在线看| 日韩无砖区2021不卡| 天堂av日韩在线播放| 成人黄色av在线看| 亚州中文字幕久久一区| 免费的一区二区中文字幕| 国产精品久久99粉嫩| 午夜伦理视频免费观看| 久久久久久精品国产免费| av一区二区三区三| 最新中文字幕成人在线观看| 偷窥偷拍原味一区二区三区| 精品人妻一区二区三区四| 国产精品综合日韩精| 日韩av在线国产观看| 国产欧美日韩经典一区| 精品啪在线观看国产熟女| 国产精品欧美日韩高清| 日韩激情一区二区三区| 日韩精品一区二区三区都在看| 日韩精品一区二区91| 日韩精品中文女同在线播放| 国产黄色大片在线关看| 在线成人影院中文字幕|