Reputation: 60131
I have an Android project in Kotlin, where it is setup properly and works
In Root build.gradle
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
In App build.gradle
apply plugin: 'kotlin-android'
// ...
implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
All works well.
It also has Protobuf Support as per https://github.com/google/protobuf-gradle-plugin
Where in the App build.gradle it has
apply plugin: 'com.google.protobuf'
// ...
protobuf {
protoc {
// Download from repositories
artifact = 'com.google.protobuf:protoc:3.0.0'
}
plugins {
javalite {
// The codegen for lite comes as a separate artifact
artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
}
}
generateProtoTasks {
all().each { task ->
task.plugins {
javalite { }
}
}
}
}
sourceSets {
main {
java {
srcDirs += file("${protobuf.generatedFilesBaseDir}/debug/javalite")
}
}
}
// ...
api 'com.google.protobuf:protobuf-lite:3.0.0'
The only thing is, when the code that access the Protobuf generated codes i.e. codes in com.elyeproj.proto.*
, is in Java, all works well
package com.elyeproj.myapplication;
import com.elyeproj.proto.Card;
import com.elyeproj.proto.Heart;
import com.elyeproj.proto.Result;
import com.elyeproj.proto.Spade;
public class MainPresenter {
private MainView mainView;
public MainPresenter(MainView mainView) {
this.mainView = mainView;
}
public void fetchData() {
Card card1 = Card.newBuilder().setHeart(Heart.newBuilder().build()).build();
Card card2 = Card.newBuilder().setSpade(Spade.newBuilder().build()).build();
Result result = Result.newBuilder().addCards(card1).addCards(card2).build();
mainView.showResult(result.toString());
}
}
However, when converted to Kotlin
package com.elyeproj.myapplication
import com.elyeproj.proto.Card
import com.elyeproj.proto.Heart
import com.elyeproj.proto.Result
import com.elyeproj.proto.Spade
class MainPresenter(private val mainView: MainView) {
fun fetchData() {
val card1 = Card.newBuilder().setHeart(Heart.newBuilder().build()).build()
val card2 = Card.newBuilder().setSpade(Spade.newBuilder().build()).build()
val result = Result.newBuilder().addCards(card1).addCards(card2).build()
mainView.showResult(result.toString())
}
}
It will render an error at compile time with the message:
Error:(6, 21) Unresolved reference: proto
Error:(11, 21) Unresolved reference: Card
Error:(11, 48) Unresolved reference: Heart
Error:(12, 48) Unresolved reference: Spade
Error:(13, 22) Unresolved reference: Result
i.e. it can not access to those Protobuf generated code (although in the Android Studio, it could still access the code, e.g. code autocomplete could find the functions).
It looks like Protobuf Gradle support and Kotlin is not working. Or did I miss something?
To test it out, you could access the code in https://github.com/elye/issue_android_protobuf_light_java with MainPresentation in Java, which compiles fine. But if converts to Kotlin, it would render an error as above.
Upvotes: 2
Views: 2181
Reputation: 11
I've just resolved this problem in my project. Maybe you could try my solution. Adding below config in app build.gradle:
android {
...
// Adding generated proto to srcDirs depending on build variant
variantFilter { variant ->
def sourceSet = android.sourceSets.findByName(variant.buildType.name)
if (sourceSet != null) {
sourceSet.java.srcDirs += "build/generated/source/proto/${variant.name}/javalite"
}
}
...
}
//Running generating proto task before compiling Kotlin
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
mustRunAfter tasks.withType(com.google.protobuf.gradle.GenerateProtoTask)
}
Upvotes: 1
Reputation: 60131
There's a workaround on getting Kotlin supported, that is to use a Kotlin Module for the protobuf file generation. Then as a separate module, it could then be used. Check out https://medium.com/@elye.project/android-protobuf-in-kotlin-a1c33014a4e2 for more detail.
Upvotes: 0