【问题标题】:What really R8 full mode do (aggressive optimizations)?R8 完整模式的真正作用是什么(积极优化)?
【发布时间】:2020-03-02 17:29:09
【问题描述】:

R8 official documentation 表示要激活其他优化,我必须将其插入gradle.properties 文件中:

android.enableR8.fullMode=true

文档说,为了使应用程序工作,我必须设置一些保留规则,但没有关于它如何工作以及它执行什么操作的详细信息:

因为额外的优化使 R8 的行为不同于 ProGuard,他们可能会要求您包含额外的 ProGuard 规则以 避免运行时问题。例如,假设您的代码引用了 通过 Java 反射 API 类。默认情况下,R8 假定您 打算在运行时检查和操作该类的对象——甚至 如果你的代码实际上没有——它会自动保留类和 它的静态初始化器。

但是,当使用“完整模式”时,R8 不会做出此假设,并且, 如果 R8 断言您的代码否则永远不会使用该类 运行时,它会从应用程序的最终 DEX 中删除该类。也就是说,如果 你想保留类和它的静态初始化器,你需要 在你的规则文件中包含一个保留规则来做到这一点。

文档建议的常见问题解答中的link 仅说明了这一点:

R8 完整模式

在完整模式下,R8 表现更激进 优化,这意味着额外的 ProGuard 配置规则 可能需要。本节重点介绍了一些常见问题 使用完整模式时可见。

android.enableR8.fullMode 究竟是如何工作的?

非常感谢!

【问题讨论】:

  • 不确定really works,但您发布的示例很清楚,运行时无法访问的代码(显式代码)将被删除,因此如果您执行Reflection API,则必须添加keep class 和@ 987654329@ 只能通过其他方式访问课程。最好的测试是激活它并测试您的应用。
  • @MarcosVasconcelos 这是它的一个例子,但我认为关于它的工作原理和作用的信息太少很奇怪。另外,我可以在激活后测试我的应用程序,但我已经对我的应用程序进行了深入测试,如果我在测试我的应用程序之前知道硬件 R8 可以工作,我可以节省大量时间,而不是测试我的整个应用程序以寻找“可能”的错误由于 R8

标签: android optimization obfuscation shrink android-r8


【解决方案1】:

确实缺少完整模式的文档。目前主要包括以下内容:

  • 不要为保留的类型保留默认构造函数 (<init>()),除非根本没有保留 <init> 方法,在这种情况下,将保留默认构造函数 (<init>())
  • 不要为仅用于强制类型转换(checkcast 字节码)的类型保留默认构造函数 (<init>())
  • 不要为仅与 instanceof 一起使用的类型保留默认构造函数 (<init>())(instanceof 字节码)
  • 不要保留目标(但不是实时)默认方法的代码,将它们抽象化
  • 不要在层次结构中保留所有直接方法(只保留完全匹配的方法)
  • 即使指定了-keepattributes,也可以为保留规则不匹配的类型保留较少的属性。目前主要针对与内/外关系相关的属性(InnerClassEnclosingMethod)。

这是主要区别,但可能还有更多区别。我们正在努力添加更具体的文档,但这仍然是一个移动的目标。

注意,如果程序的保持规则是完整的,反射使用的所有内容都被保持规则覆盖,那么打开android.enableR8.fullMode 不会导致问题。但是,我们经常看到配置,Proguard 的这些(也未记录)约定使配置工作。

【讨论】:

  • 你说“我们正在努力”也许可以说你代表哪一方
  • 我代表 R8 作者。
  • @sgjesse 你好。对我来说,R8 完整模式使用 gson 中断,它缩小了默认构造函数,并且 gson 无法在没有为每种类型显式 InstanceCreator 的情况下创建实例。这里最好的解决方案是什么?谢谢
  • 请看一下R8 compatibility FAQ。它有一个关于 GSON 的部分,包括使用完整模式的 GSON。希望能有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-11
  • 2010-10-30
  • 2021-02-17
  • 1970-01-01
  • 1970-01-01
  • 2013-02-23
  • 1970-01-01
相关资源
最近更新 更多