Skip to content
Santekno.com | Tech Tutorials and Trends
EN
📖 0%
19 Sep 2025 · 5 min read ·Article 103 / 110
Go

103. Case Study: An Android Client (Java/Kotlin) Communicating with a gRPC Server in Go

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

title: “103. Case Study: An Android Client (Java/Kotlin) Communicating with a gRPC Server in Go” author: “Andika Pratama” date: 2024-06-10 tags: [android, kotlin, go, grpc, distributed-system, client-server]

gRPC has become the backbone of many modern distributed systems—whether for microservices, mobile backends, or cloud-native applications. This case study highlights how an Android client (written in Java/Kotlin) can communicate efficiently with a gRPC server built in Go (Golang). This article will guide you through everything from the motivation and design to real code that can power high-performance, cross-platform application development.


Why gRPC?

The main reasons to use gRPC include:

  • Efficiency: Protobuf serialization is far more efficient than JSON.
  • Contract-first: The components (Android and the Go server) interact through a clearly defined schema interface.
  • Built-in codegen: Client/server stubs can be generated automatically from a .proto file.
  • Streaming & Bidi: Supports streaming communication, not just unary request-response.
  • Ecosystem: Officially backed by Google and open source.

System Flow Diagram

Let’s take a high-level look at the communication between the Android client (Kotlin) and the Go gRPC server:

MERMAID
sequenceDiagram
    participant AndroidClient as Android Client (Kotlin/Java)
    participant gRPCServer as gRPC Server (Go)

    AndroidClient->>gRPCServer: Protobuf Request
    gRPCServer-->>AndroidClient: Protobuf Response

1. Designing the Service with Protobuf

Before writing any code, we start by defining the service interface in a helloworld.proto file:

proto
 1syntax = "proto3";
 2
 3package helloworld;
 4
 5// The greeting service definition.
 6service Greeter {
 7  // Sends a greeting
 8  rpc SayHello (HelloRequest) returns (HelloReply) {}
 9}
10
11// The request message containing the user's name.
12message HelloRequest {
13  string name = 1;
14}
15
16// The response message containing the greetings
17message HelloReply {
18  string message = 1;
19}

2. Implementing the gRPC Server in Go

Let’s begin with the server side:

a. Setting up the environment

Install the gRPC and Protobuf dependencies:

shell
1go get google.golang.org/grpc
2go get google.golang.org/protobuf/cmd/protoc-gen-go
3go get google.golang.org/grpc/cmd/protoc-gen-go-grpc

Generate the interface files:

shell
1protoc --go_out=. --go-grpc_out=. helloworld.proto

b. The Go code (server/main.go)

go
 1package main
 2
 3import (
 4  "context"
 5  "log"
 6  "net"
 7  "google.golang.org/grpc"
 8  pb "path/to/your/helloworld"
 9)
10
11type server struct {
12  pb.UnimplementedGreeterServer
13}
14
15// Implement the SayHello method
16func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
17  log.Printf("Received: %v", in.GetName())
18  return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
19}
20
21func main() {
22  lis, err := net.Listen("tcp", ":50051")
23  if err != nil {
24    log.Fatalf("failed to listen: %v", err)
25  }
26  s := grpc.NewServer()
27  pb.RegisterGreeterServer(s, &server{})
28  log.Printf("server listening at %v", lis.Addr())
29  if err := s.Serve(lis); err != nil {
30    log.Fatalf("failed to serve: %v", err)
31  }
32}

3. Preparing the Android Client (Kotlin)

gRPC Java supports Android natively. The workflow looks roughly like this:

a. Setting up the environment

Add the dependencies to build.gradle:

gradle
1dependencies {
2    implementation "io.grpc:grpc-okhttp:1.57.2"
3    implementation "io.grpc:grpc-protobuf-lite:1.57.2"
4    implementation "io.grpc:grpc-stub:1.57.2"
5}

Generate the stub from the .proto file:

shell
1protoc \
2  --java_out=app/src/main/java \
3  --grpc-java_out=app/src/main/java \
4  helloworld.proto

Configure your build so that the generated Java code folder is included in the sourceSets.

b. Example Kotlin code in an Activity

kotlin
 1import io.grpc.ManagedChannelBuilder
 2import helloworld.GreeterGrpc
 3import helloworld.HelloRequest
 4
 5fun sayHelloToServer(user: String): String {
 6    val channel = ManagedChannelBuilder.forAddress("YOUR.SERVER.IP.ADDRESS", 50051)
 7        .usePlaintext() // for development testing only, never use in production!
 8        .build()
 9
10    val stub = GreeterGrpc.newBlockingStub(channel)
11    val request = HelloRequest.newBuilder().setName(user).build()
12
13    return try {
14        val response = stub.sayHello(request)
15        response.message
16    } catch (e: Exception) {
17        "RPC failed: ${e.localizedMessage}"
18    } finally {
19        channel.shutdown()
20    }
21}

For example, in MainActivity:

kotlin
1lifecycleScope.launch(Dispatchers.IO) {
2    val greeting = sayHelloToServer("Andika")
3    withContext(Dispatchers.Main) {
4        Toast.makeText(this@MainActivity, greeting, Toast.LENGTH_SHORT).show()
5    }
6}

4. Simulating the Request-Response

Let’s see what happens when an Android user greets the Go server with the name “Andika”:

StepClient (Android)Server (Go)Response
1send HelloRequestreceive & log nameprocess request, generate HelloReply
2send HelloReplydisplay “Hello Andika”

The output on Android will appear as a Toast:
Hello Andika


5. Common Problems & Tips

Common Issues

ProblemHow to Fix
SSL/TLS handshakeFor dev, use .usePlaintext(); for prod, use an SSL channel
Firewall/serverMake sure port 50051 is open in the firewall & security group
Protobuf versionEnsure the Protobuf version is consistent across server and client
SerializationThe client and server must use an identical proto schema
Android ProguardDon’t forget keep rules for the auto-generated gRPC classes

6. Performance Analysis

Serialization Speed

FormatRequest SizeLatency (ms)
REST (JSON)250 bytes300
gRPC+Protobuf110 bytes80

This saves bandwidth and speeds up response times.


7. Conclusion

With this practical case study, you can build efficient gRPC communication from Android to a Go server. gRPC paves the way for seamless cross-platform integration, offering the speed, scalability, and maintainability that are so important in the era of modern mobile applications and microservices architectures.

If you’re interested in going further, explore advanced topics such as gRPC streaming, interceptors, authentication, and load balancing. Happy experimenting, and best of luck building robust mobile backends with Kotlin and Go!


References:

Related Articles

💬 Comments