Setting up Protobuf + Kotlin in Android Studio 2023.

huangapple go评论58阅读模式
英文:

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中,添加以下内容:
  1. 在依赖项中添加:implementation 'com.google.protobuf:protobuf-lite:3.21.12'
  2. android括号内底部添加sourceSets
  3. dependenciesandroid之间的底部添加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 ->
  1. This to the dependencies: implementation 'com.google.protobuf:protobuf-lite:3.21.12'
  2. The sourceSets at the bottom inside the android bracket
  3. The protobuf section at the bottom between the dependencies and android 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

以下是翻译好的部分:

  1. 首先要检查的是您的proto文件夹是否位于正确的路径中,它应该在以下位置:

    root->app->src->main->proto
    
  2. 在项目的Gradle文件中,请确保应用了以下插件:

    id("com.google.protobuf") version "0.8.15" apply false
    
  3. 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.

  1. 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
  1. In the project gradle make sure to have the plugin applied
id("com.google.protobuf") version "0.8.15" apply false
  1. 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 {
        ...
      }
    }
  }
}

huangapple
  • 本文由 发表于 2023年2月8日 17:54:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/75384020.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定