Android ProGuard:最激进的优化

Android的官方proguard文档显示了两个主要的优化:

  • minifyEnabled设置为true
  • 使用proguard-android-optimize.txt代替proguard-android.txt

这两个最积极的可能设置?

我正在编写一个Android库,并且需要确保何时人们使用我的库,我的代码不会中断。 (我知道有些规则可以放在我的库中,用来对付使用该库的应用程序中设置的proguardconfiguration,但是如果不需要,我不想这样做)。

请记住,最好的ProGuardconfiguration – 是一个极less有例外的configuration。 根据例外,我明白:

  -keepclassmembers class * extends android.content.Context { public void *(android.view.View); public void *(android.view.MenuItem); } 

让我们通过proguard-android-optimize.txt来查看优化/混淆选项。

有关ProGuard选项的详细说明,请使用此选项

-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/* 这个 – 可能的优化列表! 意味着否定,所以这个优化不被使用

-optimizationpasses 5指定要执行的优化传递的数量。 默认情况下,执行一次传递。 多次传递可能会导致进一步的改进。 如果在优化后没有find改进,则优化结束。 只适用于优化。
用法: 好的 ,看起来像默认的5遍就足够了

-allowaccessmodification指定在处理期间可以扩展类和类成员的访问修饰符。 这可以改善优化步骤的结果。
用法: 好的 ,是的,看起来像提高优化

-dontpreverify当瞄准Android时,preverifing是不必要的,所以dontpreverify把它closures以减less处理时间。 但是这个选项不影响代码的不可破解性。
用法: 好吧 ,稍微减less处理时间

-dontusemixedcaseclassnames指定在模糊处理时不生成混合大小写的类名称。 默认情况下,混淆的类名可以包含大写字母和小写字符的混合。 这创造完全可接受和可用的jar子。
用法: QUESTIONABLE ,找不到确切的原因为什么添加这个选项,但是看起来像从abcdefAbSdEf更改类名不会使代码AbSdEf破解

-dontskipnonpubliclibraryclasses指定不忽略非公共库类。 从版本4.5开始,这是默认设置。
用法: 好的 ,非常有用

以下选项不包含在proguard-android-optimize.txt中:

-mergeinterfacesaggressively指定可以合并接口,即使它们的实现类不实现所有接口方法…设置此选项可能会降低某些JVM上处理的代码的性能
用法: BAD ,对Android来说看起来很危险,不包括在configuration中,禁止类/合并/优化中的总和

-overloadaggressively指定在混淆时应用主动重载。 只要它们的参数和返回types不同,多个字段和方法就可以获得相同的名称,正如Java字节码所要求的那样(不仅仅是它们的参数,正如Java语言所要求的那样)
用法: BAD ,Google的Dalvik虚拟机无法处理重载的静态字段。

-repackageclasses ''指定将所有重命名的类文件重新打包,将它们移动到给定的单个包中。 没有参数或空string(''),包被完全删除。 该选项将覆盖-flattenpackagehierarchy选项。
用法: 好的 ,由Google使用,所以看起来我们至less已经find了我们可以添加到我们的configuration的选项

所以我知道只有一个更有用的混淆和非危险的选项:
-repackageclasses ''

另外请注意解码堆栈跟踪。 ProGuard也从堆栈中删除文件名和行号。 这使得发现错误非常复杂。 您可以通过将以下代码添加到您的configuration中来保留行号:

 -renamesourcefileattribute SourceFile -keepattributes SourceFile,LineNumberTable 

这将保留行号,但用“SourceFile”replace堆栈跟踪中的文件名。

另外不要忘记,ProGuard看起来很脆弱,因为它不会encryptionstring资源 ,所以考虑使用DexGuard或者自己encryption重要的string(如标记,url)。

根据优化文件的评论,优化会带来一定的风险,如果使用,应用程序必须彻底testing。 根据我的经验,有必要禁用代码/简化/高级,因为它导致最终的局部variables在lambda之外被初始化为lambda中的空值。 debugging和查找非常困难。 所以我的优化设置如下:

代码/简化/高级,!字段/ *,!类/合并/ *,!方法/删除/参数,!方法/传播/参数

请注意,如果您的目标是Android 2.0或更低(这是不太可能的),代码/简化/算术也必须被禁用。 除此之外,我还必须禁用方法/删除/参数和方法/传播/参数,因为这些隐式启用代码/简化/高级(更多信息参见ProGuard手册 )。

Interesting Posts