创建基线配置文件

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

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

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

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

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

创建新基线配置文件最简单的方法是使用基线配置文件模块模板,该模板从 Android Studio Iguana 和 Android Gradle 插件 (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 创建新的基线配置文件

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

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

  1. 在 Gradle 项目中设置 Macrobenchmark 模块
  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 任务。

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

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

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

我们建议使用 Android Studio 的基线配置文件模块模板(首选)或Macrobenchmark 模板创建基线配置文件,但您也可以单独使用基线配置文件 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. :baseline-profile模块中添加一个baselineProfile依赖项。

    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.3.1")
    }
    
  4. 构建应用程序的生产版本,同时将应用的 HRF 规则编译成二进制形式并包含在 APK 或 AAB 中。然后像往常一样分发您的应用程序。

基准测试基线配置文件

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

图 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 加上在显示初始帧后异步加载的内容所花费的时间。

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

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

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

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