创建基准配置文件

您可以使用 Jetpack Macrobenchmark 库BaselineProfileRule 为每个应用版本自动生成配置文件。我们建议您使用 com.android.tools.build:gradle:8.1.0 或更高版本,因为这些版本改进了使用基准配置文件时的构建功能。

定义基准配置文件生成器

如需使用 Macrobenchmark 库创建基准配置文件,请按照以下步骤操作:

Android Studio Hedgehog Canary 1

基准配置文件生成器模块模板

Android Studio 基准配置文件生成器模块模板会自动创建一个新模块,以便生成基准配置文件并对其进行基准测试。运行该模板会生成大部分典型的 build 配置代码、基准配置文件生成代码,以及验证代码。该模板会创建用于生成基准配置文件并对其进行基准测试的代码,以便衡量应用启动情况。

您需要在应用中手动定义关键用户历程 (CUJ),这样一来,生成的基准配置文件便会为这些 CUJ 提供所需的优化。

使用模板创建基准配置文件生成器模块

如需运行基准配置文件模块模板,请执行以下步骤:

  1. 依次选择 File > New > New Module
  2. Templates 面板中选择 Baseline Profile Generator 模板,并对其进行配置:
    图 1. 基准配置文件生成器模块模板。

    该模板中的字段如下:

    • Target application:此字段会列出项目中的应用模块,并定义是为哪个应用生成基准配置文件。如果项目中只有一个应用模块,此列表中将只有一项。
    • Module name:您希望要创建的基准配置文件模块使用的名称。
    • Package name:您希望基准配置文件模块使用的软件包名称。
    • Language:您希望生成的代码是 Kotlin 还是 Java。
    • Build configuration language:您希望 build 配置脚本使用 Kotlin Script (KTS) 还是 Groovy。
  3. 点击 Finish,即会创建一个新模块。如果您使用源代码控制工具,系统可能会提示您将新创建的模块文件添加到源代码控制工具中。

新创建的模块中包含用于生成基准配置文件并对其进行基准测试的代码,以及用于仅测试基本应用启动时间的代码。我们建议您将这些代码扩充为包含 CUJ。如果您将这些 CUJ 提取到生成的基准配置文件和基准测试代码之外,以便它们可以用于这两者,将有助于提高可维护性。这意味着会一致地使用您对 CUJ 所做的更改。

生成基准配置文件

基准配置文件模块模板中添加了一个新的运行配置,用于生成基准配置文件:

图 2. 运行此配置会生成基准配置文件。

若要从命令行界面执行此操作,您可以运行 :app:generaterBaselineProfile:app:generateBaselineProfile Gradle 任务。这会生成基准配置文件,并将其安装到要分析的应用。

安装基准配置文件

“Generate Baseline Profile”运行配置在完成运行后,会将生成的基准配置文件复制到要分析的模块中的 src/release/generated/baselineProfiles/baseline-prof.txt

系统会在 build/outputs 中创建生成的基准配置文件。不过,完整路径取决于要分析的应用变体或变种,以及您是使用 Gradle 管理的设备还是使用已连接的设备进行分析。

如果您使用由模板生成的代码和 build 配置所使用的名称,系统将在 build/outputs/managed_device_android_test_additional_output/nonminifiedrelease/pixel6Api31/BaselineProfileGenerator_generate-baseline-prof.txt 中创建生成的基准配置文件。

Android Studio Giraffe 及更早版本

  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. (可选)生成基准配置文件时,关闭混淆功能。为此,您只需要为负责生成配置文件的 benchmark build 类型执行以下操作即可:在应用模块中再创建一个 ProGuard 文件,并添加 -dontobfuscate

    Kotlin

    buildTypes {
        val benchmark by creating {
            // Only use benchmark Proguard rules.
            proguardFiles("benchmark-rules.pro")
            // ...
        }
    }
    

    Groovy

    buildTypes {
        benchmark {
            // Only use benchmark Proguard rules.
            proguardFiles 'benchmark-rules.pro'
            // ...
        }
    }
    

生成基准配置文件

在已启用 root 权限的实体设备、模拟器或 Gradle 管理的设备上,将生成器作为插桩测试运行。如需设置受管设备,请打开 build.gradle.kts 文件。在 testOptions 配置块中,添加 managedDevicesdevices,并创建模拟器定义。使用 aosp 作为 systemImageSource,因为您需要拥有对基准配置文件生成器的 root 访问权限。

Kotlin

testOptions {
    managedDevices {
        devices {
            create ("pixel6Api31", ManagedVirtualDevice::class) {
                device = "Pixel 6"
                apiLevel = 31
                systemImageSource = "aosp"
            }
        }
    }
}

Groovy

testOptions {
    managedDevices {
        devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device = "Pixel 6"
                apiLevel = 31
                systemImageSource = "aosp"
            }
        }
    }
}

Gradle 会根据所选的设备名称以及模块中提供的 build 变体来创建所需的任务。其格式为 [emulator_name][flavor][build type]AndroidTest。您可以通过终端执行此任务:

./gradlew :benchmark:pixel6Api31BenchmarkAndroidTest

对基准配置文件进行基准测试

如需对基准配置文件进行基准测试,请通过负责执行 StartupBenchmarks.ktStartupBencharks.java 中定义的基准测试的边线操作,创建新的 Android 插桩测试运行配置。如需详细了解基准测试,请参阅创建 Macrobenchmark 类使用 Macrobenchmark 库自动进行衡量

图 3. 通过边线操作运行 Android 测试。

当您在 Android Studio 中运行测试时,build 输出中会包含基准配置文件带来的速度提升的详细信息:

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 是显示应用界面的第一帧所用的时间。TTFD 还包含在显示第一帧后显示异步加载的内容所用的时间。

系统会在调用 ComponentActivityreportFullyDrawn() 方法后报告 TTFD。如果从未调用 reportFullyDrawn(),则改为报告 TTID。如果系统调用 reportFullyDrawn(),可能需要延迟到异步加载完成之后再报告相应时间。例如,如果界面包含一个动态列表,例如 RecyclerView延迟列表,那么可能就要在首次绘制列表之后,也就是在界面被标记为完全绘制之后,才通过后台任务来填充该列表。在这种情况下,基准配置文件中将不包含在界面达到完全绘制状态后运行的代码。

如需将列表填充也纳入基准配置文件中,请使用 getFullyDrawnReporter() 获取 FullyDrawnReporter,并在应用代码中为其添加报告程序。一旦后台任务完成列表填充,便释放报告程序。在所有报告程序都被释放之后,FullyDrawnReporter 才会调用 reportFullyDrawn() 方法。这样一来,基准配置文件会包含填充列表所需的代码路径。这不会改变面向用户的应用行为,但可让基准配置文件包含所有必要的代码路径。

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

  • ReportDrawn 表示可组合项已准备好立即进行互动。
  • ReportDrawnWhen 接受一个谓词(例如 list.count > 0),以指明可组合项何时准备好进行互动。
  • ReportDrawnAfter 接受一个暂停方法,该方法完成时表示您的可组合项已准备好进行互动。

基准配置文件 Gradle 插件

使用基准配置文件 Gradle 插件,可以更轻松地生成和维护基准配置文件。该插件会执行生成基准配置文件并将其安装到应用模块中的必要步骤。

如需使用该插件,请向您的项目中添加插桩测试模块,并定义一组测试以模拟整个应用中的关键用户历程。当您运行插桩测试时,基准配置文件 Gradle 插件会跟踪在这些用户体验历程中执行的所有类和方法,并根据这些类和方法生成基准配置文件。然后,它会将生成的基准配置文件复制到应用模块中。

插桩测试模块是配置文件生产方。应用模块是配置文件使用方。

