Kotlin Multiplatform(Android/Desktop)集成gRPC实现代码共享问题
解决方案
一、先解决现有方案的重复类报错
你遇到的重复类错误是因为同时引入了互斥的protobuf-java(完整版)和protobuf-javalite(轻量版)依赖,直接按以下步骤修改即可:
- 删掉
shared-logic模块依赖中的api("com.google.protobuf:protobuf-java-util:${Versions.PROTOBUF}"),该库默认依赖完整版protobuf-java,和你配置的lite代码生成规则冲突。 - 在项目根目录的
build.gradle.kts中添加全局排除规则,强制所有子模块仅使用轻量版protobuf:
allprojects { configurations.all { exclude(group = "com.google.protobuf", module = "protobuf-java") } }
修改后重新sync项目即可解决依赖冲突问题。
二、更优方案:直接在KMP公共模块集成gRPC,实现逻辑完全复用
不需要单独拆分JVM子模块,直接改造你原来的common KMP模块,就能实现gRPC逻辑一次编写、Android和Desktop两端直接调用:
1. 修改common模块的build.gradle.kts配置
plugins { id("com.android.library") kotlin("multiplatform") id("org.jetbrains.compose") // 加入protobuf插件 id("com.google.protobuf") version "0.9.4" } kotlin { android() jvm("desktop") sourceSets { val commonMain by getting { dependencies { api(compose.runtime) api(compose.foundation) api(compose.material) api(compose.ui) implementation(compose.preview) implementation(compose.uiTooling) // 公共gRPC依赖 api("io.grpc:grpc-stub:${Versions.GRPC}") api("io.grpc:grpc-protobuf-lite:${Versions.GRPC}") api("io.grpc:grpc-kotlin-stub:${Versions.GRPC_KOTLIN}") api("com.google.protobuf:protobuf-kotlin-lite:${Versions.PROTOBUF}") api("org.jetbrains.kotlinx:kotlinx-coroutines-core:${Versions.COROUTINES}") } } val androidMain by getting { dependencies { // Android端gRPC传输层实现 implementation("io.grpc:grpc-okhttp:${Versions.GRPC}") } } val desktopMain by getting { dependencies { // Desktop端gRPC传输层实现 implementation("io.grpc:grpc-netty-shaded:${Versions.GRPC}") } } } } android { compileSdk = 31 defaultConfig { minSdk = 21 targetSdk = 31 } compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } sourceSets { val main by getting { manifest.srcFile("src/androidMain/AndroidManifest.xml") res.srcDirs("src/androidMain/res") // 配置Android端识别proto目录 proto.srcDir("src/commonMain/proto") } } } // 配置proto文件路径,这里可以直接放在commonMain/proto目录下,也可以指定你原来的外部proto目录 sourceSets { main { proto { srcDirs("src/commonMain/proto") // 要是用外部目录就换成你之前的路径:srcDirs("../protos/src/main") } } } // proto代码生成配置 protobuf { protoc { artifact = "com.google.protobuf:protoc:${Versions.PROTOBUF}" } plugins { id("grpc") { artifact = "io.grpc:protoc-gen-grpc-java:${Versions.GRPC}" } id("grpckt") { artifact = "io.grpc:protoc-gen-grpc-kotlin:${Versions.GRPC_KOTLIN}:jdk7@jar" } } generateProtoTasks { all().forEach { task -> task.plugins { id("grpc") { option("lite") } id("grpckt") { option("lite") } } task.builtins { id("kotlin") { option("lite") } } } } }
2. 代码复用实现
在commonMain中编写gRPC业务逻辑,只需要将传输层客户端的实例化通过接口注入的方式,分别在androidMain和desktopMain中实现对应平台的传输客户端,上层业务逻辑完全不需要区分平台,一次编写两端通用。
内容的提问来源于stack exchange,提问作者Intektor
相关产品推荐
相关产品推荐

