[译]区分ProGuard不同的"keep"指令

原文链接:https://jebware.com/blog/?p=418

如果搜索Java活Android库的ProGuard规则,你会在StackOverflow上看到一堆回答,告诉你要这样做:

-keep class com.foo.library.** { *; }

这个建议很糟糕,你永远都不应该这样做。首先,它过于宽泛——包中的双星号表示该顶级包下的每个包里的所有类;而花括号内的星号用于这些类中的每个成员(变量,方法和常量)。也就是说,它使用与库中的所有代码。如果你是用这个规则,Jack Wharton将会对你大喊:

其次,这盘文章是关于什么的,是指令的开始,即“keep”。你几乎不想用-keep;如果确实需要ProGurad规则,则通常需要以下更具体的变体之一。但是ProGuard手册花了我一些时间来弄清楚我的情况适用于哪个变体,所以我制作了一些表格以便快速查阅。(ProGuard手册非常有用,我强烈建议你仔细阅读。)

无规则

为了开始学习,先看看默认情况。如果不对任何类指定keep指令,那么ProGuard就会这样做,这是正常的事情——即要压缩(例如,去除无用代码),也要混淆(例如,重命名事物)类和类成员。

-keep

看,这就是为什么我说你几乎不应该使用-keep。-keep基诺那个了所有的ProGuard效益。不压缩,不混淆;即不用于类,也不用于成员。在实际的使用情况下,可以让ProGuard执行少量工作。即使通过反射访问变量,例如,可以删除或者重命名未使用的类。所以让我们看看其他具体的-keep变体。

-keepclassmembers

这个变体只保护类的成员不被压缩和混淆。也就是说,如果类未被使用,则删除类。如果类被使用,保留并重命名该类。类里的成员维持不变,仍然是之前的名字。

-keepnames

这个变体压缩类及成员,但不混淆它们。也就是说,未使用的代码将被移除。剩下的代码则维持原状。

-keepclassmembernames

这是最宽容的keep指令;它允许ProGuard完成几乎所有工作。移除未使用的类,剩下的类被重命名,类中未使用的成员将被移除,剩余的成员保留原来的名称。

-keepclasseswithmembers

这个变体没有表格,因为它与-keep作用一致。区别是它只适用于拥有类规范中所有成员的类。

-keepclasseswithmembernames

同样的,这条规则与-keepnames一致。区别也是它只适用于拥有类规范中所有成员的类。

结论

如果希望ProGuard做尽可能多的工作,就要选择上面最少红色X块,同时还能满足需求的指令。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值