在我目前的 Kotlin Android 项目中,我不得不面对以下问题:
对于这个类层次结构
abstract class MyClass {
...
}
class MySubClassA: MyClass() {
...
}
class MySubClassB: MyClass() {
...
}
class MySubClassC: MyClass() {
...
}
我写了一个这样的创建者函数:
private fun <T : MyClass> createMyClass(myClassType: KClass<T>): T? {
val constructor = myClassType.primaryConstructor
return constructor?.call()?.apply {
...
}
}
这对于调试版本非常有效,但对于启用了 R8 混淆的发布版本,构造函数总是
null
。我对 R8 的设置是这样的:-keep class kotlin.** { *; }
-keep class kotlin.Metadata { *; }
-dontwarn kotlin.**
-keepclassmembers class **$WhenMappings {
<fields>;
}
-keepclassmembers class kotlin.Metadata {
public <methods>;
}
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
}
-keep class kotlin.reflect.jvm.internal.impl.builtins.BuiltInsLoaderImpl
在对 Kotlin 反射 API 进行一些逆向工程之后,我想出了以下解决方法:
private fun <T : MyClass> createMyClass(myClassType: KClass<T>): T? {
val constructor = myClassType.constructors.firstOrNull() {
it.valueParameters.isEmpty()
}
return constructor?.call()?.apply {
...
}
}
这似乎表明,该类的构造函数信息由 R8 保留,但有关主构造函数的元信息丢失了。
有人知道如何解决这个问题吗?
最佳答案
我遇到了这个问题,并且能够使用 @Keep
注释解决它。
abstract class MyClass {
}
class MySubClassA @Keep constructor(): MyClass() {
}
class MySubClassB @Keep constructor(): MyClass() {
}
class MySubClassC @Keep constructor(): MyClass() {
}
关于android - Kotlin 反射 : primaryConstructor not found with R8 obfuscation,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57206792/