1

我已将 kotlin-reflect 库添加到我的 Android 项目中,现在 Proguard 正在生成数百行注释,列出所有具有名为 字段的类INSTANCE,其中当然包括每个 Kotlin object

这只是 Proguard 输出的一小部分:

Note: kotlin.reflect.jvm.internal.KClassImpl$Data$objectInstance$2 accesses a declared field 'INSTANCE' dynamically
      Maybe this is program field 'co.zsmb.example.proguardkttest.MySingleton { co.zsmb.example.proguardkttest.MySingleton INSTANCE; }'
      Maybe this is program field 'kotlin.UNINITIALIZED_VALUE { kotlin.UNINITIALIZED_VALUE INSTANCE; }'
      Maybe this is program field 'kotlin.Unit { kotlin.Unit INSTANCE; }'
      Maybe this is program field 'kotlin._Assertions { kotlin._Assertions INSTANCE; }'
      Maybe this is program field 'kotlin.collections.EmptyIterator { kotlin.collections.EmptyIterator INSTANCE; }'
      Maybe this is program field 'kotlin.collections.EmptyList { kotlin.collections.EmptyList INSTANCE; }'
      Maybe this is program field 'kotlin.collections.EmptyMap { kotlin.collections.EmptyMap INSTANCE; }'
      Maybe this is program field 'kotlin.collections.EmptySet { kotlin.collections.EmptySet INSTANCE; }'
      Maybe this is program field 'kotlin.comparisons.NaturalOrderComparator { kotlin.comparisons.NaturalOrderComparator INSTANCE; }'

如您所见,它既包括我自己的MySingleton类,也包括来自 Kotlin 标准库的许多类,并且它也可以在任何其他库中找到这些字段(如果存在)。

4

1 回答 1

1

错误的第一行告诉我们这里出了什么问题,它发现无论如何,它正在访问一个通过反射kotlin.reflect.jvm.internal.KClassImpl$Data$objectInstance$2命名的字段。INSTANCEProguard 无法判断此代码​​访问的INSTANCE字段是哪个类,因此它会警告我们每个具有此字段的类,以防万一。

如果我们查看 的来源KClassImpl,我们会很快找到罪魁祸首:它包含一个名为 的属性objectInstance,该属性在某些情况下会调用该Class#getDeclaredField方法,并传入一个带有值"INSTANCE"作为参数的常量。这就是 Proguard 正在检测的内容。

所以,除非你有一个单例类,并且你通过它的来访问它的实例KClass,就像这样:

val instance = MySingleton::class.objectInstance

您可以在proguard-rules.pro文件中添加以下规则来忽略 Proguard 注释:

-dontnote kotlin.reflect.jvm.internal.KClassImpl$Data$objectInstance**

您也可以使用 精确结束它objectInstance$2,但是库中的实现更改可能会在将来更改该位置编号。这样,您将忽略所有出现的关于该objectInstance属性及其实现的注释。

于 2018-07-10T17:41:16.380 回答