Das*_*tor 6 java annotations proguard shrink
这是有问题的配置设置: -keep @interface *
此帖子中引用了此设置:https://stackoverflow.com/a/17437740/367544
在Proguard手册中:https://www.guardsquare.com/en/proguard/manual/troubleshooting#notkept
但手册(或帖子)并未解释此配置设置的工作原理或原因.我认为这个配置值将保留您的应用程序中定义的任何注释.我强调这个词定义这里是因为我想比较它在那里的注释使用.因此,如果我在我的代码中定义了一个注释,public @interface MyAnnotation {}那么我希望这个配置设置能够保留它.但是,如果我在另一个类中使用我的注释,public class MyClass { @MyAnnotation public void run(){} }那么我不希望这个配置设置在那里保留它.我认为要保留使用它的注释,你需要一个像这样的设置-keep class * { @interface <methods>; }.但是,我的理解显然是错误的,因为-keep @interface *配置设置确实保留了使用它们的注释.
任何人都可以解释为什么-keep @interface *配置设置会影响其他类中使用的注释吗?此外,Proguard手册从未解释过如何使用@interface关键字.这是任何注释的通配符吗?或者它是否像我的例子中那样引用了注释的定义public @interface MyAnnotation {}?或者它完全是另一回事?
当每个接口被编译时,即使使用 proguard,它也应该创建一个可以在 java 虚拟机中使用的有效类文件。Java 有特定的命名规则来连接包中的接口和类与文件。
因此,例如,即使VeryImportantInterface包的接口com.mycompany.mypackage被混淆,结果你得到:interface ain package java期望在名为的文件中b.c.d找到a包中的接口b.c.da.class
类似的规则适用于内部类和接口。
因此,如果您确实混淆了类或接口的定义,则必须在任何地方都提及它的混淆名称。否则,如果类MyClass.class被混淆为a.class另一个类,例如MyClassReference仍然引用此类,MyClass那么当尝试ClassNotFoundException时将抛出第一次MyClassReference使用。MyClass
关于-keep @interface *如ProGuard RefCard 中指定
“keep”可防止类和类成员被删除或重命名。
ProGuard RefCard*还提到可以使用通配符
*可用于任意数量的字符(但不能用于包分隔符)- 类名
*指的是任何类,无论其包是什么。*匹配任何字段或方法
因此-keep @interface *根据上面的定义适用于,public @interface MyAnnotation {}因为它的名称与通配符匹配*。由于根据定义MyAnnotation是不可删除的,因此它不会从任何地方删除。
相反-keep class * { @interface <methods>; },它更具体,并且只保留注释的用法。
另一件需要考虑的事情是keep后面跟着一个Class 规范。并基于类规范
@ 规范可用于将类和类成员限制为使用指定注释类型注释的类和类成员。注释类型的指定就像类名一样。
在收缩过程中,proguard 将删除所有直接或间接使用的方法和成员以及指定的方法和成员-keep。但是它没有明确提及它对注释的作用。Pro-Guard 提到了关于缩小以下内容:
默认情况下,应用收缩;除了各种 -keep 选项列出的类和类成员以及它们直接或间接依赖的类和类成员之外,所有类和类成员都将被删除。 收缩选项 因此,一种情况可能是 pro-guard 以某种方式检测到注释已被使用,并防止它在收缩过程中被删除。另一种情况是注释被视为方法的元数据而不被视为成员。它在 proguard 文档中确实不明显或没有很好的记录。
您可以使用-whyareyoukeeping @interface *和-verbose从 Prog-Guard 获取有关其保留相关接口的原因的反馈。
更新:由于上述配置指令的结果是:
... is kept by a directive in the configuration.,因此只能得出结论,-keep @interface *实际上 . 因此,它不提供任何额外的说明。如果没有 Pro-Guard 文档的任何具体解释,我认为以下 2 种可能的解释是可能的: 1. proguard 收缩步骤认为注释在代码的某些部分使用,因此需要且不会减少。2. class_specation@interface *匹配带注释的方法和注释声明。