问题
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 ?
Removing
@Jvmstatic
resolves the issue but it created ugly Java calling codeKept
@Jvmstatic
but removedLambda
converting Lambda into aninterface with one method
and everything is working fine. UnfortunatelySAM for Kotlin classes
is not there yet, so callingKotlin
code looks ugly.
回答1:
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.
}
回答2:
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.
}
}
来源:https://stackoverflow.com/questions/62249685/dealing-with-r8-jvmstatic-annotation-lambda-in-public-api-for-android-librar