As an app developer, you can automatically generate profiles for every app
release by using the Jetpack Macrobenchmark library and
BaselineProfileRule
. It is recommended to use
com.android.tools.build:gradle:7.4.1
or higher, which
comes with build improvements when using Baseline Profiles.
Define Baseline Profile generator
To create Baseline Profiles using the Macrobenchmark library:
Set up a Macrobenchmark module in your Gradle project.
Define a new test called
BaselineProfileGenerator
that looks something like:@OptIn(ExperimentalBaselineProfilesApi::class) class BaselineProfileGenerator { @get:Rule val baselineProfileRule = BaselineProfileRule() @Test fun startup() = baselineProfileRule.collectBaselineProfile( packageName = "com.example.app", profileBlock = { startActivityAndWait() } ) }
The generator can contain interactions with your app beyond app startup. This lets you optimize runtime performance of your app, such as scrolling lists, running animations, navigating within an Activity, and others. View some other examples on tests that use
@BaselineProfileRule
to improve critical user journeys.(Optional) You must disable obfuscation when generating Baseline Profiles. You can do it by creating another Proguard file in your app module and adding
-dontobfuscate
, only for yourbenchmark
build type that is responsible for generating the profiles.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' // ... } }
Generate the Baseline Profile
Run the generator as an instrumented test on a rooted physical device, emulator, or Gradle managed device. To set up a managed device, open your
build.gradle.kts
file and within thetestOptions
configuration block, addmanagedDevices
,devices
, and create your definition of an emulator. Make sure to useaosp
as thesystemImageSource
because you need root access for the Baseline Profile generator.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 creates the required tasks based on the selected device name and the build variants available in the module. It is formatted as
[emulator_name][flavor][build type]AndroidTest
. This task can be executed from a terminal like this, :./gradlew :benchmark:pixel6Api31BenchmarkAndroidTest
Apply the generated rules
The Baseline Profile generator creates a human readable text file (HRF) on the device and also copies it into your host machine. Follow these steps to apply the generated profile to your code:
Locate it in build folder of the module you generated the profile in:
[module]/build/outputs/managed_device_android_test_additional_output/[device]
.Profiles follow the
[class name]-[test method name]-baseline-prof.txt
naming pattern, which looks like this:BaselineProfileGenerator-startup-baseline-prof.txt
.Copy the generated profile to
src/main/
of your app module, alongside yourAndroidManifest.xml
and rename the file tobaseline-prof.txt
.Add a dependency to the ProfileInstaller library in your app's
build.gradle
to enable local Baseline Profile compilation where Cloud Profiles aren't available. This is the only way to sideload a Baseline Profile locally.dependencies { implementation("androidx.profileinstaller:profileinstaller:1.2.2") }
Build the production version of your app, during which the applied HRF rules are compiled into binary form and included in the APK or AAB. Then distribute your app as usual.
Additional notes
When creating Baseline Profiles, there are some additional things to note:
Compiled Baseline Profiles must be smaller than 1.5 MB (this does not apply to the text format in your source files, which are typically much larger prior to compilation). You can verify the size of your binary baseline profile by locating it in the output artifact under
assets/dexopt/baseline.prof
for APK orBUNDLE-METADATA/com.android.tools.build.profiles/baseline.prof
for AAB.Broad rules that compile too much of the application can slow down startup due to increased disk access. If you're just starting with Baseline Profiles, you don't need to worry about it. But when you start adding a lot1 of journeys, you should test the performance of your app by trying different profiles and verifying the performance doesn't regress with the additions.
Codelabs
Inspect app performance with Macrobenchmark
Improve app performance with Baseline Profiles
-
Depending on your app size and the number journeys. ↩