简体   繁体   中英

Kotlin Reflection: primaryConstructor not found with R8 obfuscation

In my current Kotlin Android project I just had to face the following problem:

For this class hierarchy

abstract class MyClass {
...
}

class MySubClassA: MyClass() {
...
}

class MySubClassB: MyClass() {
...
}

class MySubClassC: MyClass() {
...
}

I wrote a creator function like this:

private fun <T : MyClass> createMyClass(myClassType: KClass<T>): T? {
    val constructor = myClassType.primaryConstructor

    return constructor?.call()?.apply {
    ...
    }
}

This worked nicely for the debug version but for the release version with R8 obfuscation turned on the constructor was alway null . My settings for R8 were this:

-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

After some reverse engineering of the Kotlin reflection API I came up with the following workaround:

private fun <T : MyClass> createMyClass(myClassType: KClass<T>): T? {
    val constructor = myClassType.constructors.firstOrNull() {
        it.valueParameters.isEmpty()
    }

    return constructor?.call()?.apply {
    ...
    }
}

This seems to indicate, that the constructor information of the class is preserved by R8 but the meta information about a constructor being primary gets lost.

Does anybody know how to solve this in general?

I came across this issue and was able to resolve it using the @Keep annotation.

abstract class MyClass {
}

class MySubClassA @Keep constructor(): MyClass() {
}

class MySubClassB @Keep constructor(): MyClass() {
}

class MySubClassC @Keep constructor(): MyClass() {
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM