A profile is recorded, not written: a test drives the app through its critical journeys while the runtime logs every class and method it touches. Jetpack 234 's Macrobenchmark 234 library runs such tests from a separate com.android.test module that installs the app, controls it through UI Automator 234 , and reads the results back. Three pieces make it work (versions from Google's Maven 129 , 25 September 2026):
a :benchmark module with the com.android.test and androidx.baselineprofile plugins (1.5.0), targetProjectPath = ":app", and benchmark-macro-junit4 1.5.0 plus uiautomator 2.4.0;
in :app, the same androidx.baselineprofile plugin, baselineProfile(project(":benchmark")), and profileinstaller 1.4.1, which installs the profile even when the APK isn't installed by Play;
a generator test:
@RunWith(AndroidJUnit4::class)
class BaselineProfileGenerator {
@get:Rule val rule = BaselineProfileRule()
@Test fun startupAndCatalog() = rule.collect(packageName = PACKAGE) {
pressHome()
startActivityAndWait() // the cold-start path
device.wait(Until.hasObject(By.text("BookNest")), 10_000)
pressHome()
startActivityAndWait { it.putExtra("stage", "lazy") } // the 600-book catalog
val list = device.findObject(By.scrollable(true))
list.setGestureMargin(device.displayWidth / 5)
repeat(3) { list.fling(Direction.DOWN) } // the scroll path
}
}./gradlew :app:generateBaselineProfile builds a nonMinifiedRelease variant, which the plugin adds so method names in the profile are not obfuscated, runs the test on the connected device (an emulator needs androidx.benchmark.suppressErrors=EMULATOR, since emulator timings aren't trusted for benchmarks) and copies the result into the source tree. The first attempt produced a profile full of names like SPLc71;-><init>(Lf71;...): with AGP 9.4.0's new optimization { enable = true } block, the plugin's nonMinifiedRelease variant was still minified (a 4.4 MB APK with a mapping file). Switching release to the classic isMinifyEnabled = true form (How R8 Works) fixed it, and the second run took 6 minutes:
A baseline profile was generated for the variant `release`: file:///home/dev/lane-ch5/booknest/app/src/release/generated/baselineProfiles/baseline-prof.txt Comparison with previous baseline profile: 10704 Old rules 28289 New rules ... BUILD SUCCESSFUL in 6m
The file is plain text in ART's rule format: L marks a class to load at startup, and on a method H, S and P mean hot, used during startup, and used after startup. Of its 28,288 lines, 860 name BookNest's own code, for example SPLcom/example/booknest/ui/BookScreensKt;->CatalogList(...)V; the rest cover libraries. Commit the file and regenerate it when the journeys change.