Proguard 优化设置:在现代 API 和 Proguard 版本中启用类合并、强制转换和字段/*



我已经混淆我的应用程序很长时间了,以下设置我像口头禅一样,因为它们是谷歌的推荐

-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*

但是,前几天我错误地评论了这一行,该应用程序构建正确,并且"显然"可以工作。我做了很多测试,但无法让它崩溃。

所以我想知道是否需要那些禁用的优化设置......

  • 从今天的Android SDK和最新的Proguard版本开始,我只针对Android 4.0.3(15)以上的设备,并使用Proguard 5.1。
  • 以及不做异国情调的东西并且有正确编写的proguard.cfg指示保留相关有问题的类等的应用程序。

这里与这个问题相关的大多数答案都有相互矛盾的信息,并且与相当旧的 API 版本有关。

一个接一个:

!代码/简化/算术

我在谷歌网上论坛上发现了一个讨论,他们说Android甜甜圈之后的SDK不需要simplification/arithmethic。我假设,我可以安全地启用此优化。

!类/合并/*

看起来 proguard 在我的项目中做得很好,打开了这个优化:

[proguard]   Number of vertically merged classes:         296
[proguard]   Number of horizontally merged classes:       445

除了堆栈跟踪不正确之外,还有其他副作用吗?我的意思是,副作用与应用程序崩溃有关,而不是与调试问题有关。我发现了这个相关的问题,但它并没有得出结论,它是否安全。

!field/* 和 !code/簡化/投射

我在ProGuard的作者回答的这个问题中读到,包括这些是为了避免旧Proguard版本的错误。那么在Proguard 5.1上激活它们是否安全?

一般建议:不能保证优化不起作用,但始终存在风险。默认的 Android 专业保护设置试图做的是提供一种将风险降至最低的配置,因此它们在您的具体情况下显得如此保守。

启用这些优化只是意味着,如果某些内容崩溃,您无法确定根本原因。通常,proguard 步骤对输出相对于输入的保证不太强,这是程序中非确定性的来源。代码中的微小更改可能会导致运行时行为发生显著不同的更改,并且在实际运行程序之前无法知道,具体取决于您的配置。

总之,如果您可以运行APK,并且一切正常 - 那就太好了,优化对您有用。但是,他们不能保证。

那么在 Proguard [5.1] 上激活它们是否安全?

这是一个高风险的举动,我可以给你一个例子,它会导致问题。

我们正在使用 ProGuard 5.2.1,并且在重新启用field/*优化时遇到了一个错误(更具体地说,field/removal/writeonly似乎是导致问题的)。我们的代码使用 protobuf,启用该优化会导致 ProGuard 在第三次优化时失败并显示以下消息:

优化。。。 评估指令时出现意外错误:  Class = [com/google/protobuf/FieldSet$1]  方法 = [()V]  指令 = [308] isub  Exception = [java.lang.IllegalArgumentException] (值 "com/google/protobuf/WireFormat$JavaType!" 不是整数值 [proguard.evaluation.value.TypedReferenceValue])执行部分评估时出现意外错误:  Class = [com/google/protobuf/FieldSet$1]  方法 = [()V]  Exception = [java.lang.IllegalArgumentException] (值 "com/google/protobuf/WireFormat$JavaType!" 不是整数值 [proguard.evaluation.value.TypedReferenceValue])警告:处理任务时出现异常 java.io.IOException: java.lang.IllegalArgumentException: 值 "com/google/protobuf/WireFormat$JavaType!" 不是整数值 [proguard.evaluation.value.TypedReferenceValue]

也就是说,这些优化已被禁用这么多年的事实意味着它们可能没有像其他优化那样得到很好的维护。幸运的是,这是在编译时捕获的,但是重新启用其中一些优化(例如,通过class/merging/*水平合并类)可能会很容易在某些版本的Android中破坏您的应用程序,而不会正确报告给您"开发人员"(例如,它可能会使dexopts崩溃或无法与VerifyError一起完全安装)。

最新更新