Proguard 不会保留班级成员的枚举

Posted

技术标签:

【中文标题】Proguard 不会保留班级成员的枚举【英文标题】:Proguard won't keep a class member's enums 【发布时间】:2011-09-11 06:04:45 【问题描述】:

我正在开发一个作为 java jar 分发的库,并且我正在对它运行 proguard,以便只暴露所需的接口。我有一个带有一堆成员变量和一些枚举定义的配置类。我的 proguard 脚本很好地保留了成员变量,但是,枚举定义被混淆了。我已经尝试了所有我能想到的强制 proguard 保留这些内部定义和公共枚举的方法,但我无法让它工作。

我现在正在使用:

-keep public class com.stuff.MyConfigObject 
    public *;


-keepclassmembers enum * 
    public static **[] values();
    public static ** valueOf(java.lang.String);

如果我尝试:

-keep public enum com.stuff.MyConfigObject.MyEnum

我收到一个模棱两可的错误: "注意:配置引用未知类'com.stuff.MyConfigObject.MyEnum'"

感谢您的帮助!

【问题讨论】:

【参考方案1】:

改用com.stuff.MyConfigObject$MyEnum。 Proguard class specification 期望 $ 作为内部类的分隔符。

实际上,对于您想要的,也许最好的选择是这样的:

-keep public enum com.stuff.MyConfigObject$** 
    **[] $VALUES;
    public *;

这将只保留嵌套在 MyConfigObject 中的所有 enums 所需的成员 - 所需的成员是 $VALUES[] 数组(有关说明,请参阅 this question)和枚举的任何 public 成员。不会保留任何其他成员(例如私有字段方法)。


正如 Jesse 和我在 cmets 中所指出的 - 由于您正在处理库,因此您还必须添加 -keepAttributes 选项。来自reference guide:

例如,在处理库时,您至少应该保留 Exceptions、InnerClasses 和 Signature 属性。

【讨论】:

谢谢你让我更接近了!但是,生成的 .jar 有点奇怪。枚举的类文件在那里,一切看起来都很好,但是在 Eclipse 中,没有一个成员可以使用。代码完成正确地显示了它们,但编译一直失败,并显示“MyEnum 无法解析或不是字段”。我正在使用 proguard 4.4。 我发现如果你添加 -keepAttributes ** 它将起作用。不确定必须保留哪些特定属性,但通过Proguard reference 和一些实验,我敢打赌你可以弄明白。 谢谢@Kevin K,你是救生员。像魅力一样工作! 感谢领导,我在 -keepattributes 的文档中找到了这一点:“例如,在处理库时,您至少应该保留 Exceptions、InnerClasses 和 Signature 属性。” 啊,我错过了那句话。很高兴知道。【参考方案2】:

要保留所有内部枚举,请尝试以下操作:

-keep class * 
    public enum **;

它让我不用在 proguard 配置中编写 123 个枚举中的每一个。

另外,如果您正在处理库,请不要忘记 -keepAttributes

【讨论】:

以上是关于Proguard 不会保留班级成员的枚举的主要内容,如果未能解决你的问题,请参考以下文章

如何将枚举类型字段保留在 proguard 中?

使用 Proguard 进行改造警告

我应该使用 unique_ptr 来保留班级成员吗?

Android Proguard 跳过外部 jar

如何排除一个类被proguard保留

android - 如何让 enum 远离 proguard