第 3 章:Gradle 配置 Baseline Profile:集成 profile 插件、生成基线文件、配置 consumerProguardFiles、多 flavor 支持
3.1 原理:Baseline Profile 与 Gradle 构建生命周期的集成
Baseline Profile 的生成不是在运行时由开发者手动触发的,而是深度嵌入在 Gradle 构建流程中。Android Gradle Plugin(AGP)从 7.2+ 开始内置了对 Baseline Profile 的原生支持,通过 androidx.profileinstaller 的 profileplugin 或 AGP 自带的 profile 配置块,可以将开发者编写的 profile 规则(HRule 定义的热点类/方法)在构建期转换为二进制基线文件 baseline.prof,并打包进 APK/AAB 的 assets/dexopt/baseline.prof 路径。当设备首次安装应用时,系统 PackageManager 会根据此文件执行 AOT 编译,将热点方法预编译为机器码,从而大幅缩短冷启动时间。
collectBaselineProfile)→ 生成 baseline.prof → 通过 consumerProguardFiles 或 build.gradle 配置纳入 APK → 安装时触发 AOT 编译。3.2 集成 Profile 插件
在项目级 build.gradle 引入 androidx.navigation.safeargs 或直接使用 AGP 内置 profile 支持。推荐使用 AGP 7.3+ 的 profile 配置块,无需额外插件。若需要更精细的控制(如多 flavor 合并规则),可添加 androidx.baselineprofile Gradle 插件:
// 项目级 build.gradle
buildscript {
dependencies {
classpath "androidx.baselineprofile:baselineprofile-gradle-plugin:1.2.3"
}
}
// 应用级 build.gradle
plugins {
id 'com.android.application'
id 'androidx.baselineprofile' // 仅当使用独立插件时
}
android {
// Android 配置块...
}
若使用 AGP 7.2+,可直接在 android 块中配置 profile:
android {
buildTypes {
release {
profile {
// 启用基线 profile 生成
enabled true
// 指定 profile 规则文件(可选)
rules files("my-profile-rules.txt")
}
}
}
}
3.3 生成基线文件:profile 规则与输出
profile 规则文件通常以 .txt 或 .prof 格式编写,使用 Human-Readable Rule (HRule) 语法定义需要预编译的类和方法:
// my-profile-rules.txt
[HSP]com/example/app/MainActivity
[HSP]com/example/app/SplashActivity
[HSP]com/example/app/HomeFragment
[HSP]com/example/app/data/repository/UserRepository
[HSP]com/example/app/util/DateUtils#formatDate
[SP]com/example/app/network/ApiService
规则前缀含义:
| 前缀 | 含义 | AOT 编译策略 |
|---|---|---|
[HSP] | Hot Startup Path | 启动路径上的热点,优先预编译 |
[SP] | Startup Path | 启动路径上的普通热点,次优先 |
[WU] | Warmup | 预热类,延迟编译 |
[P] | Post Startup | 启动后使用的类,按需编译 |
构建完成后,基线文件生成在 build/outputs/baseline-profile/ 目录下:
build/outputs/baseline-profile/
├── release
│ ├── baseline.prof # AGP 8.0+ 合并后的二进制文件
│ └── baseline-prof.txt # 可读的 profile 规则文本(用于调试)
├── debug
│ └── baseline-prof.txt
最终会打包进 APK 的 assets/dexopt/baseline.prof,可通过 zipinfo 或 apkanalyzer 验证:
apkanalyzer apk ./app-release.apk | grep baseline.prof
assets/dexopt/baseline.prom 5372 bytes (compressed 2431)
3.4 配置 consumerProguardFiles
consumerProguardFiles 用于声明哪些 ProGuard 规则需要保留给消费者(库项目)或打包时保留 profile 相关的 keep 规则。对于 Baseline Profile,需要确保 profile 规则不会因代码混淆而被移除。在应用模块或库模块的 build.gradle 中配置:
android {
defaultConfig {
// 将 profile 规则添加到 consumerProguardFiles
consumerProguardFiles 'proguard-rules.pro', 'baseline-profile-keep.pro'
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
'proguard-rules.pro',
'consumer-rules.pro'
}
}
}
其中 baseline-profile-keep.pro 内容示例如下:
# 保留 baseline profile 规则中涉及的所有类和方法
-keep class com.example.app.** { *; }
# 保留所有带 @Keep 注解的元素
-keep @androidx.annotation.Keep class *
-keepclassmembers class * {
@androidx.annotation.Keep *;
}
# 保留 profile 规则中明确列出的类路径
-keep class com.example.app.MainActivity
-keep class com.example.app.SplashActivity
-keep class com.example.app.HomeFragment
consumerProguardFiles 比直接在 proguardFiles 中配置更安全,因为前者会随 AAR 库一起发布给下游消费者,确保 profile 规则在库项目中被正确保留。对于多 module 项目,每个 module 的 consumerProguardFiles 会自动合并到主 app 的混淆规则中。3.5 多 flavor 支持
不同产品风味(flavor)通常对应不同的启动路径、API 端点或功能集,因此需要为每个 flavor 独立配置 Baseline Profile 规则。在 android 块中使用 flavorDimensions 和 productFlavors 分别指定 profile 规则:
android {
flavorDimensions "version", "market"
productFlavors {
free {
dimension "version"
profile {
rules file("free-profile-rules.txt")
}
}
paid {
dimension "version"
profile {
rules file("paid-profile-rules.txt")
}
}
googlePlay {
dimension "market"
}
huawei {
dimension "market"
profile {
rules file("huawei-profile-rules.txt")
}
}
}
}
当 flavor 组合(如 freeGooglePlay)构建时,Gradle 会自动合并对应维度的 profile 规则文件。规则合并策略:
- 相同类/方法出现冲突时,以较高优先级 flavor 为准(排列靠前的 flavor 优先级高)。
- 可通过
profile { rules files(...) }中多次声明来添加多组规则。 - 若 flavor 未指定
rules,则使用defaultConfig中的 profile 配置。
3.6 调试与验证
配置完成后,执行以下 Gradle 任务验证是否正确集成了 Baseline Profile:
# 1. 生成 profile 规则并打包
./gradlew :app:assembleFreeGooglePlayRelease
# 2. 查看 APK 中是否包含 profile 文件
./gradlew :app:transformClassesAndResourcesWithProguardForRelease
# 3. 安装到设备并检查 AOT 编译状态
adb shell dumpsys dexopt --statistics
# 或查看特定应用的编译状态
adb shell dumpsys package com.example.app | grep compiler-filter
# 输出示例:
# compiler-filter=speed-profile
# pkg=com.example.app, codePath=/data/app/~~something==/base.apk
# compilation reason=install, status=compiled
# 4. 检查 profile 文件是否被解析
adb shell dumpsys package dexopt com.example.app
# 日志中应包含 "Profile guided compilation enabled" 字样
若编译状态为 speed-profile 而非 speed,说明 baseline profile 已生效。
3.7 常见错误与稳定性优化
| 错误现象 | 原因 | 解决方法 |
|---|---|---|
APK 中无 baseline.prof | profile 配置未启用或规则文件路径错误 | 检查 profile { enabled true } 是否设置,规则文件路径是否相对于 build.gradle |
| 混淆后 profile 规则失效 | 类名被混淆,但 profile 规则未保留原路径 | 添加 consumerProguardFiles 并保持 -keep 规则 |
| 多 flavor 规则冲突 | 不同 flavor 的规则文件中包含相同类但不同优先级 | 统一 flavor 维度优先级,或使用 profile { rules } 的注释标记优先级 |
| 安装时未触发 AOT 编译 | 设备 Android 版本过低或 AOT 编译策略变更 | 最低需要 Android 10(API 29)+ 且安装时 ProfileInstaller 必须正常启动 |
| 基线文件过大(>1MB) | 包含过多不必要的类/方法,导致编译时间过长 | 限 profile 规则数量(建议少于 500 条 HSP),使用 [WU]/[P] 降低优先级 |
rule 文件中优先使用 [HSP] 标记最关键的前 5 个 Activity 和 10 个 Service,其余使用 [SP] 或 [WU];4)基线文件生成后,通过 apkanalyzer 和 dexopt --statistics 在 CI pipeline 中自动校验是否生效。