How to setup protobuf in kotlin/android studio?
Asked Answered
S

2

9

First time using protobuf, so following googles instructions I placed all my .protos in a protos folder in my android studio project. I know the .proto files are setup correctly. I compile the files from that folder using:

protoc -I=. --java_out=. --kotlin_out=. filename.proto

This generates a bunch of kotlin and java files that look like what I am supposed to get. However, android studio throws a ton of errors and doesn't seem to like most of the code in those files.

So my question is there something additional I need to do with the setup, bring in a dependency in the gradle file? I saw an example like that but it seemed only relevant to the plugin for compiling using gradle - since I'm compiling from the command line I don't think I should need that?

Stripe answered 12/5, 2022 at 5:12 Comment(0)
R
11

One cannot add *.proto files into Java or Kotlin source directories ...
For Android use protobuf-lite; the configuration looks about like this:

plugins {
    id 'com.android.application' version '7.2.0' apply false
    id 'com.google.protobuf' version '0.8.18' apply false
}

Module build.gradle:

plugins {
    id 'com.android.application'
    id 'com.google.protobuf'
}

android {
    sourceSets {
        main {
            java {
                srcDirs += 'build/generated/source/proto/main/java'
            }
            kotlin {
                srcDirs += 'build/generated/source/proto/main/kotlin'
            }
            proto {
                srcDir 'src/main/proto' // default value
            }
        }
    }
}

dependencies {
    implementation 'com.google.protobuf:protobuf-javalite:3.20.1'
    implementation 'com.google.protobuf:protobuf-kotlin-lite:3.20.1'
}

There's also a protoc compiler and protoc-gen-javalite generator available:

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'
            }
        }
    }
}

Also see protobuf-gradle-plugin (the Kotlin/GRPC example there isn't for Android).

Rockies answered 12/5, 2022 at 5:23 Comment(6)
eg. Firebase is using protobuf-javalite, which may subsequently lead to a dependency conflict. Android Java is not necessarily the same as "Java". option 'lite' is also a matter of performance. That Kotlin example on GitHub is the anti-pattern, which not to follow on Android. You don't get to choose.Rockies
I tried this and I get > Could not find method option() for arguments [lite] on extension 'kotlin' of type org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension. I'm using gradle 7.4, Any idea?Vraisemblance
@Vraisemblance I am also using the Kotlin DSL and tonycodes reply on this github issue helped me.Girish
@MartinZeitler This post really helped me understand when to use the lite dependencies. Declaring sourceSets is not necessary since you are using the default location for proto files. Documented in the plugin docs: github.com/google/protobuf-gradle-pluginGirish
@Vraisemblance use task.builtins { } and put the java or kotlin inside thatSabadilla
Thanks @MartinZeitler for the answer which works.Mielke
D
2

I configured protobuf like this:

app/build.gradle.kts

plugins {
    ...
    id("com.google.protobuf") version "0.9.4"
}

android {}

dependencies {
    ...
    implementation("com.google.protobuf:protobuf-javalite:3.18.0")
}

protobuf {
    protoc {
        artifact = "com.google.protobuf:protoc:3.19.4"
    }

    generateProtoTasks {
        all().configureEach {
            builtins {
                id("java") {
                    option("lite")
                }
            }
        }
    }
}
Dithionite answered 13/3, 2024 at 17:9 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.