我有一个带有同伴对象的类,它实现了一个工厂接口。
class GoalInspectorData(
...
) {
companion object : DataClassFactory<GoalInspectorData> {
override fun fromV8Object(v8Object: V8Object): GoalInspectorData {
...
}
}
}我有一些代码在运行时使用反射检查这个类,以查看该类是否提供了工厂方法。它通过检查类是否有伴生对象(companionObjectInstance)来实现这一点,如果有,则检查该类是否实现了工厂接口。
internal inline fun <reified T> convert(obj: Any): T {
val companionObject = T::class.companionObjectInstance
@Suppress("UNCHECKED_CAST")
return when {
T::class in builtInClasses -> obj as T
companionObject as? DataClassFactory<T> != null -> companionObject.fromV8Object(obj as V8Object)
else -> throw IllegalArgumentException("No converter for type ${T::class}")
}
}在调试版本中,所有这些都可以很好地工作。
在启用了build.gradle). ( R8中的minifyEnabled true)的版本构建中,它会失败。它失败了,因为companionObjectInstance返回null。
我使用的是不优化Proguard配置:
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'在我自己的proguard-rules.pro中,我添加了几乎所有我能想象到的-keep规则,试图保留这个伙伴对象,并在所有东西中添加了@Keep注释,但是没有什么效果。R8决心把它去掉。
例如:
-keep class my.package.** {
*;
}
-keep interface my.package.** {
*;
}
-if class **$Companion extends **
-keep class <2>
-if class **$Companion implements **
-keep class <2>是否还有其他-keep规则或配置选项可以指示R8保留此伙伴对象?
发布于 2019-09-17 15:51:21
首先,保持规则
-keep class my.package.** {
*;
}应该足以保留所有的类-包括程序中的辅助类。您不应该需要-dontoptimize标志,所以使用配置proguard-android-optimize.txt应该可以。
但是,在使用Kotlin反射时,您可能还需要保留注释类kotlin.Metadata和运行时可见注释,并包含以下规则:
-keep @interface kotlin.Metadata {
*;
}
-keepattributes RuntimeVisibleAnnotations如果这仍然不起作用,你能提交一个R8问题吗?如果你能包括一个简单的复制,那将是伟大的。
https://stackoverflow.com/questions/57974556
复制相似问题