Baseline Profiles
源:Android 官方文档 - Baseline Profiles overview
Baseline Profiles 通过 AOT (Ahead-Of-Time) 编译优化应用启动速度和运行时性能,减少卡顿。
什么是 Baseline Profiles
Baseline Profiles 是一个包含应用关键代码路径的文件,告诉 Android Runtime (ART) 哪些类和方法应该被 AOT 编译。
工作原理:
- 在发布前生成 Baseline Profile
- 打包到 AAB/APK 中
- 安装后,ART 立即 AOT 编译这些代码
- 应用从首次启动就获得性能提升
性能提升
典型改进:
- 启动速度提升 30%+
- 减少卡顿和掉帧
- 降低 ANR 发生率
- 提高用户留存率
适用场景:
- 应用启动流程
- 屏幕导航
- 列表滚动
- 复杂UI渲染
快速开始
前置要求
最低版本要求:
| 组件 | 最低版本 |
|---|---|
| AGP | 8.0.0 |
| Kotlin | 1.9.0 |
| Compose | 1.4.0 |
| Gradle | 8.0 |
添加依赖
plugins {
id("androidx.baselineprofile") version "1.3.0"
}
dependencies {
baselineProfile(project(":baselineprofile"))
}plugins {
id("androidx.baselineprofile") version "1.3.0" apply false
}创建 Baseline Profile 模块
新建模块:
File → New → Module → Baseline Profile Generator
或手动创建:
// baselineprofile/build.gradle.kts
plugins {
id("com.android.test")
kotlin("android")
id("androidx.baselineprofile")
}
android {
namespace = "com.example.baselineprofile"
compileSdk = 34
targetProjectPath = ":app"
testOptions.managedDevices.devices {
create("pixel6Api31") {
device = "Pixel 6"
apiLevel = 31
systemImageSource = "aosp"
}
}
}
dependencies {
implementation("androidx.benchmark:benchmark-macro-junit4:1.3.0")
implementation("androidx.test.ext:junit:1.2.1")
implementation("androidx.test.espresso:espresso-core:3.6.1")
implementation("androidx.test.uiautomator:uiautomator:2.3.0")
}编写 Profile 生成测试
// baselineprofile/src/main/kotlin/BaselineProfileGenerator.kt
package com.example.baselineprofile
import androidx.benchmark.macro.junit4.BaselineProfileRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class BaselineProfileGenerator {
@get:Rule
val rule = BaselineProfileRule()
@Test
fun generate() = rule.collect(
packageName = "com.example.myapp",
// 定义用户旅程
profileBlock = {
startActivityAndWait()
// 应用启动后的操作
device.waitForIdle()
// 导航到主界面
device.findObject(By.text("Home")).click()
device.waitForIdle()
// 滚动列表
val list = device.findObject(By.res("recyclerView"))
list.setGestureMargin(device.displayWidth / 5)
list.fling(Direction.DOWN)
device.waitForIdle()
// 打开详情页
device.findObject(By.text("Details")).click()
device.waitForIdle()
}
)
}生成 Baseline Profile
# 生成 Baseline Profile
./gradlew :baselineprofile:pixel6Api31BaselineProfile生成的文件位于:
app/src/main/baseline-prof.txtProfile 文件格式
# baseline-prof.txt
HSPLcom/example/myapp/MainActivity;-><init>()V
HSPLcom/example/myapp/MainActivity;->onCreate(Landroid/os/Bundle;)V
PLcom/example/myapp/ui/HomeScreen;->HomeScreen()V
SPLandroidx/compose/runtime/ComposerKt;->sourceInformation(...)V标记说明:
- H - Hot method(热方法)- 应该被 AOT 编译
- S - Startup method(启动方法)- 应用启动时调用
- P - Post-startup method(启动后方法)
- L - Layout(布局)- 在首帧绘制前编译
配置选项
变体配置
为不同构建变体生成不同的 Profile:
android {
defaultConfig {
// ...
}
}
baselineProfile {
variants {
release {
automaticGenerationDuringBuild = true
}
}
saveInSrc = true
baselineProfileOutputDir = "."
}Gradle Managed Devices
使用虚拟设备自动化生成:
android {
testOptions {
managedDevices {
devices {
create<com.android.build.api.dsl.ManagedVirtualDevice>("pixel6Api31") {
device = "Pixel 6"
apiLevel = 31
systemImageSource = "aosp"
}
}
}
}
}运行:
./gradlew :baselineprofile:pixel6Api31BaselineProfile自动生成
在构建时自动生成(不推荐用于 CI):
baselineProfile {
automaticGenerationDuringBuild = true
}验证效果
使用 Macrobenchmark
创建基准测试验证改进:
@RunWith(AndroidJUnit4::class)
class StartupBenchmark {
@get:Rule
val rule = MacrobenchmarkRule()
@Test
fun startupNoCompilation() = startup(CompilationMode.None())
@Test
fun startupBaselineProfile() = startup(CompilationMode.Partial(
baselineProfileMode = BaselineProfileMode.Require
))
private fun startup(compilationMode: CompilationMode) = rule.measureRepeated(
packageName = "com.example.myapp",
metrics = listOf(StartupTimingMetric()),
iterations = 5,
compilationMode = compilationMode
) {
pressHome()
startActivityAndWait()
}
}对比结果:
startupNoCompilation: 450ms
startupBaselineProfile: 310ms # 31% 提升分析生成的 Profile
查看类覆盖率:
# 查看有多少类被包含
grep -c '^H' app/src/main/baseline-prof.txt热方法分析:
# 查看所有热方法
grep '^H' app/src/main/baseline-prof.txt | head -20最佳实践
Profile 应该包含什么
√ 应该包含:
- 应用启动流程
- 常见用户操作
- 关键用户旅程
- 首屏渲染
× 不应该包含:
- 很少使用的功能
- 错误处理路径
- 调试代码
增量更新
每次发布前更新 Profile:
./gradlew :baselineprofile:generateBaselineProfile提交更新的 baseline-prof.txt 到版本控制。
多变体支持
为不同产品变体生成不同的 Profile:
android {
productFlavors {
create("free") {
// ...
}
create("paid") {
// ...
}
}
}
// 分别生成
// ./gradlew :baselineprofile:freeReleaseBaselineProfile
// ./gradlew :baselineprofile:paidReleaseBaselineProfileCI/CD 集成
在 CI 中验证 Profile 存在:
# GitHub Actions 示例
- name: Verify Baseline Profile
run: |
if [ ! -f "app/src/main/baseline-prof.txt" ]; then
echo "Baseline Profile not found!"
exit 1
fi监控 Profile 效果
使用 Firebase Performance Monitoring 或自定义分析:
val trace = FirebasePerformance.getInstance().newTrace("app_start")
trace.start()
// 应用启动逻辑
trace.stop()Baseline Profiles vs Startup Profiles
| 特性 | Baseline Profiles | Startup Profiles |
|---|---|---|
| 生成方式 | 开发者生成并打包到应用 | Google Play 自动生成 |
| 生效时间 | 首次安装即生效 | 需要用户使用一段时间 |
| 覆盖范围 | 开发者定义的用户旅程 | 基于真实用户行为 |
| 控制力 | 完全由开发者控制 | Google 自动优化 |
| 适用场景 | 所有分发渠道 | 仅 Google Play |
建议:同时使用两者获得最佳效果。
Cloud Profiles
Google Play 自动生成的 Profile,基于真实用户行为。
启用方式:
在 Google Play Console 中默认启用,无需额外配置。
与 Baseline Profiles 的关系:
- Baseline Profiles 保证首次安装即优化
- Cloud Profiles 基于真实数据持续优化
- 两者互补,不冲突
常见问题
Profile 文件太大
问题:生成的 Profile 过大,增加 APK 体积。
解决:
- 精简用户旅程
- 移除不常用的功能
- 检查是否包含第三方库代码
性能提升不明显
可能原因:
- Profile 覆盖的代码路径不是瓶颈
- 设备已有足够的 JIT 优化
- Profile 生成不完整
解决:
- 使用 Profiler 分析实际瓶颈
- 确保 Profile 覆盖关键路径
- 在低端设备上测试
构建时间增加
原因:自动生成 Profile 需要运行测试。
解决:
- 关闭
automaticGenerationDuringBuild - 仅在发布前手动生成
- 使用增量生成
工具链
AGP Baseline Profile Plugin:
- 自动集成 Profile 到构建
- 支持多变体
- Gradle Managed Devices 支持
Macrobenchmark:
- 生成 Profile
- 性能基准测试
- 对比优化效果
Android Studio Profiler:
- 分析启动性能
- 验证 AOT 编译
- 识别优化机会