创建基线配置文件

使用 Jetpack Macrobenchmark 库BaselineProfileRule 自动为每个应用版本生成配置文件。我们建议您使用 com.android.tools.build:gradle:8.0.0 或更高版本,它在使用基线配置文件时包含构建改进。

以下是创建新基线配置文件的一般步骤

  1. 设置基线配置文件模块。
  2. 定义有助于生成基线配置文件的 JUnit 测试。
  3. 添加您想要优化的关键用户旅程 (CUJ)。
  4. 生成基线配置文件。

生成基线配置文件后,使用物理设备对其进行基准测试以衡量速度改进。

使用 AGP 8.2 或更高版本创建新的基线配置文件

创建新基线配置文件最简单的方法是使用基线配置文件模块模板,该模板从 Android Studio Iguana 和 Android Gradle Plugin (AGP) 8.2 开始可用。

Android Studio 基线配置文件生成器模块模板自动创建一个新模块以生成和 基准测试 基线配置文件。运行该模板会生成大多数典型的构建配置、基线配置文件生成和验证代码。该模板创建用于生成和基准测试基线配置文件的代码,以衡量应用启动。

设置基线配置文件模块

要运行基线配置文件模块模板,请按照以下步骤操作

  1. 选择文件 > 新建 > 新模块
  2. 模板面板中选择基线配置文件生成器模板并进行配置
    图 1. 基线配置文件生成器模块模板。

    模板中的字段如下所示

    • 目标应用程序:定义为哪个应用生成基线配置文件。当您的项目中只有一个应用模块时,此列表中只有一项。
    • 模块名称:要为正在创建的基线配置文件模块指定的名称。
    • 包名:要为基线配置文件模块指定的包名。
    • 语言:是否希望生成的代码为 Kotlin 或 Java。
    • 构建配置语言:是否希望使用 Kotlin 脚本 (KTS) 或 Groovy 作为构建配置脚本。
    • 使用 Gradle 管理的设备:是否正在使用 Gradle 管理的设备 测试您的应用。
  3. 点击完成,新模块即创建完成。如果您正在使用源代码控制,系统可能会提示您将新创建的模块文件添加到源代码控制中。

定义基线配置文件生成器

新创建的模块包含用于生成和基准测试基线配置文件以及仅测试基本应用启动的测试。建议您对这些测试进行扩展,以包含 CUJ 和高级启动工作流。确保与应用启动相关的任何测试都在 rule 代码块中,并将 includeInStartupProfile 设置为 true;相反,为了获得最佳性能,请确保任何与应用启动无关的测试都不包含在启动配置文件中。应用启动优化用于定义基线配置文件的一个特殊部分,称为 启动配置文件

如果您将这些 CUJ 抽象到生成的基线配置文件和基准测试代码之外,则有助于提高可维护性,以便可以同时使用它们。这意味着对 CUJ 的更改将始终保持一致。

生成并安装基线配置文件

基线配置文件模块模板会添加一个新的运行配置来生成基线配置文件。如果您使用产品风格,Android Studio 会创建多个运行配置,以便您可以为每个风格生成单独的基线配置文件。

The Generate Baseline Profile run configuration.
图 2. 运行此配置会生成基线配置文件。

生成基线配置文件运行配置完成时,它会将生成的基线配置文件复制到正在分析的模块中的 src/variant/generated/baselineProfiles/baseline-prof.txt 文件中。变体选项要么是发布构建类型,要么是包含发布构建类型的构建变体。

生成的基线配置文件最初是在 build/outputs 中创建的。完整路径由正在分析的应用的变体或风格以及您是否使用 Gradle 管理的设备或连接的设备进行分析决定。如果您使用模板生成的代码和构建配置中使用的名称,则基线配置文件将在 build/outputs/managed_device_android_test_additional_output/nonminifiedrelease/pixel6Api31/BaselineProfileGenerator_generate-baseline-prof.txt 文件中创建。除非您要手动将其复制到目标模块(不推荐),否则您可能不必直接与该版本的生成的基线配置文件进行交互。

使用 AGP 8.1 创建新的基线配置文件

如果您无法使用 基线配置文件模块模板,请使用宏基准测试模块模板和基线配置文件 Gradle 插件创建新的基线配置文件。建议您从 Android Studio Giraffe 和 AGP 8.1 开始使用这些工具。

