请记住,最好的 ProGuard 配置 - 是具有最少异常的配置。
在我理解的例外情况下:
-keepclassmembers class * extends android.content.Context {
public void *(android.view.View);
public void *(android.view.MenuItem);
}
让我们浏览一下 proguard-android-optimize.txt 并查看优化/混淆选项。
有关 ProGuard 选项的详细说明,我使用 this
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
This - 可能的优化列表,!表示否定,所以不使用这个优化
-optimizationpasses 5
指定要执行的优化遍数。默认情况下,执行单遍。多次通过可能会导致进一步的改进。如果优化通过后没有发现改进,则结束优化。仅在优化时适用。
用法:OK,貌似默认5遍就够了
-allowaccessmodification
指定在处理期间可以扩展类和类成员的访问修饰符。这可以改善优化步骤的结果。
用法:OK,是的,看起来改进了优化
-dontpreverify
当面向 Android 时,preverifing 不是必需的,所以不要preverify 将其关闭以减少一点处理时间。但是这个选项不会影响代码的不可破坏性。
用法:OK,只是稍微减少处理时间
-dontusemixedcaseclassnames
指定在混淆时不生成大小写混合的类名。默认情况下,混淆的类名可以包含大写字符和小写字符的混合。这将创建完全可接受和可用的罐子。
用法:QUESTIONABLE,我找不到添加此选项的确切原因,但看起来将类名从 abcdef 更改为 AbSdEf 不会使代码牢不可破
-dontskipnonpubliclibraryclasses
指定不忽略非公共库类。从 4.5 版开始,这是默认设置。
用法:OK,很有用
proguard-android-optimize.txt 中不包含以下选项:
-mergeinterfacesaggressively
指定可以合并接口,即使它们的实现类没有实现所有接口方法...设置此选项会降低某些 JVM 上已处理代码的性能
用法:BAD,对Android来说看起来很危险,不要包含在配置中,禁止类/合并/优化的总结
-overloadaggressively
指定在混淆时应用积极的重载。然后,多个字段和方法可以获得相同的名称,只要它们的参数和返回类型不同,这是 Java 字节码所要求的(不仅仅是它们的参数,是 Java 语言所要求的)
用法:BAD,Google 的 Dalvik VM 无法处理重载的静态字段。
所以我只知道一个更有用的混淆和非危险选项:
-repackageclasses ''
-repackageclasses ''
指定通过将所有重命名的类文件移动到单个给定包中来重新打包它们。如果没有参数或使用空字符串 (''),则会完全删除包。此选项会覆盖 -flattenpackagehierarchy 选项。
用法:OK,由 Google 使用,所以看起来我们至少找到了可以添加到配置中的选项
另外请注意解码堆栈跟踪。 ProGuard 还会从堆栈跟踪中删除文件名和行号。这使得查找错误变得非常复杂。您可以通过将以下代码添加到配置中来保留行号:
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
这将保留行号,但将堆栈跟踪中的文件名替换为“SourceFile”。
另外不要忘记,ProGuard 看起来很容易受到攻击,因为它不加密字符串资源,因此请考虑使用 DexGuard 或自己加密重要的字符串(如令牌、url)。