首先,请注意,我不希望收到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
的库时,一切都很好,并且按预期编写了从Java
和Kotlin
的调用代码。
但是现在我想在打开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
。
我重建了图书馆,一切正常。
在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.
}