以下是使用宏基准测试模块模板和基线配置文件 Gradle 插件创建新的基线配置文件的步骤

  1. 在您的 Gradle 项目中设置宏基准测试模块
  2. 定义一个名为 BaselineProfileGenerator 的新类
    class BaselineProfileGenerator {
        @get:Rule
        val baselineProfileRule = BaselineProfileRule()
    
        @Test
        fun startup() = baselineProfileRule.collect(
            packageName = "com.example.app",
            profileBlock = {
                startActivityAndWait()
            }
        )
    }

    生成器可以包含超出应用启动的与应用的交互。这使您可以优化应用的运行时性能,例如滚动列表、运行动画以及在 Activity 中导航。查看其他示例,了解使用 @BaselineProfileRule 改善关键用户体验的测试。

  3. 添加基线配置文件 Gradle 插件 (libs.plugins.androidx.baselineprofile)。该插件使生成基线配置文件并将来维护它们变得更加容易。

  4. 要生成基线配置文件,请在终端中运行 :app:generateBaselineProfile:app:generateVariantBaselineProfile Gradle 任务。

    在已扎根的物理设备、模拟器或 Gradle 管理的设备 上以已检测测试的形式运行生成器。如果您使用 Gradle 管理的设备,请将 aosp 设置为 systemImageSource,因为基线配置文件生成器需要 root 访问权限。

    在生成任务结束时,基线配置文件将复制到 app/src/variant/generated/baselineProfiles

无需模板创建新的基线配置文件

建议使用 Android Studio 基线配置文件模块模板(首选)或 宏基准测试模板创建基线配置文件,但您也可以单独使用基线配置文件 Gradle 插件。要详细了解基线配置文件 Gradle 插件,请参阅 配置基线配置文件生成

以下是使用基线配置文件 Gradle 插件直接创建基线配置文件的方法

  1. 创建一个新的 com.android.test 模块,例如 :baseline-profile
  2. 配置 :baseline-profilebuild.gradle.kts 文件

    1. 应用 androidx.baselineprofile 插件。
    2. 确保 targetProjectPath 指向 :app 模块。
    3. 可选:添加 Gradle 管理的设备 (GMD)。在以下示例中,它是 pixel6Api31。如果未指定,则插件会使用连接的设备,无论是模拟的还是物理的。
    4. 应用所需的配置,如下例所示。

    Kotlin

    plugins {
        id("com.android.test")
        id("androidx.baselineprofile")
    }
    
    android {
        defaultConfig {
            ...
        }
    
        // Point to the app module, the module that you're generating the Baseline Profile for.
        targetProjectPath = ":app"
        // Configure a GMD (optional).
        testOptions.managedDevices.devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device = "Pixel 6"
                apiLevel = 31
                systemImageSource = "aosp"
            }
        }
    }
    
    dependencies { ... }
    
    // Baseline Profile Gradle plugin configuration. Everything is optional. This
    // example uses the GMD added earlier and disables connected devices.
    baselineProfile {
        // Specifies the GMDs to run the tests on. The default is none.
        managedDevices += "pixel6Api31"
        // Enables using connected devices to generate profiles. The default is
        // `true`. When using connected devices, they must be rooted or API 33 and
        // higher.
        useConnectedDevices = false
    }

    Groovy

    plugins {
        id 'com.android.test'
        id 'androidx.baselineprofile'
    }
    
    android {
        defaultConfig {
            ...
        }
    
        // Point to the app module, the module that you're generating the Baseline Profile for.
        targetProjectPath ':app'
        // Configure a GMD (optional).
        testOptions.managedDevices.devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device 'Pixel 6'
                apiLevel 31
                systemImageSource 'aosp'
            }
        }
    }
    
    dependencies { ... }
    
    // Baseline Profile Gradle plugin configuration. Everything is optional. This
    // example uses the GMD added earlier and disables connected devices.
    baselineProfile {
        // Specifies the GMDs to run the tests on. The default is none.
        managedDevices ['pixel6Api31']
        // Enables using connected devices to generate profiles. The default is
        // `true`. When using connected devices, they must be rooted or API 33 and
        // higher.
        useConnectedDevices false
    }
  3. :baseline-profile 测试模块中创建一个基线配置文件测试。以下示例是一个启动应用并等待空闲的测试。

    Kotlin

    class BaselineProfileGenerator {
    
        @get:Rule
        val baselineRule = BaselineProfileRule()
    
        @Test
        fun startupBaselineProfile() {
            baselineRule.collect("com.myapp") {
                startActivityAndWait()
            }
        }
    }

    Java

    public class BaselineProfileGenerator {
    
        @Rule
        Public BaselineProfileRule baselineRule = new BaselineProfileRule();
    
        @Test
        Public void startupBaselineProfile() {
            baselineRule.collect(
                "com.myapp",
                (scope -> {
                    scope.startActivityAndWait();
                    Return Unit.INSTANCE;
                })
            )
        }
    }
  4. 更新应用模块中的 build.gradle.kts 文件,例如 :app

    1. 应用插件 androidx.baselineprofile
    2. baselineProfile 依赖项添加到 :baseline-profile 模块。

    Kotlin

    plugins {
        id("com.android.application")
        id("androidx.baselineprofile")
    }
    
    android {
        // There are no changes to the `android` block.
        ...
    }
    
    dependencies {
        ...
        // Add a `baselineProfile` dependency on the `:baseline-profile` module.
        baselineProfile(project(":baseline-profile"))
    }

    Groovy

    plugins {
        id 'com.android.application'
        id 'androidx.baselineprofile'
    }
    
    android {
        // No changes to the `android` block.
        ...
    }
    
    dependencies {
        ...
        // Add a `baselineProfile` dependency on the `:baseline-profile` module.
        baselineProfile ':baseline-profile'
    }
  5. 通过运行 :app:generateBaselineProfile:app:generateVariantBaselineProfile Gradle 任务生成配置文件。

  6. 在生成任务结束时,基线配置文件将复制到 app/src/variant/generated/baselineProfiles

