虽然 Unity 中的核心游戏逻辑是用 C# 编写的(使用 IL2CPP 编译),但 Android build 包含大量 Java 和 Kotlin 字节码 (classes.dex),用于处理 UnityPlayerActivity 生命周期事件、Google Play 服务、结算、广告和社交 SDK。
启用 R8(Android Gradle 插件 [AGP] 中的默认代码缩减器和优化器)可移除未使用的类和方法,并优化字节码。这不仅可以缩减应用下载大小,还可以减少内存映射 (mmap) DEX 页面和基准 Java 进程开销的运行时内存占用,从而缓解物理内存压力并减少低内存终止守护程序 (LMK) 终止。Google Play 还会通过 Android Vitals 中的 DEX 代码优化指标监控游戏的 DEX 优化级别。
默认行为和 Unity 版本支持
在 Unity 中,创建新项目时,发布 build 和调试 build 的代码缩减功能默认处于停用状态 (false)。
Unity 首次在 Unity 2020.1.0f1 中引入了 R8 作为可选切换开关。 从 Unity 2022.2.0f1(并向后移植到 Unity 2021.3.41f1 LTS)开始,Unity 将其捆绑的工具链升级到了 AGP 7.1.2+,移除了旧版 ProGuard 支持,并且只要启用了缩减大小功能,就会专门运行 R8。
| Unity 版本 | 捆绑式 AGP | 默认版本 | R8 支持和所需配置 |
|---|---|---|---|
| 2019.4 LTS 及更早版本 | 早于 3.4 | 已停用 (false) |
不支持(仅限旧版 ProGuard)。 |
| 2020.1.0f1 至 2021.3.40f1 | 3.4 到 4.0 | 已停用 (false) |
可选(默认为 ProGuard)。同时启用 Minify > Release 和 Use R8。 |
| 2021.3.41f1 及更高版本 (2021 LTS) | 7.1+ | 已停用 (false) |
仅限 R8。启用缩减大小 > 发布,以自动运行 R8。 |
| 2022.2.0f1 至 Unity 6+ | 7.1 至 8.x | 已停用 (false) |
仅限 R8。启用缩减大小 > 发布,以自动运行 R8。 |
在 Player Settings 中启用 R8
如需为发布 build 启用 R8 代码缩减和优化功能,请执行以下操作:
- 在 Unity 编辑器中,依次打开 Edit(修改)> Project Settings(项目设置),然后选择 Player(播放器)。
- 选择 Android 标签页,然后展开发布设置 > 构建。
- 在 Minify 部分下,根据您的 Unity 版本配置选项:
- Unity 2021.3.41f1+ 和 2022.2.0f1+:选择 Release。Unity 会在
minifyReleaseWithR8Gradle 任务期间自动运行 R8。 - Unity 2020.1.0f1 至 2021.3.40f1:同时选择 Release 和 Use R8。
- Unity 2021.3.41f1+ 和 2022.2.0f1+:选择 Release。Unity 会在
如果您使用 C# 编辑器脚本自动执行 build,请通过 PlayerSettings.Android 配置这些属性:
using UnityEditor;
public static class AndroidBuildConfig
{
public static void EnableR8ForRelease()
{
PlayerSettings.Android.minifyRelease = true;
// Required only in Unity 2020.1.0f1 to 2021.3.40f1 and 2022.1 or earlier
// (In Unity 2021.3.41f1+ and 2022.2+, R8 is always used when minification is enabled)
#if !UNITY_2022_2_OR_NEWER
PlayerSettings.Android.minifyWithR8 = true;
#endif
}
}
为 JNI 和反射添加保留规则
使用 AndroidJavaClass 或 AndroidJavaObject 从 C# 脚本动态调用的 Java 类和方法没有静态 Java 调用网站。如果没有明确的保留规则,R8 可能会认为这些类未被使用,并将其剥离或重命名。
如需保留自定义 Java 桥,请执行以下操作:
- 在 Project Settings(项目设置)> Player(可执行游戏文件)> Android > Publishing Settings(发布设置)> Build(构建)中,启用 Custom Proguard File(自定义 Proguard 文件)。
- 打开生成的
Assets/Plugins/Android/proguard-user.txt文件。 - 为通过 JNI 访问的类或第三方插件所需的类添加
-keep规则:
# Keep custom Java classes invoked from C# using JNI bridges
-keep class com.example.yourgame.** { *; }
# Keep callback interfaces passed between C# and Java
-keep interface com.example.yourgame.IPluginCallback { *; }
排查常见问题
本部分介绍了如何解决在 Unity 中使用 R8 时遇到的常见构建和运行时问题。
Missing classes detected while running R8 个构建错误
在使用 AGP 7.0 及更高版本(2021.3.41f1+ 和 2022.2+)的 Unity 版本中,R8 会强制执行严格的缺失类检查。如果 build 失败并显示此错误,请检查 build 输出目录(位于 Library/Bee/Android/Prj/.../build/outputs/mapping/release/missing_rules.txt 或 Temp/gradleOut/... 下)中生成的 missing_rules.txt 文件,并将所需的依赖项或规则添加到 proguard-user.txt。如需详细了解如何编写保留规则,请参阅自定义要保留的代码。
R8 完整模式与第三方插件的兼容性
在 AGP 8.0 及更高版本 (Unity 6+) 中,R8 完整模式默认处于启用状态,以执行更积极的优化。如果旧版 Android 插件在运行时因反射问题而失败,请更新插件的 ProGuard 规则或将 R8 还原为兼容模式:
- 在 Publishing Settings(发布设置)> Build(构建)中,启用 Custom Gradle Properties Template。
- 打开
Assets/Plugins/Android/gradleTemplate.properties并添加以下属性:
android.enableR8.fullMode=false