Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

311
Views
Dealing with R8 + JvmStatic Annotation + Lambda in public API for Android Library written in Kotlin

First of all, please note that I'm not expecting why do you want to obfuscate library comments. This is a genuine problem I'm asking about.

I have been having an issue dealing with R8/obfuscation with an Android library written in Kotlin.

I've a public API method which is annotated with @JvmStatic and that method takes a Lambda as parameter.

For example, take a look at code below,

typealias MyLambdaCallback = (String, Map<String, Any>) -> Unit

@Keep
object MyApi {

    private var callback: MyLambdaCallback? = null

    @JvmStatic
    fun setCallback(callback: MyLambdaCallback) {
        this.callback = callback
    }
}

I have added @Jvmstatic so that Java calling code can call the method statically rather than doing MyApi.INSTANCE.setCallback()

When I release the library without minification, everything is fine and calling code from both Java and Kotlin is written as expected.

But now I want to release the library while turning on minification.

That creates an issue.

Here is the error

java.lang.IncompatibleClassChangeError: The method 'void setCallback(kotlin.jvm.functions.Function2)' was expected to be of type virtual but instead was found to be of type static (declaration of 'com.demo.basic.Application' appears in /data/app/com.demo.basic-_0uJXPbtfs3UZ2Rp2h-RdQ==/base.apk!classes2.dex)

Am I making a mistake somewhere or this is expected as some kind of limitation ?

What did I Try ?

  1. Removing @Jvmstatic resolves the issue but it created ugly Java calling code

  2. Kept @Jvmstatic but removed Lambda converting Lambda into an interface with one method and everything is working fine. Unfortunately SAM for Kotlin classes is not there yet, so calling Kotlin code looks ugly.

over 4 years ago · Hanz Gallego
2 answers
Answer question

0

This is tracked on the R8 issue tracker http://issuetracker.google.com/158393309 which has more details.

The short story is that this has been fixed in R8 version 2.1.35, which can be used by making the following changes to the top level build.gradle file:

repositories {
    maven {
        url 'https://storage.googleapis.com/r8-releases/raw'
    }
}

dependencies {
    classpath 'com.android.tools:r8:2.1.35'          // Must be before the Gradle Plugin for Android.
    classpath 'com.android.tools.build:gradle:X.Y.Z' // Your current AGP version.
 }
over 4 years ago · Hanz Gallego Report

0

R8 team has fixed this issue along with related issue b/158400283 in R8 version 2.1.42

Fix should already be available in Android Studio 4.1 beta or higher, but if you're using stable Android Studio 4.0 then add following to your top-level build.gradle file:

buildscript {

    repositories {
        maven {
            url 'https://storage.googleapis.com/r8-releases/raw'
        }
    }

    dependencies {
        classpath 'com.android.tools:r8:2.1.42'          // Must be before the Gradle Plugin for Android.
        classpath 'com.android.tools.build:gradle:X.Y.Z' // Your current AGP version.
     }
}
over 4 years ago · Hanz Gallego Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!