Android代码压缩工具R8详解 android.enableR8=true

15,971 阅读3分钟

前言

最近 Android Studio 稳定版迎来了3.3版本更新,带来的新特性之一是新一代的代码压缩工具 R8,本文将详细介绍这一新工具 R8。阅读本文内容前需了解:

关于 R8

作为 Android 开发者,大家都知道缩减 APK 的大小是每个项目都需要面临的重要工作,而代码缩减有助于通过移除未使用的代码和资源来减少 APK 的大小,并使实际代码占用更少的空间(也称为混淆),所以 R8 这一项工具的目的是让代码缩减过程更快和更有效率。R8 目前已开源:

R8 工具出现的背景和历史

我们开发者使用 Java 或者是 Kotlin 来编写程序代码,然后转换为 Android 设备所需要的 Dalvik 字节码(.dex),整个过程可以简单的用下图来表示:

传统的 Java 编译器将源代码编译为 Java 字节码(.class)ProGuard 可以选择优化此代码,从而生成更小,更快的 Java 字节码。 dx 编译器最终可以将此 Java 字节码转换为 Dalvik 字节码(.dex)。 Dalvik 字节码打包在 apk 文件中,最终安装在设备上。 根据 Android 的版本,字节码被及时(Dalvik VM),提前(ART)或两者的组合(Android P)解释、编译。 许多 Android 设备在处理能力,内存和带宽方面存在许多限制因素,因此即使在当前,字节码的大小和效率仍然很重要。 ProGuard 通常将字节码大小减少20-50%,并将字节码性能提高多达20%

对于开发者来说,构建过程的性能是非常重要的,因此在2015年,谷歌 Android 团队引入了编译器 Jack 和 Jill 。他们只需一步即可集成 Java 编译器、ProGuard 和 Dalvik 编译器的功能:

它极大地简化了构建过程,但对于使用 Java 字节码的语言和工具的生态系统并没有起到很好的作用。 Android 团队在2017年放弃了它。使用新的 D8 编译器,他们退后一步,只需用新的实现替换 dx 编译器:
整个过程变得更加的温和并适应外部工具,它仍然适应 Kotlin 语言。此外,D8 已经产生比 dx 更好的字节码,具有更少的指令和更好的寄存器分配。

这仍然为优化构建过程留下了空间,R8 是 D8 的衍生产品,旨在集成 ProGuard 和 D8 的功能

R8 和 Proguard

R8 一步到位地完成了所有的缩减(shrinking),去糖(desugaring)和 转换成 Dalvik 字节码(dexing )过程。

缩减(shrinking)过程实现以下三个重要的功能:

  • 压缩:从代码中移除无用的类、段、方法等。
  • 优化:使代码在指令级更小,更高效。
  • 混淆:使用简短无意义的名称重命名代码里剩余的类,字段和方法。

R8 和当前的代码缩减解决方案 Proguard 相比,R8 可以更快地缩减代码,同时改善输出大小。下面将通过几张数据图来对比(数据源自于 benchmark):

数据源自于 benchmark

如何使用 R8

R8 使用的方式非常简单,Android Studio 升级到3.3及以上版本后,只需在项目的 gradle.properties 里加上:

android.enableR8=true

R8 普通模式是兼容 Proguard的,若原项目里已使用了proguard,直接启用 R8 即可。同时,R8 也有完全模式,与Proguard不直接兼容。可以在 gradle.properties 文件中另外设置以下内容:

android.enableR8.fullMode=true

本文为个人原创,转载请注明出处。