grpc android客户端,记一次技术调研(二): Android 应用实现 gRPC 调用

问题

在手机应用的开发中,通常会将复杂的业务逻辑层实现放在服务端,客户端仅负责表现层。但是对于某些手机应用而言,业务逻辑的实现位于服务端反而是不安全的或是不合理的,而是需要将其逻辑直接在手机端实现。

目的

面对不同系统的手机客户端,单独重复实现相同的业务逻辑,并非最佳实践。如何通过第三方语言 Go 语言将业务逻辑封装成库的形式,并以静态打包的方式提供给不同系统的手机客户端使用,是本次调研的目的。

理想目标图:

grpc android客户端,记一次技术调研(二): Android 应用实现 gRPC 调用_第1张图片

具体调研内容包括:

GoMobile SDK 在 iOS & Android 上的集成

GoMobile SDK 在 iOS & Android 上的边界

C/S 架构 or 静态库

其中关于 gRPC 在 iOS 与 Android 的实现,本身官方就已经提供了样例。本次调研会用到相关内容,所以将其作为调研的一部分记录下来,方便后来者阅读。调研中所有涉及的项目代码均存放于: liujianping/grpc-apps 仓库中, 需要的朋友可以直接下载测试。

1. 环境安装

保证整个过程在"全球通"的环境下操作。

1.1 JDK 安装

没什么好说的,下载安装。设置好相应的环境变量。完成后,通过 java -version 命令确认安装成功。

1.2 Android Studio 安装

官网下载安装包,按步骤安装即可。

2. 开启服务端

请参考 iOS 应用实现 gRPC 调用 服务端部分, 确认服务端服务启动。

3. 创建 Android 项目

虽然项目 grpc-java 提供完整的样例程序。但是缺少过程的结果,往往还是令初学者望而生畏。所以,从头开始一步一步的记录样例的实现过程,是有必要的。

3.1 创建 Basic Activity 项目

创建 Basic Activity 初始项目,过程只是简单的鼠标操作,同时输入相应的项目名。这个过程就不多说了。完成创建后,打开 app/src/main/java/com/gitdig/androidDemo/MainActivity.java 文件, 添加一句日志输出:

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

Toolbar toolbar = findViewById(R.id.toolbar);

setSupportActionBar(toolbar);

FloatingActionButton fab = findViewById(R.id.fab);

fab.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)

.setAction("Action", null).show();

// Demo 日志输出

Log.i("demo", "Hello Android");

}

});

}

复制代码

构建程序,并在模拟器中执行。在模拟器的选择中,可以选择版本比较低的模拟器,会比较小,下载速度更快一点。启动程序后,点击按钮,查看日志输出: I/demo: Hello Android . 初始程序构建完成。

3.2 新增 proto 文件,并生成 java 代码

在 Android 项目中,通过 proto 文件生成 java 代码的过程和 iOS 与 Go 的过程不一样,没有直接用到 protoc 命令行工具。而是通过 protobuf-gradle-plugin 插件的方式,在 Gradle 构建过程中自动生成。

grpc android客户端,记一次技术调研(二): Android 应用实现 gRPC 调用_第2张图片

首先配置插件以及 Gradle 构建过程, 将项目左栏视图切换成 Android ,在 Gradle 脚本栏中,首先修改 Project: androidDemo 项目级 build.gradle 文件。增加 protobuf-gradle-plugin 插件支持。

buildscript {

repositories {

google()

jcenter()

}

dependencies {

classpath 'com.android.tools.build:gradle:3.4.1'

// NOTE: Do not place your application dependencies here; they belong

// in the individual module build.gradle files

classpath

// 增加 protobuf-gradle-plugin 插件

"com.google.protobuf:protobuf-gradle-plugin:0.8.8"

}

}

...

复制代码

在打开 Module: app 模块级 build.gradle ,增加相应的构建脚本:

apply plugin: 'com.android.application'

//应用插件

apply plugin: 'com.google.protobuf'

android {

compileSdkVersion 29

buildToolsVersion "29.0.0"

defaultConfig {

applicationId "com.gitdig.androiddemo"

minSdkVersion 14

targetSdkVersion 29

versionCode 1

versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

}

buildTypes {

release {

minifyEnabled false

proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'

}

}

}

//插件构建脚本

protobuf {

protoc {

artifact = 'com.google.protobuf:protoc:3.0.0'

}

plugins {

grpc {

artifact = 'io.grpc:protoc-gen-grpc-java:1.0.0-pre2'

}

javalite {

artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'

}

}

generateProtoTasks {

all()*.plugins {

javalite {}

}

ofNonTest()*.plugins {

grpc {

// Options added to --grpc_out

option 'lite'

}

}

}

}

dependencies {

implementation fileTree(dir: 'libs', include: ['*.jar'])

implementation 'androidx.appcompat:appcompat:1.0.2'

implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

implementation 'com.google.android.material:material:1.0.0'

testImplementation 'junit:junit:4.12'

androidTestImplementation 'androidx.test:runner:1.2.0'

androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

// 增加插件依赖

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

implementation 'io.grpc:grpc-protobuf-lite:1.21.0'

implementation 'io.grpc:grpc-okhttp:1.21.0'

implementation 'io.grpc:grpc-stub:1.21.0'

}

复制代码

以上 Gradle 脚本的配置就能实现构建过程中,通过 proto 文件自动生成 java 代码了。 不过需要注意的就是,proto 文件的位置是固定的。再次将左侧视图切换到 Project 视图。proto 文件的位置: app/src/main/proto 文件夹。

grpc android客户端,记一次技术调研(二): Android 应用实现 gRPC 调用_第3张图片

proto 文件夹与 proto 文件均通过手动创建。完成了以上过程,现在就可以构建一次项目,看看 java 文件是否生成。再切换会 Android 视图,就会发现生成的代码已经有了。

grpc android客户端,记一次技术调研(二): Android 应用实现 gRPC 调用_第4张图片

3.3 实现 gRPC 客户端调用

实现 gRPC 客户端的调用,代码很简单。首先是提供一个创建 gRPC 通信的客户端连接。直接再 MainActivity 类中增加一个功能函数:

public class MainActivity extends AppCompatActivity {

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

return ManagedChannelBuilder.forAddress(host, port)

.usePlaintext()

.build();

}

...

}

复制代码

再在按钮点击事件中,发起客户端 gRPC 请求:

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

Toolbar toolbar = findViewById(R.id.toolbar);

setSupportActionBar(toolbar);

final GreeterGrpc.GreeterStub greeterStub = GreeterGrpc.newStub(newChannel("192.168.0.134", 50051));

FloatingActionButton fab = findViewById(R.id.fab);

fab.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)

.setAction("Action", null).show();

Log.i("demo", "Hello Android");

//增加 gRPC 请求,打印日志

HelloRequest request = HelloRequest.newBuilder().setName("JayL").build();

greeterStub.sayHello(request, new StreamObserver() {

@Override

public void onNext(HelloReply value) {

Log.i("demo", value.getMessage());

}

@Override

public void onError(Throwable t) {

Log.e("demo", t.getMessage());

}

@Override

public void onCompleted() {

}

});

}

});

}

复制代码

因为涉及网络通信,打开模块app的配置文件: app/src/main/AndroidManifest.xml , 增加一行配置:

package="com.gitdig.androiddemo">

...

复制代码

构建程序,并在模拟器上执行,确认 gRPC 通信正常。完成该部分调研。

你可能感兴趣的:(grpc,android客户端)