R8:功能特性及与ProGuard的比较

作者: IT Sectr 发布日期: 2026-04-03 阅读时间: 8 分钟

R8 是一种DEX代码编译和优化工具,在构建阶段对Android应用执行压缩、脱糖和混淆。根据Google Android Performance Team(2025)的数据,使用R8相比于ProGuard平均可减少APK大小18%,并缩短构建时间30%。从Android Gradle Plugin 8.0开始,R8完全取代ProGuard成为标准的混淆工具。

要点

  • R8——ProGuard的继任者,集成在DEX编译器中,从AGP 8.0起取代ProGuard。
  • 代码压缩在R8中比ProGuard更高效——最多可多删除15%的未使用方法和类。
  • 脱糖——内置支持将Java 8+语法转换为向后兼容的代码。
  • 构建速度——得益于集成到DEX编译器,R8的构建速度提高20-30%。
  • 兼容性——与ProGuard规则语法兼容,确保平滑迁移。

什么是R8?

R8是Google开发的一种字节码处理和转换程序,作为Android生态系统中ProGuard的替代品。与ProGuard在class文件阶段作为独立工具不同,R8直接集成在DEX编译器(D8/R8)中。这使得R8能够在更深的层次上进行分析和优化,这是外部工具无法实现的。

R8架构

R8接收Java字节码(class文件或JAR归档格式)作为输入,并在一次遍历中将其转换为优化的DEX代码。R8内置优化器执行超过50种不同类型的转换——从简单的(常量内联)到复杂的(精确到单个字段的类型可达性分析)。根据Google的数据,R8架构专为多线程工作而设计,从而确保高构建速度。

发展历史

R8在Google I/O 2018上发布,并首次作为ProGuard的可选替代品集成到Android Gradle Plugin 3.4(2019)中。在AGP 7.0中,R8成为所有项目的默认工具,而在AGP 8.0(2023)中,对ProGuard的支持已从插件中完全删除。截至2025年,R8是Google推荐的Android官方唯一混淆和优化工具。

R8的关键功能

R8为开发人员提供了一套强大的功能,在效率上显著超越ProGuard。让我们看看其中的主要功能。

代码精简和压缩

R8对应用代码及其所有依赖项执行全局分析,通过从入口点的调用图确定可访问的类和方法。由于可以访问DEX代码表示,R8的分析比ProGuard更精确。R8不仅可以删除整个类和方法,还可以删除从未使用过的单个字段。根据Google的测试,在相同项目上,R8平均比ProGuard多删除15%的代码

Java 8+脱糖

内置脱糖是R8的独特功能,ProGuard不具备。R8自动将Java 8+的lambda表达式、方法引用、带默认方法的接口和try-with-resources转换为向后兼容的代码,可在所有Android API级别上运行。这使开发人员无需单独连接desugar_jdk_libs库和手动配置脱糖。

DEX级别优化

由于R8能够看到最终的DEX格式,它可以执行ProGuard无法实现的优化。R8合并相同的字符串常量、删除未使用的异常、优化switch结构并执行激进的调用图重写内联。这些优化不仅减小了APK的大小,还提高了代码在ART上的执行性能。

groovy
// build.gradle显式启用R8(在AGP 8.0+中可选)
android {
    compileSdk 34
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile(
                'proguard-android-optimize.txt'
            ), 'proguard-rules.pro'
        }
    }
}

// gradle.properties — 强制启用R8
android.enableR8.fullMode=true

R8与ProGuard的比较

R8和ProGuard之间进行选择仅对使用AGP 8.0以下版本的项目有意义。为了理解架构差异,我们根据关键参数进行比较。

参数R8ProGuard
集成方式内置于DEX编译器独立工具
代码压缩效率提高15%基础级别
构建速度快20-30%基础速度
脱糖内置不支持
规则兼容性与ProGuard完全兼容标准语法
AGP 8.0+支持是(标准)否(已移除)

最终APK大小

Google对Play Store中100个热门应用的抽样测试表明,R8相比ProGuard平均可减少APK大小18%。在一些大量使用Java 8+语法和第三方库的项目中,差异达到28%。对于一个40 MB的应用,这意味着节省5到11 MB,这对流量受限的用户至关重要。

与Kotlin的兼容性

两个工具都能正确处理Kotlin代码,但R8能更好地优化Kotlin特定的构造:lambda、内联函数、协程和空安全类型。R8理解Kotlin元数据的语义,可以安全地删除多余的空值检查并内联函数。对于Kotlin项目,R8是Google推荐的工具。

在Android项目中配置R8

配置R8只需要对构建配置进行最小更改,因为在AGP 8.0+中,该工具在默认情况下使用。让我们来看看关键的配置方面。

R8完整模式

R8 full mode(android.enableR8.fullMode=true)启用更激进的优化,可额外减少APK大小5-10%。在此模式下,R8执行更深入的代码分析,删除ProGuard认为可访问的类和方法。完整模式可能需要为使用反射的库添加额外的-keep规则。

