微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

您如何使用 Kotlin 将 gRPC 添加到 Android Studio? 任务背景我尝试了什么?我现在拥有的问题我想要什么

如何解决您如何使用 Kotlin 将 gRPC 添加到 Android Studio? 任务背景我尝试了什么?我现在拥有的问题我想要什么

任务

我需要使用 gRPC 将 Android 客户端与 python 服务器连接。在 Python 中制作服务器和生成原型很容易,但是 Kt 客户端缺乏教程和混乱的文档使它看起来非常复杂。

背景

直到现在我已经使用 Kotlin 制作了一些简单的 Android 应用程序,我已经习惯于向模块或应用程序级别的 build.gradle 添加依赖项。

我尝试了什么?

我的第一个想法是去官方 documentation ,就像我用 Python 做的那样。 我发现那里的指南非常混乱(我觉得那篇文章中缺少一些东西),所以我去看了他们的 GitHub 中的完整示例。我还克隆了 repo 并使用 gradlew installdist 命令编译了原型。然后事情变得非常复杂:

  • 当你创建一个 Android Studio 项目时,你会得到一堆 gradle 东西(模块和应用级别的 build.gradle、gradlew 和 gradlew.bat、设置等)
  • 克隆存储库后,您会在 grpc-kotlin 文件夹中获得另一堆 gradle 内容
  • 您还会获得 build.gradle.kts,它似乎是相同的构建逻辑/包管理器帮助文件,但具有其他依赖项和 Kotlin 脚本语法。

这是我去 YouTube 上搜索一个简单实现的时候,发现只有少数关于 gRPC with Kotlin 主题的视频,其中大部分是演示视频关于使用 Coroutines 时 Kotlin 中 gRPC 的特性。

我现在拥有的

我将我所有的 build.gradle 迁移到 .kts 的。 这是我的模块级 build.gradle.kts 的样子:

buildscript {
    val kotlin_version = "1.5.10"
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:4.2.1")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlin_version}")
        classpath("org.jetbrains.kotlin:kotlin-android-extensions:${kotlin_version}")
        classpath("com.google.gms:google-services:4.3.8")
        classpath ("com.google.protobuf:protobuf-gradle-plugin:0.8.14")

    }
}

allprojects {
    repositories {
        google()
        mavenCentral()

    }
}

tasks.register("clean",Delete::class){
    delete(rootProject.buildDir)
}

这是我的应用级别 build.gradle.kts 的样子:

import com.google.protobuf.gradle.generateProtoTasks
import com.google.protobuf.gradle.id
import com.google.protobuf.gradle.plugins
import com.google.protobuf.gradle.protobuf
import com.google.protobuf.gradle.protoc

plugins {
    id("com.android.application")
    id("com.google.protobuf")
    kotlin("android")
}

android {
    compileSdkVersion(30)
    buildToolsversion = "30.0.3"

    defaultConfig {
        applicationId = "com.example.myapplication"
        minSdkVersion(26)
        targetSdkVersion(30)
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
            proguardFiles(getDefaultProguardFile("proguard-android.txt"),"proguard-rules.pro")
        }
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    kotlinoptions {
        jvmTarget = "1.8"
    }
    buildFeatures {
        viewBinding = true
    }
}

protobuf {
    protoc { artifact = "com.google.protobuf:protoc:3.12.0" }
    plugins {
        id("grpc") {
            artifact = "io.grpc:protoc-gen-grpc-java:1.35.0"
        }
    }
    generateProtoTasks {
        all().forEach { task ->
            task.plugins.create("java") {
                option("lite")
            }
            task.plugins {
                id("grpc") {
                    this.option("lite")
                }

            }
        }


    }
}

dependencies {

    val kotlin_version = "1.5.10"
    implementation("org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}")
    implementation("androidx.core:core-ktx:1.5.0")
    implementation("androidx.appcompat:appcompat:1.3.0")
    implementation("com.google.android.material:material:1.3.0")
    implementation("androidx.constraintlayout:constraintlayout:2.0.4")
    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test.ext:junit:1.1.2")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.3.0")

    // GRPC Deps
    implementation("io.grpc:grpc-okhttp:1.37.0")
    implementation("io.grpc:grpc-protobuf-lite:1.37.0")
    implementation("io.grpc:grpc-stub:1.36.0")
    implementation("org.apache.tomcat:annotations-api:6.0.53")
}

我可以生成原型,但它们有些不对劲。

问题

分别实现请求函数和双向流时,我发现我所有的 rpc 函数都要求额外的 StreamObserver 参数(我在互联网上找到的所有教程中都没有)。仔细一看,我发现所有生成文件都是用java写的,在官方文档上,生成文件都是POJO和Kotlin。

这是我生成的 Stub 类的样子:

  public static final class ChatServiceStub extends io.grpc.stub.AbstractAsyncStub<ChatServiceStub> {
    private ChatServiceStub(
        io.grpc.Channel channel,io.grpc.CallOptions callOptions) {
      super(channel,callOptions);
    }

    @java.lang.Override
    protected ChatServiceStub build(
        io.grpc.Channel channel,io.grpc.CallOptions callOptions) {
      return new ChatServiceStub(channel,callOptions);
    }

    /**
     * <pre>
     * This bi-directional stream makes it possible to send and receive Notes between 2 persons
     * </pre>
     */
    public void chatStream(grpc.Chat.Empty request,io.grpc.stub.StreamObserver<grpc.Chat.Note> responSEObserver) {
      io.grpc.stub.ClientCalls.asyncServerStreamingCall(
          getChannel().newCall(getChatStreamMethod(),getCallOptions()),request,responSEObserver);
    }

    /**
     */
    public void sendNote(grpc.Chat.Note request,io.grpc.stub.StreamObserver<grpc.Chat.Empty> responSEObserver) {
      io.grpc.stub.ClientCalls.asyncUnaryCall(
          getChannel().newCall(getSendNoteMethod(),responSEObserver);
    }
  }

我不知道如何为我的项目复制 gradle 脚本,我在互联网上找不到任何人解释所有这些 build.gradle 是如何链接在一起的(我发现模块级别的 build.gradle 正在描述它们如何're 应该构建和应用程序级别的 build.gradle 是同上的,但对于整个应用程序)。我找到的大部分文章都与官方文档相同。

我想要什么

我只想要一个简单的项目或分步教程,没有“克隆它并在终端中运行命令,它就可以工作”。

我不责怪开发人员或编写官方文档的人,我实际上打赌我在这里是个愚蠢的人,但我很难理解这些概念,如果有人能向我解释我做错了什么,我将不胜感激在哪里学习。

另外,抱歉问了这么长的问题,我试图尽可能地暴露我的 POV,这是我开始学习编程以来的第二个问题,如果问题和我的目标不够明确,我很抱歉,我如果需要,将编辑任何内容

解决方法

我没有可以分享的分步过程,也不想轻视一个很好的问题。但是,我想回应一下,在研究类似问题时,我发现 Square 有一个似乎对 Kotlin 更友好的库:

https://square.github.io/wire/#wire-kotlin

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。