您需要关注的主要方面是初始设置以及创建测试来模拟关键用户历程。

插件要求

使用该插件

以下示例假定存在一个名为 :app 的应用模块。

下面的示例中有 2 个模块:

  • 配置文件使用方:生成的配置文件将供该应用模块使用。在以下示例中,它是 :app
  • 配置文件生产方:包含用于生成配置文件的插桩测试的基准配置文件测试模块。在以下示例中,它名为 :baseline-profile

如需使用该插件,请执行以下步骤:

  1. 创建一个新的 com.android.test 模块,例如 :baseline-profile
  2. :baseline-profile 配置 build.gradle
    1. 应用 androidx.baselineprofile 插件。
    2. 确保 targetProjectPath 指向 :app 模块。
    3. (可选)添加 GMD。在以下示例中,它是 pixel6Api31。如果未指定,该插件将使用一部已连接的模拟或实体设备。
    4. 应用您需要的配置,如以下示例所示。

    Kotlin

    plugins {
        id("com.android.test")
        id("androidx.baselineprofile")
    }
    
    android {
    
        // There are no changes here. It's documented for completeness.
        defaultConfig {
            ...
        }
    
        // This must point to the app module.
        targetProjectPath = ":app"
    
        // This is the optional managed device.
        testOptions.managedDevices.devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device = "Pixel 6"
                apiLevel = 31
                systemImageSource = "aosp"
            }
        }
    }
    
    // There are no changes here. It's documented for completeness.
    dependencies { ... }
    
    // This is the plugin configuration. Everything is optional. Defaults are in the
    // comments. In this example, you use the GMD added earlier and disable
    // connected devices.
    baselineProfile {
    
        // This specifies the managed devices to use that you run the tests on. The
        // default is none.
        managedDevices += "pixel6Api31"
    
        // This 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 {
    
        // There are no changes here. It's documented for completeness.
        defaultConfig {
            ...
        }
    
        // This must point to the app module.
        targetProjectPath ':app'
    
        // This is the optional managed device.
        testOptions.managedDevices.devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device 'Pixel 6'
                apiLevel 31
                systemImageSource 'aosp'
            }
        }
    }
    
        // There are no changes here. It's documented for completeness.
    dependencies { ... }
    
    // This is the plugin configuration. Everything is optional. Defaults are in the
    // comments. In this example, you use the GMD added earlier and disable
    // connected devices.
    baselineProfile {
    
        // This specifies the managed devices to use that you run the tests on. The
        // default is none.
        managedDevices ['pixel6Api31']
    
        // This 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 测试模块中创建基准配置文件测试。以下示例是一项会启动应用并等待应用进入空闲状态的测试。
  4. 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;
                })
            }
        }
    }
    
  5. 更新应用模块 :app 中的 build.gradle 配置。
    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 to 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 to the :baseline-profile module.
        baselineProfile ':baseline-profile"'
    }
    
  6. 运行以下代码,生成配置文件:./gradlew :app:generateBaselineProfile

在生成任务结束时,基准配置文件会被存储在 app/src/release/generated/baselineProfiles 中。

为库生成基准配置文件

在以下示例中,库模块名为 :library,应用模块名为 :sample-app,其中包含会使用该库的应用。

在此示例中,您需要三个模块:

  • 应用目标:包含示例应用的应用模块。在以下示例中,它是 :sample-app
  • 配置文件使用方:生成的配置文件将供该库模块使用。在以下示例中,它是 :library
  • 配置文件生产方:包含用于生成模块的插桩测试的基准配置文件测试模块。

