提问者:小点点

Android ProGuard:最激进的优化


Android的官方proGuard留档显示了两个主要优化:

  • minifyEn的设置为true
  • 使用progard-android-优化. txt而不是progard-android.txt

这两个是最具侵略性的设置吗?

我正在编写一个android库,需要确保当人们使用我的库时,我的代码不会中断。(我知道我可以在我的库中放置一些规则来对抗使用该库的应用程序上设置的proGuard配置,但如果没有必要,我不想这样做。)


共3个答案

匿名用户

请记住,最好的ProGuard配置-是具有最少异常的配置。在我理解的异常下:

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

让我们浏览progard-android-优化. txt并查看优化/混淆选项。

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

-优化!代码/简化/算术,!代码/简化/铸造,!字段/*,!类/合并/*这-可能优化的列表,!平均否定,所以不使用此优化

-优化传递5指定要执行的优化传递次数。默认情况下,执行一次传递。多次传递可能会导致进一步的改进。如果在优化传递后没有发现任何改进,则优化结束。仅在优化时适用。
用法:确定,看起来默认5次传递就足够了

-会扩展类和类成员的访问修饰符指定在处理过程中可以扩展。这可以改善优化步骤的结果。
用法:确定,是看起来像改善优化

-dontpre验证当针对Android时,不需要预验证,所以dontpre验证关闭它以减少一点流转时长。但是这个选项不会影响代码的牢不可破性。
用法:好的,只是稍微重复一下流转时长

-dontusmixedcaseclassname指定在混淆时不生成混合大小写的类名。默认情况下,混淆的类名可以包含大写字符和小写字符的混合。这创建了完全可接受和可用的罐子。
用法:有问题,我找不到添加此选项的确切原因,但看起来将类名从abcdef更改为AbCdEf并不能使代码牢不可破

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

proard-android-优化. txt不包括以下选项:

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

-overloadgrizy指定在混淆时应用激进重载。然后多个字段和方法可以获得相同的名称,只要它们的参数和返回类型不同,这是Java字节码所要求的(不仅仅是它们的参数,这是Java语言所要求的)
用法:BAD,谷歌的DalvikVM不能处理重载的静态字段。

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

-repackageclass"指定将所有重命名的类文件重新打包,方法是将它们移动到单个给定的包中。如果没有参数或空字符串 (''), 包将被完全删除。此选项覆盖-flattenpackage层次结构选项。
用法:确定,由Google使用,因此看起来我们至少已经找到了可以添加到配置中的选项

另请注意解码堆栈跟踪。ProGuard还会从堆栈跟踪中删除文件名和行号。这使得查找错误非常复杂。您可以通过将以下代码添加到配置中来保留行号:

-renamesourcefileattribute SourceFile 
-keepattributes SourceFile,LineNumberTable

这将保留行号,但将stacktrace中的文件名替换为“SourceFile”。

另外不要忘记ProGuard看起来很容易受到攻击,因为它不会加密字符串资源,因此请考虑使用DexGuard或加密重要字符串(如令牌、url)本身。

匿名用户

根据优化文件中的评论,优化会带来一定的风险,如果使用,应用程序必须经过彻底的测试。根据我的经验,有必要禁用代码/简化/高级,因为这会导致在lambda之外初始化的最终局部变量在lambda内部为NULL。调试和查找非常困难。因此我的优化设置如下:

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

请注意,如果您的目标是Android 2.0及更低版本(这不太可能),则还必须禁用代码/简化/算术。除此之外,我还必须禁用方法/删除/参数和方法/传播/参数,因为它们隐式地启用了代码/简化/高级(有关更多信息,请参阅ProGuard手册)。

匿名用户

在libminecraft 1.15.2 0中,第一个使用新libminecraft先进技术的全程序优化的Minecraft版本,我只使用了gson、内联和代码优化。这样做是为了减轻使用完全优化的潜在不稳定影响。

现在我们有了Minecraft 1.16.2和ProGuard 7.0.0,我使用了完全优化,没有任何稳定性问题(我实际上用Allatori堆叠了ProGuard,仍然没有遇到稳定性问题,因为Allatori比ProGuard做了更好的控制和数据流优化)。

我在libminecraft 1.16.2中运行了三次ProGuard。一次只进行了5次代码优化,一次进行了所有非代码优化,一次只进行了2次代码优化。此外,我使用Allatori进行了最后一次优化,因为它执行了非常高质量的控制和数据流优化。