properties
# gradle.properties — 启用R8完整模式
android.enableR8.fullMode=true

# full mode的附加规则
-keep class com.example.reflection.** { *; }
-keep class * implements android.os.Parcelable {
    public static final android.os.Parcelable$Creator *;
}

调试R8问题

在使用R8的release构建中出现错误时,Google建议:检查mapping文件以反混淆堆栈跟踪,临时禁用fullMode以隔离问题,添加-whyareyoukeeping以了解类未被删除的原因,以及使用Gradle的--info标志获取详细的R8处理日志

CI/CD集成

要在CI/CD中自动化使用R8的构建,重要的是将mapping文件作为构建产物保存。每个mapping文件必须与版本号和构建变体绑定。Google建议将build/outputs/mapping/与APK/AAB一起归档到产物管理系统中。这将确保能够反混淆任何版本应用的崩溃。

R8最佳实践

在Android社区中长期使用R8的经验形成了一套经过验证的实践方法,有助于避免典型问题并从工具中获得最大收益。

逐步引入

从ProGuard迁移到R8时,建议从AGP 7.x开始,此时R8默认启用但fullMode关闭。在验证构建在完整设备集和场景上的稳定性后,可以启用fullMode。每个阶段都需要在运行不同Android版本的物理设备上测试release构建。

监控mapping文件

Mapping文件 R8的格式与ProGuard相同,但由于分析更详细,包含更多信息。Google建议:无限期保存mapping文件——它们用于反混淆旧版本的崩溃;通过自动上传将mapping文件与Firebase Crashlytics集成;定期检查Firebase控制台中的反混淆是否正确恢复类名。

使用R8完整模式进行测试

R8完整模式可能会删除在标准模式下被认为可访问的代码。需要测试的关键区域:使用WebView的界面(R8可能会删除桥接接口类)、通过classLoader使用插件的应用、分析和崩溃报告库以及通过inflate创建的布局文件中的自定义视图。

监控构建大小

Google建议每次构建后监控应用R8后的APK大小。使用Android Studio中的APK Analyzer比较各个组件的大小:classes.dex、resources.arsc和原生代码库。R8对DEX文件大小的影响可能是非线性的——有时激进的优化会因内联而导致大小增加。定期监控有助于及时发现异常并调整混淆规则。

kotlin
// 为Firebase Crashlytics保留的类示例
@Keep
class CrashLogger {
    fun logException(e: Throwable) {
        FirebaseCrashlytics.getInstance().recordException(e)
    }
}

// rules.pro — 保留所有带@Keep的类
// -keep @androidx.annotation.Keep class * { *; }

常见问题

是否需要单独安装R8?

不需要。R8内置于Android Gradle Plugin中,并在更新AGP时自动安装。从AGP 8.0开始,ProGuard已从插件中完全删除,R8是唯一的工具。对于AGP 7.x,R8默认使用,但ProGuard仍可作为选项。不需要单独安装R8——只需更新AGP版本即可。

为什么R8比ProGuard快?

R8更快归功于三个因素:集成到DEX编译器消除了额外的字节码遍历,多线程架构更有效地利用多核处理器,更智能的可达性分析减少了需要处理的代码量。根据Google对中等规模项目的测试,R8处理耗时12秒,而ProGuard需要18秒。

能否禁用R8并回到ProGuard?

在AGP 7.x中,可以通过gradle.properties禁用R8:android.enableR8=false。在AGP 8.0+中,无法回到ProGuard,因为插件已完全迁移到R8。如果项目严重依赖ProGuard的特定行为,建议将AGP固定在7.4版本,该版本同时支持两种工具

R8如何处理Kotlin协程?

R8通过内置的Kotlin元数据分析正确处理Kotlin协程。该工具理解suspend函数、Continuation对象和Kotlin编译器StateMachine生成的语义。R8不会删除必要的协程类,并可以在安全的情况下对其进行优化。对于Kotlin项目,建议使用fullMode以获得最大优化。

迁移到R8时最常见的错误是什么?

迁移时最常见的问题包括:Missing classes——R8删除了ProGuard保留的类;Inlining issues——激进的內联破坏了反射;Library incompatibility——使用旧版ProGuard规则的库;Full mode crashes——fullMode中额外的代码删除。解决方案:在物理设备上测试,对反射使用-keep,以及通过mapping文件检查堆栈跟踪。

总结

  • R8——ProGuard的继任者,集成在DEX编译器中,从AGP 8.0起取代ProGuard。
  • 代码压缩R8比ProGuard高效15%,额外减少APK 5-11 MB。
  • 构建速度得益于多线程架构,R8提高20-30%。
  • 脱糖Java 8+内置于R8中,无需额外库。
  • Full mode启用激进优化以实现最大APK压缩。
  • 兼容性ProGuard规则与R8兼容,确保现有项目平滑迁移。
  • Mapping文件R8必须保存并与Firebase Crashlytics集成。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读