使用 AGP 7.3-7.4 创建新的基线配置文件

可以使用 AGP 7.3-7.4 生成基线配置文件,但强烈建议升级到至少 AGP 8.1,以便您可以使用基线配置文件 Gradle 插件及其最新功能。

如果您需要使用 AGP 7.3-7.4 创建基线配置文件,则步骤与 AGP 8.1 的步骤 相同,但以下情况除外

手动应用生成的规则

基线配置文件生成器会在设备上创建一个人类可读格式 (HRF) 文本文件,并将其复制到您的主机计算机。要将生成的配置文件应用到您的代码,请执行以下步骤

  1. 在您生成配置文件的模块的构建文件夹中找到 HRF 文件:[module]/build/outputs/managed_device_android_test_additional_output/[device]

    配置文件遵循 [class name]-[test method name]-baseline-prof.txt 命名模式,如下所示:BaselineProfileGenerator-startup-baseline-prof.txt

  2. 将生成的配置文件复制到 src/main/ 并将文件名重命名为 baseline-prof.txt

  3. 在应用的 build.gradle.kts 文件中添加对 ProfileInstaller 库 的依赖项,以启用本地基线配置文件编译,在其中 云配置文件 不可用。这是本地旁加载基线配置文件的唯一方法。

    dependencies {
         implementation("androidx.profileinstaller:profileinstaller:1.4.1")
    }
    
  4. 构建应用的生产版本,同时将应用的 HRF 规则编译成二进制形式并包含在 APK 或 AAB 中。然后照常分发您的应用。

基准测试基线配置文件

要对基线配置文件进行基准测试,请从代码行操作创建新的 Android 已检测测试运行配置,该配置执行 StartupBenchmarks.ktStartupBencharks.java 文件中定义的基准测试。要详细了解基准测试,请参阅 创建宏基准测试类使用宏基准测试库自动测量

图 3. 从代码行操作运行 Android 测试。

在 Android Studio 中运行此操作时,构建输出包含基线配置文件提供的速度改进的详细信息

StartupBenchmarks_startupCompilationBaselineProfiles
timeToInitialDisplayMs   min 161.8,   median 178.9,   max 194.6
StartupBenchmarks_startupCompilationNone
timeToInitialDisplayMs   min 184.7,   median 196.9,   max 202.9

捕获所有必需的代码路径

衡量应用启动时间的两个关键指标如下

首次显示时间 (TTID)
显示应用程序 UI 的第一帧所需的时间。
完全显示时间 (TTFD)
TTID 加上在显示初始帧后异步加载的内容的显示时间。

一旦调用 reportFullyDrawn() 方法(位于 ComponentActivity 类中),就会报告 TTFD。如果从未调用 reportFullyDrawn(),则会改为报告 TTID。您可能需要延迟 reportFullyDrawn() 的调用时间,直到异步加载完成之后。例如,如果 UI 包含动态列表,如 RecyclerView延迟加载列表,则该列表可能由一个在列表首次绘制后(因此在 UI 被标记为完全绘制后)完成的后台任务填充。在这种情况下,在 UI 达到完全绘制状态后运行的代码不会包含在基线配置文件中。

要将列表填充作为基线配置文件的一部分,请使用 getFullyDrawnReporter() 获取 FullyDrawnReporter,并在您的应用代码中向其添加一个报告器。在后台任务完成填充列表后,释放该报告器。 FullyDrawnReporter 只有在所有报告器都被释放后才会调用 reportFullyDrawn() 方法。通过这样做,基线配置文件将包含填充列表所需的代码路径。这不会改变应用对用户的行为,但它允许基线配置文件包含所有必要的代码路径。

如果您的应用使用 Jetpack Compose,请使用以下 API 指示完全绘制状态

  • ReportDrawn 表示您的可组合项已立即准备好进行交互。
  • ReportDrawnWhen 获取一个谓词(例如 list.count > 0),以指示您的可组合项何时准备好进行交互。
  • ReportDrawnAfter 获取一个挂起方法,当该方法完成时,表示您的可组合项已准备好进行交互。