Android 最新混淆编译器 R8 优化你的安装包

Android 最新混淆编译器 R8 优化你的安装包


为了尽可能减小应用的大小,我们应在发布 build 中启用缩减功能来移除不使用的代码和资源。启用缩减功能后,还会产生另外2项好处:一项是混淆处理功能,该功能会缩短应用的类和成员的名称;另一项是优化功能,该功能会采用更积极的策略来进一步减小应用的大小。

Android 中,通过混淆编译器来实现以上能力,在早起 Android Studio 版本中,混淆编译器使用的是 ProGuard 执行编译时代码优化,当我们使用 Android Gradle 插件 3.4.0 或更高版本构建项目时,该插件不再使用 ProGuard 执行编译时代码优化,而是与 R8 编译器协同工作。

R8 介绍

在 Android studio 3.2.0 中,引入了 R8 编译器,但默认使用的是 ProGuard(默认)。从 Android studio 3.3 开始改用新的代码压缩器 R8。

开发者现在可以在 Android Studio 3.3 Beta 中,让 R8 搭配 Proguard 规则使用。

代码压缩可以移除未使用的代码和资源,以减少APK的容量,让实际代码占用更少的空间。

新的代码压缩器 R8 能够一步到位进行代码压缩、脱糖(Desugaring)以及 Dexing,与之前的代码压缩器 Proguard 相比,不只能降低输出的大小,执行速度也更快了。
在这里插入图片描述

R8 和当前的代码缩减解决方案 Proguard 相比,R8 可以更快地缩减代码,同时改善输出大小。

R8 编译器主要作用

R8 编译器主要作用有:

  • 代码缩减(即摇树优化)从应用及其库依赖项中检测并安全地移除不使用的类、字段、方法和属性(这使其成为了一个对于规避 64k 引用限制非常有用的工具)。例如,如果你仅使用某个库依赖项的少数几个 API,那么缩减功能可以识别应用不使用的库代码并仅从应用中移除这部分代码。
  • 资源缩减:从封装应用中移除不使用的资源,包括应用库依赖项中不使用的资源。此功能可与代码缩减功能结合使用,这样一来,移除不使用的代码后,也可以安全地移除不再引用的所有资源。
  • 优化:检查并重写代码,以进一步减小应用的 DEX 文件的大小。例如,如果 R8 检测到从未采用过给定 if/else 语句的 else {} 分支,则会移除 else {} 分支的代码。
  • 混淆:使用无意义的简短名称重命名类、方法和字段,增加逆向难度,并且缩短类和成员的名称,从而减小 DEX 文件的大小。

启用与禁用 R8

如需启用缩减、混淆处理和优化功能,请在项目级 build.gradle 文件中添加以下代码:

android {
    buildTypes {
        release {
            // Enables code shrinking, obfuscation, and optimization for only
            // your project's release build type.
            minifyEnabled true

            // Enables resource shrinking, which is performed by the
            // Android Gradle plugin.
            shrinkResources true

            // Includes the default ProGuard rules files that are packaged with
            // the Android Gradle plugin. To learn more, go to the section about
            // R8 configuration files.
            proguardFiles getDefaultProguardFile(
                    'proguard-android-optimize.txt'),
                    'proguard-rules.pro'
        }
    }
    ...
}

如果需要修正 Android Gradle Plugin 的默认行为,可以在gradle.properties中添加配置:

# 显式启用 R8
android.enableR8 = true
# 只对 Android Library module 停用 R8 编译器
android.enableR8.libraries = false
# 对所有 module 停用 R8 编译器
android.enableR8 = false

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

android.enableR8.fullMode=true

代码缩减

如果将 minifyEnabled 属性设为 true,系统会默认启用 R8 代码缩减功能。

代码缩减(也称为“摇树优化”)是指移除 R8 确定在运行时不需要的代码的过程。此过程可以大大减小应用的大小,例如,当我们的应用包含许多库依赖项,但只使用它们的一小部分功能时。

为了缩减应用的代码,R8 首先会根据组合的配置文件集确定应用代码的所有入口点。这些入口点包括 Android 平台可用来打开应用的 Activity 或服务的所有类。从每个入口点开始,R8 会检查应用的代码来构建一张图表,列出应用在运行时可能会访问的所有方法、成员变量和其他类。系统会将与该图表没有关联的代码视为执行不到的代码,并可能会从应用中移除该代码。

下图显示了一个具有运行时库依赖项的应用。R8 通过检查应用的代码,确定可以从 MainActivity.class 入口点执行到的 foo()、faz() 和 bar() 方法。不过,你的应用从未在运行时使用过 OkayApi.class 类或其 baz() 方法,因此 R8 会在缩减应用时移除该代码。

在这里插入图片描述

R8 通过项目的 R8 配置文件中的 -keep 规则确定入口点。也就是说,保留规则指定 R8 在缩减应用时不应舍弃的类,R8 将这些类视为应用的可能入口点。Android Gradle 插件和 AAPT2 会自动为你生成大多数应用项目(如应用的 Activity、视图和服务)所需的保留规则。

自定义要保留的代码

在大多数情况下,如要让 R8 仅移除不使用的代码,使用默认的 ProGuard 规则文件 (proguard-android- optimize.txt) 就已足够。不过,在某些情况下,R8 很难做出正确判断,因而可能会移除应用实际上需要的代码。下面列举了几个示例,说明它在什么情况下可能会错误地移除代码:

  • 当应用通过 Java 原生接口 (JNI) 调用方法时
  • 当应用在运行时查询代码时(如使用反射)

这时,我们就需要强制 R8 保留某些代码,可以在 ProGuard 规则文件中添加 -keep 代码行。例如:

-keep public class MyClass

或者,我们也可以为要保留的代码添加 @Keep 注解。在类上添加 @Keep 可按原样保留整个类。在方法或字段上添加该注释,将使该方法/字段(及其名称)以及类名称保持不变。请注意,只有在使用 AndroidX 注解库且你添加 Android Gradle 插件随附的 ProGuard 规则文件时,此注解才可用。

输出

启用R8构建项目后会在模块下的 build\outputs\mapping\release 文件夹下输出下列文件:

  • dump.txt:说明 APK 中所有类文件的内部结构。
  • mapping.txt:提供原始与混淆过的类、方法和字段名称之间的转换。
  • seeds.txt:列出未进行混淆的类和成员。
  • usage.txt:列出从 APK 移除的代码。

**PS:更多精彩内容,请查看 --> 《Android 性能优化》
**PS:更多精彩内容,请查看 --> 《Android 性能优化》
**PS:更多精彩内容,请查看 --> 《Android 性能优化》

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卜大爷

觉得不错的可以给我加油哦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值