如需为库生成基准配置文件,请执行以下步骤:

  1. 创建一个新的 com.android.test 模块,例如 :baseline-profile
  2. :baseline-profile 配置 build.gradle
    1. 应用 androidx.baselineprofile 插件。
    2. 确保 targetProjectPath 指向 :sample-app 模块。
    3. (可选)添加 GMD。在以下示例中,它是 pixel6Api31
    4. 应用您需要的配置,如以下示例所示。

    Kotlin

    plugins {
        id("com.android.test")
        id("androidx.baselineprofile")
    }
    
    android {
    
        // There are no changes here. It's reported for completeness.
        defaultConfig {
            minSdkVersion 23
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        }
    
        // This must point to the app module.
        targetProjectPath = ":app"
    
        // This is the optional managed device.
        testOptions.managedDevices.devices {
            create("pixel6Api31") {
                device = "Pixel 6"
                apiLevel = 31
                systemImageSource = "aosp"
            }
        }
    }
    
    // There's nothing to change here.
    dependencies { ... }
    
    // This is the plugin configuration. Everything is optional. Defaults are in the
    // comments. In this example, you use the GMD added earlier and disable
    // connected devices.
    baselineProfile {
    
        // This specifies the managed devices to use that you run the tests on. The
        // default is none.
        managedDevices += "pixel6Api31"
    
        // This 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 {
    
        // There are no changes here. It's reported for completeness.
        defaultConfig {
            ...
        }
    
        // This must point to the app module.
        targetProjectPath ':app'
    
        // This is the optional managed device.
        testOptions.managedDevices.devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device 'Pixel 6'
                apiLevel 31
                systemImageSource 'aosp'
            }
        }
    }
    
    // There's nothing to change here.
    dependencies { ... }
    
    // This is the plugin configuration. Everything is optional. Defaults are in the
    // comments. In this example, you use the GMD added earlier and disable
    // connected devices.
    baselineProfile {
    
        // This specifies the managed devices to use that you run the tests on. The
        // default is none.
        managedDevices ['pixel6Api31']
    
        // This 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 测试模块中创建基准配置文件测试。此测试需要特定于示例应用,并且必须使用该库的所有功能。
  4. 更新库模块 :librarybuild.gradle 的配置。
    1. 应用插件 androidx.baselineprofile
    2. baselineProfile 依赖项添加到 :baseline-profile 模块。
    3. 应用您需要的使用方插件配置,如以下示例所示。

    Kotlin

    plugins {
        id("com.android.library")
        id("androidx.baselineprofile")
    }
    
    // There are no changes to the android block.
    android { ... }
    
    dependencies {
        ...
        // Add a baselineProfile dependency to the :baseline-profile module.
        baselineProfile(project(":baseline-profile"))
    }
    
    // This is the plugin configuration.
    baselineProfile {
    
        // This filters the generated profile rules. In this example, you keep
        // all the classes in com.library and in all the subpackages.
        filter {
            include "com.mylibrary.**"
        }
    }
    

    Groovy

    plugins {
        id 'com.android.library'
        id 'androidx.baselineprofile'
    }
    
    // There are no changes to the android block.
    android { ... }
    
    dependencies {
        ...
        // Add a baselineProfile dependency to the :baseline-profile module.
        baselineProfile ':baseline-profile'
    }
    
    // This is the plugin configuration.
    baselineProfile {
    
        // This filters the generated profile rules. In this example, you keep
        // all the classes in com.library and in all the subpackages.
        filter {
            include 'com.mylibrary.**'
        }
    }
    
  5. 更新应用模块 :sample-app 中的 build.gradle 配置,添加 androidx.baselineprofile 插件。
  6. Kotlin

    plugins {
        ...
        id("androidx.baselineprofile")
    }
    // There are no other changes to the configuration.
    

    Groovy

    plugins {
        ...
        id 'androidx.baselineprofile'
    }
    // There are no other changes to the configuration.
    
  7. 运行以下代码,生成配置文件:./gradlew :library:generateBaselineProfile

在生成任务结束时,基准配置文件会被存储在 library/src/main/generated/baselineProfiles 中。

DSL

虽然本文档将基准配置文件 Gradle 插件称为单个插件,但实际上有三个插件,它们会根据所应用到的模块执行不同的任务。本文档中的插件 ID 为 androidx.baselineprofile,是这三个插件的快捷方式。

如需更好地了解此概念,请参阅生成基准配置文件所需的以下模块:

  • 要运行基准配置文件测试所针对的应用。这是一个应用了 com.android.application 的 Android 应用模块。为库生成配置文件时,这可能是一个示例应用。为应用生成配置文件时,它是应用本身。在以下示例中,androidx.baselineprofile 插件在内部应用了 androidx.baselineprofile.apptarget
  • 包含要运行的测试的基准配置文件测试模块。这是一个应用了 com.android.test 的 Android 测试模块。在以下示例中,androidx.baselineprofile 插件在内部应用了 androidx.baselineprofile.producer
  • 构建流程中最终使用基准配置文件的模块。这是一个 Android 应用 com.android.application 或库 com.android.library 模块。在以下示例中,androidx.baselineprofile 插件在内部应用了 androidx.baselineprofile.consumer

应用目标 (androidx.baselineprofile.apptarget)

这没有任何配置。

配置文件生产方 (androidx.baselineprofile.producer)

支持 Gradle 管理的设备

如需使用 Gradle 管理的设备,请在配置文件生产方模块的 build.gradle 配置中添加一部 Gradle 管理的设备,如以下示例所示:

Kotlin

android {
   testOptions.managedDevices.devices {
       create("pixel6Api31") {
           device = "Pixel 6"
           apiLevel = 31
           systemImageSource = "aosp"
       }
   }
}

Groovy

android {
   testOptions.managedDevices.devices {
       pixel6Api31(ManagedVirtualDevice) {
           device 'Pixel 6'
           apiLevel = 31
           systemImageSource 'aosp'
       }
   }
}

然后,您可以使用创建的 GMD,通过将它添加到以下代码中来生成基准配置文件:

Kotlin

baselineProfile {
    managedDevices += "pixel6Api31"
}

Groovy

baselineProfile {
    managedDevices = ['pixel6Api31']
}

以下示例是其他可选代码,可用于启用或停用已连接设备以生成基准配置文件:

Kotlin

baselineProfile {
    ...
    useConnectedDevices = true
}

Groovy

baselineProfile {
    ...
    useConnectedDevices true
}

配置文件使用方 (androidx.baselineprofile.consumer)

为每个变种生成配置文件/为所有变体生成一个配置文件

您可以为每个变体、每个变种生成配置文件,也可以将配置文件生成为单个文件用于所有变体。您可以通过合并设置控制此行为,如以下示例所示。

Kotlin

baselineProfile {
    mergeIntoMain = true
}

Groovy

baselineProfile {
    mergeIntoMain true
}
  • mergeIntoMain 设为 true,可将为每个变体生成的所有配置文件合并到一个配置文件中。此设置为 true 时,无法为每个变体生成基准配置文件,因此只存在一个名为 generateBaselineProfile 的生成任务。配置文件输出路径为 src/main/generated/baselineProfiles
  • mergeIntoMain 设为 false 可停用合并设置,让每个变体都有一个配置文件。在下例中,可以为每个变体生成基准配置文件,因此存在多个生成任务(每个变体对应一个任务)。举个例子,当有两个变种(比如免费和付费变种)和一个发布 build 类型时,生成的任务如下所示:
    • generateFreeReleaseBaselineProfile
    • generatePaidReleaseBaselineProfile
    • generateReleaseBaselineProfile

默认情况下,对于库,此设置为 true;对于应用,此设置为 false

您还可以按变体指定此行为:

Kotlin

baselineProfile {
    variants {
        freeRelease {
            mergeIntoMain = true
        }
    }
}

Groovy

baselineProfile {
    variants {
        freeRelease {
            mergeIntoMain true
        }
    }
}

在上面的示例中,标志设为 true 的所有变体都会合并到 src/main/generated/baselineProfiles 中,而标志设为 false 的变体对应的配置文件会保留在文件夹 src/<variant>/generated/baselineProfiles 中。

在组装新版本时自动生成基准配置文件

您可以通过任务 generateBaselineProfile 手动触发基准配置文件生成操作,也可以在构建版本时自动触发此操作。这由以下标志控制:

Kotlin

baselineProfile {
    automaticGenerationDuringBuild = true
}

Groovy

baselineProfile {
    automaticGenerationDuringBuild true
}

将此标志设为 true 会触发为每次组装生成新的基准配置文件。这样一来,build 中就会包含最新的配置文件。这意味着,运行发布 build 组装任务(例如 ./gradlew:app:assembleRelease)也会触发 :app:generateReleaseBaselineProfile。此操作还会启动基准配置文件插桩测试,并构建用于运行这些测试的基准配置文件 build。虽然这有助于确保用户获得最佳性能优势,但由于需要进行双重构建和插桩测试,这也会增加构建时间。

您还可以按变体指定此行为,如以下示例所示:

Kotlin

baselineProfile {
    variants {
        freeRelease {
            automaticallyGenerateDuringBuild = true
        }
    }
}

Groovy

baselineProfile {
    variants {
        freeRelease {
            automaticallyGenerateDuringBuild true
        }
    }
}

在前面的示例中,generateFreeReleaseBaselineProfile 任务会在开始 assembleFreeRelease 时运行。这有时会很有帮助,比如在以下情况下:用户想有一个针对分发 build 的 release(始终会在构建时生成配置文件),和一个针对内部测试的 releaseWithoutProfile

将基准配置文件存储到源目录中

您可以通过 saveInSrc 标志将基准配置文件存储在源目录中:

  • true:基准配置文件存储在 src/<variant>/generated/baselineProfiles 中。这样,您就可以使用源目录提交最新生成的配置文件。
  • false:基准配置文件存储在 build 目录下的中间文件中。这样,您在提交代码时不会保存最新生成的配置文件。

Kotlin

baselineProfile {
    saveInSrc = true
}

Groovy

baselineProfile {
    saveInSrc true
}

您还可以按变体指定此行为:

Kotlin

baselineProfile {
    variants {
        freeRelease {
            saveInSrc = true
        }
    }
}

Groovy

baselineProfile {
    variants {
        freeRelease {
            saveInSrc true
        }
    }
}
过滤配置文件规则

您可以通过插件配置来过滤生成的基准配置文件规则。如果您想为示例应用或库自身的其他依赖项中的类和方法排除配置文件规则,上述过滤对库特别有帮助。过滤条件可以针对软件包和类实现指定、包含和排除操作。当您仅指定排除项时,系统仅会排除匹配的基准配置文件规则,所有其他规则都会被包含在内。

过滤条件规范可以是以下任意一种:

  • 以双通配符结尾的软件包名称,与指定的软件包和所有子软件包匹配。例如,com.example.**com.example.methodcom.example.method.bar 匹配。
  • 以通配符结尾的软件包名称,仅与指定的软件包匹配。例如,com.example.*com.example.method 匹配,但与 com.example.method.bar 不匹配。
  • 匹配特定类(例如 com.example.MyClass)的类名称。

以下示例展示了如何包含和排除特定软件包:

Kotlin

baselineProfile {
    filter {
        include("com.somelibrary.widget.grid.**")
        exclude("com.somelibrary.widget.grid.debug.**")
        include("com.somelibrary.widget.list.**")
        exclude("com.somelibrary.widget.list.debug.**")
        include("com.somelibrary.widget.text.**")
        exclude("com.somelibrary.widget.text.debug.**")
    }
}

Groovy

baselineProfile {
    filter {
        include 'com.somelibrary.widget.grid.**'
        exclude 'com.somelibrary.widget.grid.debug.**'
        include 'com.somelibrary.widget.list.**'
        exclude 'com.somelibrary.widget.list.debug.**'
        include 'com.somelibrary.widget.text.**'
        exclude 'com.somelibrary.widget.text.debug.**'
    }
}

过滤条件也支持变体,您可以按如下方式表示它们:

Kotlin

// Non-specific filters applied to all the variants.
baselineProfile {
    filter { include("com.myapp.**") }
}

// Flavor-specific filters.
baselineProfile {
    variants {
        free {
            filter {
                include("com.myapp.free.**")
            }
        }
        paid {
            filter {
                include("com.myapp.paid.**")
            }
        }
    }
}

// Build-type-specific filters.
baselineProfile {
    variants {
        release {
            filter {
                include("com.myapp.**")
            }
        }
    }
}

// Variant-specific filters.
baselineProfile {
    variants {
        freeRelease {
            filter {
                include("com.myapp.**")
            }
        }
    }
}

Groovy

// Non-specific filters applied to all the variants.
baselineProfile {
    filter { include 'com.myapp.**' }
}

// Flavor-specific filters.
baselineProfile {
    variants {
        free {
            filter {
                include 'com.myapp.free.**'
            }
        }
        paid {
            filter {
                include 'com.myapp.paid.**'
            }
        }
    }
}

// Build-type specific filters.
baselineProfile {
    variants {
        release {
            filter {
                include 'com.myapp.**'
            }
        }
    }
}

// Variant-specific filters.
baselineProfile {
    variants {
        freeRelease {
            filter {
                include 'com.myapp.**'
            }
        }
    }
}

您还可以在 BaselineProfileRule.collect() 中使用 filterPredicate 参数来过滤规则,但我们建议您使用 Gradle 插件进行过滤,因为这种方法可让您更轻松地过滤子软件包以及在同一位置配置整个模块。

(可选)手动应用生成的规则

基准配置文件生成器会在设备上创建一个人类可读格式 (HRF) 的文本文件,并会将其复制到宿主机中。若要将生成的配置文件应用于您的代码,请按照以下步骤操作:

  1. 在您生成配置文件时所用模块的 build 文件夹中找到 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/flavor/baselineProfiles。如需将配置文件应用于所有变种,请将其复制到 src/main/baselineProfiles

  3. 在应用的 build.gradle.kts 文件中为 ProfileInstaller 库添加一个依赖项,以便在云配置文件不可用的情况下启用本地基准配置文件编译。这是在本地旁加载基准配置文件的唯一方式。

    dependencies {
         implementation("androidx.profileinstaller:profileinstaller:1.3.1")
    }
    
  4. 构建应用的正式版,在此期间,所应用的 HRF 规则会被编译成二进制形式,并且会包含在 APK 或 AAB 中。然后,照常分发您的应用。

其他说明

创建基准配置文件时,还需要注意一些其他事项:

  • 已编译的基准配置文件必须小于 1.5 MB。此规则不适用于源文件中的文本格式,源文件在编译之前通常会比 1.5 MB 大出很多。如需验证二进制基准配置文件的大小,请在输出工件中找到相应文件(APK:位于 assets/dexopt/baseline.prof 下;AAB:位于 BUNDLE-METADATA/com.android.tools.build.profiles/baseline.prof 下)。

  • 如果宽泛规则对应用编译过多,就会增加磁盘访问,进而降低启动速度。如果您刚开始使用基准配置文件,无需担心。不过,添加大量历程可能会导致性能不够理想,具体取决于您的应用以及历程的大小和数量。请尝试通过使用不同的配置文件和确认新增历程不会导致性能降低来测试性能。

  • 如果您使用的是自动完整性保护功能,Google Play 会更改您的 APK 或 AAB。Google Play 不会将基准配置文件考虑到这些更改中。因此,基准配置文件与自动完整性保护功能不兼容。

Codelab

深入探究宏基准测试来衡量性能。
为具体 Android 应用生成量身定制的自定义基准配置文件,并验证其有效性。