TL; DR :启用proguard后,使用反射时,我的属性看起来是私有的,不可为空的,没有注释,尽管proguard配置应保留所有这些属性。
我有一些带有公共属性的简单data class
es在我的Android应用中用作数据模型。稍后,当对所述类进行泛型[de]序列化时,我会过滤属性列表,如下所示:
val properties = instance::class.memberProperties
.filter { it.visibility == KVisibility.PUBLIC } // && some other conditions, unrelated here
.filterIsInstance<KMutableProperty<*>>()
它在我的调试版本上正常工作(我的意思是它选择我想要它的属性)。但是,在执行发布构建时,proguard处于活动状态,结果为空。为了检查原因,我记录了关于一个类的属性的所有相关内容 - 结果显示他们的visibility
字段读取PRIVATE
(并且所有其他属性保持与调试版本相同)。
我已经在proguard配置中有一行来保留所有模型:
-keepclassmembers class * extends com.models.package.name.BaseModel { *; }
之前我试过这个,结果相同:
-keep class com.models.package.name.** { *; }
为什么/ proguard如何影响财产可见性?我应该以某种方式修改配置吗?或者我在这里错过了其他什么?
更新:看起来可见性并非唯一。 prop.returnType.isMarkedNullable
也不起作用,它会为声明为nullable的属性返回false
。即使我要求proguard保留它们,注释似乎也会迷失方向。有什么方法可以解决这个问题吗?它几乎让我的工作2周没用......
答案 0 :(得分:4)
感谢@yole对问题评论的建议,我已经能够完成这项工作。即使我的类被配置为由ProGuard保存,它也会从它们中删除kotlin.Metadata
注释。这些注释是Kotlin存储我失踪的所有属性的地方。解决方案是阻止ProGuard删除它们,添加到配置:
-keep class kotlin.Metadata { *; }
(旁注:奇怪的是它没有包含在默认配置中,至少如果你使用的是kotlin.reflect.full
包。或者至少它应该在文档的某个地方清楚地提到...... )