在 Kotlin 编写的 Android 库的公共 API 中处理 R8 + JvmStatic Annotation + Lambda

Jab*_*iyo 11 obfuscation android-library kotlin android-r8

首先,请注意,我不期待why do you want to obfuscate library评论。这是我要问的真正问题。

我在使用 Kotlin 编写的 Android 库处理 R8/混淆时遇到了问题。

我有一个带有注释的公共 API 方法,@JvmStatic该方法将 aLambda作为参数。

例如,看看下面的代码,

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

@Keep
object MyApi {

    private var callback: MyLambdaCallback? = null

    @JvmStatic
    fun setCallback(callback: MyLambdaCallback) {
        this.callback = callback
    }
}
Run Code Online (Sandbox Code Playgroud)

我添加了@Jvmstatic以便Java调用代码可以静态调用该方法而不是执行MyApi.INSTANCE.setCallback()

当我松开图书馆没有minification,一切都很好,并调用代码来自JavaKotlin预期被写入。

但是现在我想在打开时释放库minification

这就产生了一个问题。

这是错误

java.lang.IncompatibleClassChangeError: 方法 'void setCallback(kotlin.jvm.functions.Function2)' 预期为虚拟类型,但被发现为静态类型(出现 'com.demo.basic.Application' 声明在/data/app/com.demo.basic-_0uJXPbtfs3UZ2Rp2h-RdQ==/base.apk!classes2.dex)

我是在某处犯了错误还是预期这是某种限制?

我尝试了什么?

  1. 删除@Jvmstatic解决了问题,但它创建了丑陋的 Java 调用代码

  2. 保留@Jvmstatic但删除了Lambda将 Lambda 转换为 aninterface with one method并且一切正常。不幸的SAM for Kotlin classes是还没有,所以调用Kotlin代码看起来很难看。

Jab*_*iyo 2

R8 团队已修复此问题以及R8 版本中的相关问题b/1584002832.1.42

修复应该已经在或更高版本中可用Android Studio 4.1 beta,但如果您使用的是 stable Android Studio 4.0,则将以下内容添加到您的顶级 build.gradle 文件中:

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.
     }
}
Run Code Online (Sandbox Code Playgroud)