英文:
Setting up Protobuf + Kotlin in Android Studio 2023
问题
我在Android Studio中花费了很多时间来设置Kotlin与Protobuf。最终目标只是将我的proto文件编译成Kotlin,并在我的项目中使用它们。
我在这里有一个示例项目:https://github.com/Jasperav/ProtobufAndroid。它模仿了我在真实应用程序中的设置:一个包含proto文件的外部目录和Android项目。它包含下面提到的所有代码。这是我在互联网上找到的教程的综合努力。它可能有很大问题。我尝试了https://github.com/google/protobuf-gradle-plugin,但对于我正在做的简单事情来说,它看起来太复杂了:
- 在你的文件系统的某个地方有一个包含proto文件的目录
- 创建一个新的Kotlin Android项目
- 在项目的build.gradle中,添加以下插件:
id 'com.google.protobuf' version '0.9.2' apply false
- 在模块的build.gradle中,添加以下内容:
- 在依赖项中添加:
implementation 'com.google.protobuf:protobuf-lite:3.21.12'
- 在
android
括号内底部添加sourceSets
- 在
dependencies
和android
之间的底部添加protobuf
部分
sourceSets:
sourceSets {
main {
kotlin {
srcDirs += 'build/generated/source/proto/main/kotlin'
}
proto {
srcDir '/Users/me/androidkotlin/proto'
}
}
}
protobuf:
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.21.12'
}
plugins {
kotlinlite {
artifact = 'com.google.protobuf:protoc-gen-kotlin:3.21.12'
}
}
generateProtoTasks {
ofSourceSet("main").forEach { task ->
task.builtins {
getByName("kotlin") {
option("lite")
}
}
}
}
}
我得到了这个错误:
A problem occurred evaluating project ':app'.
> Could not find method proto() for arguments [build_cxwfo79b6zcc266x9rsqzou9f$_run_closure1$_closure8$_closure10$_closure12@203aac02] on source set main of type com.android.build.gradle.internal.api.DefaultAndroidSourceSet.
希望这些信息对你有所帮助。
英文:
I spend hours on just setting up Protobuf with Kotlin in Android Studio. The endgoal is just that my proto files are compiled in Kotlin and that I can use them in my project.
I have an example project here: https://github.com/Jasperav/ProtobufAndroid. It mimics my setup in the real application: an external dir containing the proto files and the android project. It contains all the code mentioned below. This is a combined effort of tutorials I found on the internet. It is probably terrible wrong. I tried https://github.com/google/protobuf-gradle-plugin, but it just looks so complicated for something simple I am doing:
- Have a dir with protofiles somewhere on your filesystem
- Create a new Android project on Kotlin
- In the Project build.gradle, add
id 'com.google.protobuf' version '0.9.2' apply false
as plugin - In the Module build.gradle, add ->
- This to the dependencies:
implementation 'com.google.protobuf:protobuf-lite:3.21.12'
- The
sourceSets
at the bottom inside theandroid
bracket - The
protobuf
section at the bottom between thedependencies
andandroid
section.
sourceSets:
sourceSets {
main {
kotlin {
srcDirs += 'build/generated/source/proto/main/kotlin'
}
proto {
srcDir '/Users/me/androidkotlin/proto'
}
}
}
protobuf:
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.21.12'
}
plugins {
kotlinlite {
artifact = 'com.google.protobuf:protoc-gen-kotlin:3.21.12'
}
}
generateProtoTasks {
ofSourceSet("main").forEach { task ->
task.builtins {
getByName("kotlin") {
option("lite")
}
}
}
}
}
I get this error:
A problem occurred evaluating project ':app'.
> Could not find method proto() for arguments [build_cxwfo79b6zcc266x9rsqzou9f$_run_closure1$_closure8$_closure10$_closure12@203aac02] on source set main of type com.android.build.gradle.internal.api.DefaultAndroidSourceSet.
答案1
得分: 1
以下是翻译好的部分:
-
首先要检查的是您的
proto
文件夹是否位于正确的路径中,它应该在以下位置:root->app->src->main->proto
-
在项目的Gradle文件中,请确保应用了以下插件:
id("com.google.protobuf") version "0.8.15" apply false
-
在
app
的Gradle文件中,请确保具有以下内容:import com.google.protobuf.gradle.* plugins { id("com.android.application") id("org.jetbrains.kotlin.android") id("com.google.protobuf") }
依赖项如下:
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.2") implementation("com.google.protobuf:protobuf-kotlin:3.21.2") implementation("io.grpc:grpc-stub:1.52.0") implementation("io.grpc:grpc-protobuf:1.52.0") implementation("io.grpc:grpc-okhttp:1.52.0") implementation("com.google.protobuf:protobuf-java-util:3.21.7") implementation("com.google.protobuf:protobuf-kotlin:3.21.2") implementation("io.grpc:grpc-kotlin-stub:1.3.0")
还有protobuf任务:
protobuf { protoc { artifact = "com.google.protobuf:protoc:${rootProject.ext["protobufVersion"]}" } plugins { id("java") { artifact = "io.grpc:protoc-gen-grpc-java:${rootProject.ext["grpcVersion"]}" } id("grpc") { artifact = "io.grpc:protoc-gen-grpc-java:${rootProject.ext["grpcVersion"]}" } id("grpckt") { artifact = "io.grpc:protoc-gen-grpc-kotlin:${rootProject.ext["grpcKotlinVersion"]}:jdk8@jar" } } generateProtoTasks { all().forEach { it.plugins { id("java") { option("lite") } id("grpc") { option("lite") } id("grpckt") { option("lite") } } it.builtins { id("kotlin") { option("lite") } } } } }
这些是我使用的版本:
ext["grpcVersion"] = "1.47.0"
ext["grpcKotlinVersion"] = "1.3.0" // CURRENT_GRPC_KOTLIN_VERSION
ext["protobufVersion"] = "3.21.2"
ext["coroutinesVersion"] = "1.6.2"
拥有这些配置后,您的项目应该能够基于您的Proto文件生成代码。
如需进一步参考,我最近基于Kotlin + gRPC构建了这个Android应用程序:https://github.com/wilsoncastiblanco/notes-grpc
英文:
You are in a good way, but, there is some stuff missing:
The gradle code I'll share is written in Kotlin, just in case. If you can convert your grade files to Kotlin, nice, if not you have to convert them to groovy.
- The first thing to check is if you have the
proto
folder in the right path, it should be in
root->app->src->main->proto
- In the project gradle make sure to have the plugin applied
id("com.google.protobuf") version "0.8.15" apply false
- In the app gradle, make sure to have the following.
import com.google.protobuf.gradle.*
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.protobuf")
}
The dependencies:
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.2")
implementation("com.google.protobuf:protobuf-kotlin:3.21.2")
implementation("io.grpc:grpc-stub:1.52.0")
implementation("io.grpc:grpc-protobuf:1.52.0")
implementation("io.grpc:grpc-okhttp:1.52.0")
implementation("com.google.protobuf:protobuf-java-util:3.21.7")
implementation("com.google.protobuf:protobuf-kotlin:3.21.2")
implementation("io.grpc:grpc-kotlin-stub:1.3.0")
And the protobuf task:
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:${rootProject.ext["protobufVersion"]}"
}
plugins {
id("java") {
artifact = "io.grpc:protoc-gen-grpc-java:${rootProject.ext["grpcVersion"]}"
}
id("grpc") {
artifact = "io.grpc:protoc-gen-grpc-java:${rootProject.ext["grpcVersion"]}"
}
id("grpckt") {
artifact = "io.grpc:protoc-gen-grpc-kotlin:${rootProject.ext["grpcKotlinVersion"]}:jdk8@jar"
}
}
generateProtoTasks {
all().forEach {
it.plugins {
id("java") {
option("lite")
}
id("grpc") {
option("lite")
}
id("grpckt") {
option("lite")
}
}
it.builtins {
id("kotlin") {
option("lite")
}
}
}
}
}
These are the versions I'm using:
ext["grpcVersion"] = "1.47.0"
ext["grpcKotlinVersion"] = "1.3.0" // CURRENT_GRPC_KOTLIN_VERSION
ext["protobufVersion"] = "3.21.2"
ext["coroutinesVersion"] = "1.6.2"
Having that your project should generate the code based on your proto files.
For further reference, I recently build this Android App based on Kotlin + gRPC: https://github.com/wilsoncastiblanco/notes-grpc
答案2
得分: 0
Maybe too little too late, but the answer here worked for me using Android Studio Electric Eel | 2022.1.1 Patch 1--with the exception of the protobuf section. I had to change it from:
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.20.1"
}
plugins {
javalite {
artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
}
}
generateProtoTasks {
all().each { task ->
task.builtins {
java {
option 'lite'
}
kotlin {
option 'lite'
}
}
}
}
}
To:
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.20.1"
}
plugins {
javalite {
artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
}
}
generateProtoTasks {
all().each { task ->
task.builtins {
java {
option 'lite'
}
kotlin {
option 'lite'
}
}
}
}
Notice the subtle difference in the generateProtoTasks
. Just make sure you drop your .proto file into /src/main/proto
in your project and you should be good to go.
英文:
Maybe too little too late, but the answer here worked for me using Android Studio Electric Eel | 2022.1.1 Patch 1--with the exception of the protobuf section. I had to change it from:
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.20.1"
}
plugins {
javalite {
artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
}
}
generateProtoTasks {
all().each { task ->
java {
option 'lite'
}
kotlin {
option 'lite'
}
}
}
}
To:
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.20.1"
}
plugins {
javalite {
artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
}
}
generateProtoTasks {
all().each { task ->
task.builtins {
java {
option 'lite'
}
kotlin {
option 'lite'
}
}
}
}
}
Notice the subtle difference in the generateProtoTasks
. Just make sure you drop your .proto file into /src/main/proto
in your project and you should be good to go.
答案3
得分: 0
请确认您的 sourceSets 实际上位于 android 括号内:
android {
sourceSets {
main {
proto {
...
}
java {
...
}
}
}
}
英文:
Please confirm that your sourceSets is actually within the android brackets:
android {
sourceSets {
main {
proto {
...
}
java {
...
}
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论