![](/img/trans.png)
[英]How to generate gRPC code with protobuf on Kotlin for Android client?
[英]How can I generate protobuf in Kotlin for Android applications?
任何人都可以幫助我了解如何在 Kotlin 中生成 protobuf? 我聽說過gRPC
、 wire
、 KotlinPoet
,但我不明白有什么區別,我應該使用哪個示例,任何簡單的文檔請免費填寫與我分享? 任何人都可以提供一個示例鏈接,該鏈接顯示如何將 Protobuf 示例生成到 Kotlin?
我使用square/wire
和io.grpc
庫與 gRPC 服務進行通信。 wire
的問題是它還不支持 proto3 版本。
在這里,我將為您提供一個如何從io.grpc
開始的示例。
假設有一個 gRPC 服務總結了您發送給它的號碼的 stream。 它的原型文件會是這樣的:
累加器.proto
syntax = "proto3";
package accumulator;
service Accumulator {
rpc NumberStream (stream NumberRequest) returns (stream AccumulateReply) {
}
}
message NumberRequest {
int32 number = 1;
}
message AccumulateReply {
int64 sumUp = 1;
}
你應該把這個文件放在項目的/src/main/proto/
目錄下。
現在是時候將所需的依賴項添加到build.gradle
文件中了。 請注意,它使用kapt
生成代碼。
應用層的 build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.google.protobuf'
apply plugin: 'kotlin-kapt'
android {
... others
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
}
}
protobuf {
protoc { artifact = 'com.google.protobuf:protoc:3.10.0' }
plugins {
javalite { artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0" }
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.25.0' // CURRENT_GRPC_VERSION
}
}
generateProtoTasks {
all().each { task ->
task.plugins {
javalite {}
grpc { // Options added to --grpc_out
option 'lite'
}
}
}
}
}
dependencies {
... other dependencies
// ------- GRPC
def grpc_version = '1.25.0'
implementation "io.grpc:grpc-android:$grpc_version"
implementation "io.grpc:grpc-okhttp:$grpc_version"
implementation "io.grpc:grpc-protobuf-lite:$grpc_version"
implementation "io.grpc:grpc-stub:$grpc_version"
// ------- Annotation
def javax_annotation_version = '1.3.2'
implementation "javax.annotation:javax.annotation-api:$javax_annotation_version"
}
項目級別的 build.gradle
buildscript {
repositories {
google()
jcenter()
}
dependencies {
... others
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.10'
}
}
這是一個 class 封裝了 stream 活動與服務器。 它通過回調返回接收到的值:
累加器處理程序.kt
import android.content.Context
import io.grpc.ManagedChannel
import io.grpc.android.AndroidChannelBuilder
import io.grpc.stub.ClientCallStreamObserver
import io.grpc.stub.StreamObserver
import accumulator.AccumulatorOuterClass
import java.util.concurrent.Executors
/**
* @author aminography
*/
class AccumulatorHandler constructor(
private val context: Context,
private val endPoint: String
) {
var callback: AccumulatorCallback? = null
private var managedChannel: ManagedChannel? = null
private var requestObserver: StreamObserver<AccumulatorOuterClass.NumberRequest>? = null
private val responseObserver: StreamObserver<AccumulatorOuterClass.AccumulateReply> =
object : StreamObserver<AccumulatorOuterClass.AccumulateReply> {
override fun onNext(value: AccumulatorOuterClass.AccumulateReply?) {
callback?.onReceived(value.sumUp)
}
override fun onError(t: Throwable?) {
callback?.onError(t)
}
override fun onCompleted() {
callback?.onCompleted()
}
}
fun offer(number: Int) {
initChannelIfNeeded()
requestObserver?.onNext(
AccumulatorOuterClass.NumberRequest.newBuilder()
.setNumber(number)
.build()
)
}
fun offeringFinished() {
requestObserver?.onCompleted()
}
private fun initChannelIfNeeded() {
if (managedChannel == null) {
managedChannel = AndroidChannelBuilder.forTarget(endPoint)
.context(context)
.usePlaintext()
.executor(Executors.newSingleThreadExecutor())
.build()
}
if (requestObserver == null) {
requestObserver = AccumulatorGrpc.newStub(managedChannel)
.withExecutor(Executors.newSingleThreadExecutor())
.numberStream(responseObserver)
}
}
fun release() {
(requestObserver as? ClientCallStreamObserver<*>)?.cancel("Cancelled by client.", null)
requestObserver = null
managedChannel?.shutdown()
managedChannel = null
callback = null
}
interface AccumulatorCallback {
fun onReceived(sum: Long)
fun onError(t: Throwable?)
fun onCompleted()
}
}
為了測試它,我編寫了一個活動 class 以簡單的方式展示它的用法:
我的活動.kt
/**
* @author aminography
*/
class MyActivity: AppCompatActivity, AccumulatorHandler.AccumulatorCallback {
private var accumulatorHandler: AccumulatorHandler? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
accumulatorHandler = AccumulatorHandler(applicationContext, "http://...")
accumulatorHandler.callback = this
for (number in 1..10){
accumulatorHandler.offer(number)
}
accumulatorHandler.offeringFinished()
}
override fun onReceived(sum: Long) {
Toast.makeText(this, "onReceived: $sum", Toast.LENGTH_SHORT).show()
}
override fun onError(t: Throwable?) {
Toast.makeText(this, "onError: $t", Toast.LENGTH_SHORT).show()
accumulatorHandler.release()
}
override fun onCompleted() {
Toast.makeText(this, "onCompleted", Toast.LENGTH_SHORT).show()
accumulatorHandler.release()
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.