环境配置:在 Android Studio 中启用 R8 和 ProGuard

很多新手第一件事就是问:「我该从哪里开始?」

其实很简单。你不需要装什么额外工具。R8 和 ProGuard 都集成在 Android Gradle 插件里。说白了,改几行 gradle 配置就行。

我刚开始带团队的时候,有个同事把混淆规则写在了 debug 变体里,结果每次调试都崩溃。嗯,这里要注意:位置很重要。

一句话总结:所有配置都在 app/build.gradle 或 build.gradle.kts 里完成。

Gradle 配置详解

我们来看具体的配置入口。无论是 Groovy 还是 Kotlin DSL,核心逻辑一模一样。

// app/build.gradle
android {
    buildTypes {
        release {
            // 启用代码混淆、压缩和优化
            minifyEnabled true
            // 指定 ProGuard 混淆规则文件
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
                    'proguard-rules.pro'
            // 启用资源压缩(必须与 minifyEnabled 配合)
            shrinkResources true
        }
        debug {
            // 调试版本通常不开启,但我也见过有人开
            minifyEnabled false
        }
    }
}

这段配置我看过不下几百次。但有个细节很多人会忽略:proguardFiles 的顺序是有讲究的。

先加载默认规则文件,再加载你自己的规则。如果你把顺序写反,默认规则可能会覆盖你的自定义配置。我在项目中遇到过这个坑,排查了整整一下午。

我的习惯:在 proguard-rules.pro 文件里加个注释头 —— 写上日期和修改人。团队协作时这个习惯能省不少扯皮的时间。

R8 与 ProGuard:启用方式对比

很多人以为「启用混淆 = 用 ProGuard」。其实在 AGP 3.4.0 之后,默认编译器已经换成 R8 了。

为什么要换?因为 R8 更快、更智能。它能做全量优化,而 ProGuard 只是个混淆器。

特性 ProGuard R8
默认启用 否(AGP 3.4.0 前) 是(AGP 3.4.0+)
混淆能力 强 更强(含全量优化)
编译速度 较慢 快 2~3 倍
支持 Kotlin 需额外配置 原生支持
兼容性降级 — 可通过 gradle.properties 关闭

但你想想看,如果项目中某个第三方库只兼容 ProGuard,怎么办?

别急。AGP 留了个后门。

// gradle.properties
# 强制降级到 ProGuard
android.enableR8=false
# 或者仅关闭 R8 的完整模式
android.enableR8.fullMode=false
我曾经在项目中犯过这个错:直接全局关闭 R8。结果导致包体积增加了 30%。如果你只是想绕过某个库的兼容问题,建议只针对那个库写 keep 规则,而不是一刀切。

启用步骤(实战流程)

好,我们一步步来。我习惯按这个顺序操作:

  1. 打开 app/build.gradle — 找到 buildTypes.release
  2. 设置 minifyEnabled = true — 这是混淆开关
  3. 配置 proguardFiles — 引用默认规则 + 自定义规则文件
  4. 可选:启用 shrinkResources — 删除无用资源
  5. 生成 release 包 — 用 Build → Generate Signed Bundle / APK
  6. 检查 mapping 文件 — 路径在 app/build/outputs/mapping/release/mapping.txt

如果你用的是 Kotlin DSL,配置稍微有点不同。不过我个人觉得 Kotlin DSL 写起来更清爽:

// app/build.gradle.kts
android {
    buildTypes {
        getByName("release") {
            isMinifyEnabled = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
            isShrinkResources = true
        }
    }
}
检查清单:
  • release 构建是否启用了 minifyEnabled
  • proguardFiles 中是否包含了自定义规则文件
  • shrinkResources 是否与 minifyEnabled 配对出现
  • mapping.txt 文件是否正常生成

从 ProGuard 迁移到 R8

如果你是老项目,还在用 ProGuard,我建议你尽快迁移。步骤很简单:

  1. 把 android.enableR8=false 从 gradle.properties 里删掉
  2. 删掉项目中冗余的 ProGuard 规则(R8 能兼容大部分)
  3. 运行一次 release 构建,看有没有告警
  4. 查看生成的 mapping.txt,确认混淆效果

我在迁移过程中遇到过一个问题:某个第三方库用了 -keepclassmembers 写法,R8 报告了 warning。但只要加一行 -dontwarn 就能解决。很简单。

建议:迁移时先用 --info 级别日志跑一次构建。R8 会输出很详细的压缩和混淆日志,能帮你定位问题。

SVG:R8 & ProGuard 配置决策流程图

R8 与 ProGuard 配置决策流程图 R8 / ProGuard 配置决策流程 Android Studio 项目 release 构建? 是 否 跳过混淆(debug) 开启 minifyEnabled 配置 proguardFiles 选择 R8 / ProGuard 💡 说明: 默认使用 R8;如需降级到 ProGuard, 在 gradle.properties 中设置 android.enableR8=false

常见陷阱与避坑指南

配置环境这件事看起来简单,但实际踩坑的人不少。我列几个典型问题:

我曾经遇到过一个线上事故:项目里用了 @Keep 注解,但忘了在 proguard-rules.pro 里 keep 这个注解本身的类。结果 release 包启动就崩。原因是 R8 把注解类给干掉了。
  • minifyEnabled 写在 debug 里:调试时混淆,断点都定位不准。建议只写在 release 里。
  • 忘加 shrinkResources:资源文件没有被压缩,包体积没降下来。它俩必须配对使用。
  • proguardFiles 顺序写反:自定义规则被默认规则覆盖。先默认,后自定义。
  • 使用了第三方库但没 keep 规则:运行时反射失败。解决方法:在 proguard-rules.pro 里加 -keep class com.thirdparty.** { *; }
一个小技巧:每次修改混淆规则后,用 ./gradlew assembleRelease --stacktrace 构建一次。看到 BUILD SUCCESSFUL 再继续开发。别攒一堆问题到最后才排查。

配置好了环境,下一步就是真正开始写混淆规则了。你会发现,大部分问题不是出在「配不配」,而是出在「规则怎么写」。