gRPC client side implementation for Android
gRPC is a modern RPC framework developed by Google to call remote methods as easy as if they are local methods. There are a lots of article about gRPC comparison over REST or JSON. So I am not going to talk about it. I will show you how to configure basic gRPC stuf to communicate with Backend Server. For server side implementation read this article.
How it works?
Let me explain how the entire code system works within android studio
To support protobuf, firstly you will need a proto file which will describe the structure or base format of data to be shared. Backend (e.g the webservice) must use the same proto file. Using the PROTO tool you can generate the languages spesific file (e.g the java class file) and copy it to your project. But there a better way to hand over this task to android sutdio which we will use here.
Once it is generated, you can use it as data model in your code.
Add Dependencies
Firstly add protobuf classpath and maven plugin repository in you project level build.gradle
file
buildscript { // other code dependencies { classpath 'com.android.tools.build:gradle:3.1.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.5' } } allprojects { repositories { google() jcenter() mavenLocal() maven { url "https://plugins.gradle.org/m2/" } } }
After that add gRPC related dependincies in your app level build.gradle
file
implementation 'javax.annotation:javax.annotation-api:1.2' implementation 'io.grpc:grpc-protobuf-lite:1.12.0' implementation 'io.grpc:grpc-okhttp:1.12.0' implementation 'io.grpc:grpc-stub:1.12.0'
Good news is there is a plguin to generate java classes in Gradel base system which is added above in project classpath. But it need to integraet with android studio build system to generate java class file at the time of build. To do that add those code to your app level build.gradle
file
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' } } } }
Add Proto File
You need to keep all proto file in src/main/proto/
directory because the plugin will use this directory to generate java class. Now create LoginService.proto
in this directory.
syntax = "proto3"; option java_multiple_files = true; option java_generic_services = true; package com.example.learn; message LoginRequest { string username = 1; string password = 2; } message LoginResponse { int32 responseCode = 1; string message = 2; } service LoginService { rpc logIn (LoginRequest) returns (LoginResponse); }
This will be the exact same file used by server. Now build the project and the plugin will generate necessary java class.
Communicate with Serve
To communcate with server first you have to open a connection by which you will send request
val connectionChannel: ManagedChannel by lazy { OkHttpChannelBuilder.forAddress("192.168.0.102", 8080) .usePlaintext() .build() }
To send request for login create an object of Login server by using protoc generated class LoginServiceGrpc
and request message
val loginService = LoginServiceGrpc.newBlockingStub(connectionChannel) val requestMessage = LoginRequest.newBuilder() .setUsername("Shuza") .setPassword("123") .build()
Now you can send request for login using the loginService
object as like any other method of your project. But android doesn't support network call in main thread so you have to call it in a different thread. Here I use RxJava
for threading as gRPC use Observable
pattern
Single.fromCallable { loginService.logIn(requestMessage) } .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(object : SingleObserver<LoginResponse> { override fun onSuccess(response: LoginResponse) { // here is your response } override fun onSubscribe(d: Disposable) {} override fun onError(e: Throwable) { // here is your exception } })
Run
Your project is ready to send request and get response from server. Just run it as an android project.
You will find the sources over on GitHub.
Originally published at shuza.ninja on July 20, 2018.