Setting up Protobuf + Kotlin in Android Studio 2023 - Stack Overflow
How can I generate protobuf in Kotlin for Android applications? - Stack Overflow
Protobuf serialization in kotlin
Are you intending to align with kotlinx.serialization? In the general case, I would advise doing so - this is the emerging standard for Kotlin serialization which spans serialization formats (JSON, CBOR, and Protobuf first supported) and is designed to work with multi-platform.
More on reddit.com
java - How to setup protobuf in kotlin/android studio? - Stack Overflow
Videos
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
protofolder 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
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.
Hello, want to use protobuf to serialize a large string object to be stored in realm, as of now using JSON which is causing huge object memory. But not sure how can I use protobuf to achieve this as there are very little online examples that isn't relevant to my usecase. protobuf uses schema (.proto) file and serialize this file so that we can use it but in my case I will get string from response that needs serialization, any help would be much appreciated.
Are you intending to align with kotlinx.serialization? In the general case, I would advise doing so - this is the emerging standard for Kotlin serialization which spans serialization formats (JSON, CBOR, and Protobuf first supported) and is designed to work with multi-platform.
It's hard to do protobuf serialization without knowing the fields and type up front, that is why you are not seeing much examples on dynamic serialization.
There is no type information embedded within the protobuf message, only data. You can of course be "dynamic" by having a string field that stores your JSON, but that is not really optimal usage.
The process is usually like this:
-
Create protobuf definitions (.proto)
-
Use gradle or maven to compile protobuf to Java
-
Either build and distribute a jar with the compiled classes, or import the generated into your IDE
-
In your code, manually build an object based on your generated classes
-
Serialize it by calling toByteArray()
-
Deserialize to a new object by calling MyClass.parseFrom(byteArray)
There is not really much difference from Java here. While there is the possibility to have fields varying on the content, it is not meant for dynamic objects, it's strength is in keeping a semi-rigid structure with evolvability when passing (or storing) data between different systems.
If your goal is to save storage space, just gzip your json instead.
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 "8.11.1" apply false
id 'com.google.protobuf' version "0.9.5" apply false
}
Module-level 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).
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")
}
}
}
}
}