当我在proguard配置中添加以下"keep"规则时:
-keepclasseswithmembernames class ** implements com.my.package.MyInterfaceName { <fields>; }
首先,似乎所有实现了MyInterfaceName的类的类名和字段都保持不变。
但实际上在运行时,这些类通过getSimpleName()返回不同的简单名称。
举个例子:
public class Foo {
public enum Bar implements MyInterfaceName { X, Y, Z }
}
X.getClass().getSimpleName()
返回Foo$Bar
,而不是只返回未经过proguard处理的Bar
。
内部类和其他类一样。ProGuard就是这样对待它们的,比如在混淆它们的名字的时候。如果要保留嵌套结构,则必须保留相关的可选属性:
-keepattributes InnerClasses
Proguard非常激进,删除了比需要的更多的信息。幸运的是,由于您的配置行,全名不会改变,但对于简单的名称则不是好消息。要完整地处理枚举(它们也有一些需要保留的神奇方法),您应该参考http://proguard.sourceforge.net/index.html#manual/examples.html
的Processing enumeration classes
部分。如果您的应用程序,applet, servlet,库等包含枚举类中,必须保留一些特殊的方法。枚举在Java 5中被引入。java编译器翻译枚举到具有特殊结构的类中。值得注意的是,类包含一些静态方法的实现通过自省访问运行时环境(这不是很伟大吗?自省是新一代的自我修改代码)。你必须明确指定这些,以确保它们没有被删除或混淆:
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}