使用Kotlin编写的Android库公共API中的R8 + JvmStatic批注+ Lambda处理

问题描述 投票:5回答:1

首先,请注意,我不希望收到why do you want to obfuscate library评论。这是我要问的一个真正的问题。

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

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

例如,看下面的代码,

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

@Keep
object MyApi {

    private var callback: MyLambdaCallback? = null

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

我添加了@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转换为interface with one method,一切正常。不幸的是SAM for Kotlin classes还不存在,因此调用Kotlin代码看起来很丑。

更新(2小时后):

此问题仅适用于R8。

我在gradle.properties中添加了这两行

android.enableR8=false
android.enableR8.libraries=false

这将强制使用Proguard

我重建了图书馆,一切正常。

kotlin obfuscation android-library android-r8
1个回答
0
投票

在R8问题跟踪器http://issuetracker.google.com/158393309上进行了跟踪,它具有更多详细信息。

简短的说,这已在R8版本2.1.35中修复,可以通过对顶级build.gradle文件进行以下更改来使用:

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.
 }
© www.soinside.com 2019 - 2024. All rights reserved.