当前位置: 首页 > 知识库问答 >
问题:

R8剥离反射所需的Kotlin同伴对象

米嘉禧
2023-03-14
class GoalInspectorData(
    ...
) {

    companion object : DataClassFactory<GoalInspectorData> {

        override fun fromV8Object(v8Object: V8Object): GoalInspectorData {
            ...
        }
    }
}
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}")
    }
}

它在启用R8的版本构建中失败(在build.gradle中的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保留此伴随对象?

共有1个答案

丁震博
2023-03-14

首先,保持规则

-keep class my.package.** {
    *;
}

应该足以保留所有类--包括程序中的伴生类。您应该不需要-dontoptimize标志,因此使用配置proguard-android-optimize.txt就可以了。

但是,在使用Kotlin反射时,您可能还需要使用以下规则保持注释类Kotlin.metadata和运行时可见注释:

-keep @interface kotlin.Metadata {
  *;
}
-keepattributes RuntimeVisibleAnnotations
 类似资料:
  • 所以我有下面的代码,用Kotlin写的。 我在最后一条指令行()上得到一个编译错误,编译器说,但我不知道为什么。 我认为同伴对象应该对它们“陪伴”的类的属性具有某种可见性。 (免责声明:此代码正在从Java迁移到Kotlin。在Java版本上,以前是同一个类上的静态方法。) 多谢!

  • 我用Kotlin编写了这些方法并分析了字节码: null 上下文。我一直在Kotlin编码,我觉得它很神奇。但有时我需要做一个决定:例如,一个很重的不可变属性,在java中我会将其声明为static final,但在Kotlin中我发现很难“找到一个等价物”。

  • 带有同伴对象的简单示例类 值测试可以通过访问,但如何从MyClass的实例访问?如果我有,那么我如何从sample访问测试?不正确....有没有办法? Java,C++,python等都有很简单的解决方案...(我将为每个有帮助的is提供代码示例),我认为kotlin会有一个比使用Java更好的解决方案。 对于在没有对象实例(如工厂)的情况下访问类属性,kotlin companion objec

  • 我是一个本地开发人员和新的Unity。我试图发挥我的优势,在Kotlin编码,然后使用我的代码作为一个插件在Unity。我遇到的一个问题是,我不知道如何引用伴生对象内部的函数。 但我怎样才能在团结中也这样做呢?以下是我尝试过的。 我收到的错误是, AndroidJavaException:java.lang.NosuchMethodError:没有具有name='factory'signature

  • 我想知道是否可以在同伴对象中使用类的属性。例如,以贝娄为例: 我不能通过c1或C2调用changeAge()函数。我可以使用changeAge的唯一地方是通过Person1.changeAge(),当Person1还没有用适当的构造函数实例化时。我想知道这些动作是不是有其他的选择,或者是没有,有同伴对象有什么意义呢

  • 在Kotlin的类中,一个对象和一个同伴对象有什么区别? 它的“静态”(我是java方面的)生命周期可能有区别吗?