创建基准配置文件

使用 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. 选择 File > New > New Module(文件 > 新建 > 新建模块)
  2. Templates(模板)面板中选择 Baseline Profile Generator(基准配置文件生成器)模板并进行配置
    图 1. 基准配置文件生成器模块模板。

    模板中的字段如下:

    • Target application(目标应用):定义为此基准配置文件生成哪个应用。如果您的项目中只有一个应用模块,则此列表中只有一个项目。
    • Module name(模块名称):您要为正在创建的基准配置文件模块命名的名称。
    • Package name(软件包名称):您要为基准配置文件模块指定的软件包名称。
    • Language(语言):您希望生成的代码是 Kotlin 还是 Java。
    • Build configuration language(构建配置语言):您希望为构建配置脚本使用 Kotlin Script (KTS) 还是 Groovy。
    • Use Gradle-managed device(使用 Gradle 管理的设备):您是否正在使用Gradle 管理的设备来测试您的应用。
  3. 点击 Finish(完成),新模块即已创建。如果您使用源代码管理,系统可能会提示您将新创建的模块文件添加到源代码管理中。

定义基准配置文件生成器

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

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

生成并安装基准配置文件

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

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

Generate Baseline Profile(生成基准配置文件)运行配置完成时,它会将生成的基准配置文件复制到正在分析的模块中的 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 任务。

    在有根的物理设备、模拟器或Gradle 管理的设备上将生成器作为插桩测试运行。如果您使用 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.4.1")
    }
    
  4. 构建您的应用的生产版本,同时将应用的 HRF 规则编译为二进制形式并包含在 APK 或 AAB 中。然后像往常一样分发您的应用。

基准测试基准配置文件

要对基准配置文件进行基准测试,请从 gutter 操作创建新的 Android 插桩测试运行配置,该配置执行 StartupBenchmarks.ktStartupBencharks.java 文件中定义的基准测试。要了解有关基准测试的更多信息,请参阅创建 Macrobenchmark 类使用 Macrobenchmark 库实现自动化测量

图 3. 从 gutter 操作运行 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)
显示应用界面的第一帧所需的时间。
完全显示时间 (TTFD)
TTID 加上在初始帧显示后异步加载内容所需的时间。

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

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

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

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