Skip to content

Commit 31e3ddf

Browse files
committed
Merge remote-tracking branch 'origin/release' into develop
2 parents fa40640 + 9d1a5d9 commit 31e3ddf

File tree

14 files changed

+55565
-17
lines changed

14 files changed

+55565
-17
lines changed

app/build.gradle.kts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ plugins {
44
id("ndgl.application")
55
alias(libs.plugins.google.services)
66
alias(libs.plugins.firebase.crashlytics)
7+
alias(libs.plugins.baselineprofile)
78
}
89

910
android {
@@ -72,4 +73,7 @@ dependencies {
7273
implementation(libs.androidx.navigation3.ui)
7374
implementation(libs.androidx.lifecycle.viewmodel.navigation3)
7475
implementation(libs.androidx.core.splashscreen)
76+
implementation(libs.androidx.profileinstaller)
77+
78+
"baselineProfile"(project(":baselineprofile"))
7579
}

app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
android:theme="@style/Theme.NDGL"
1616
android:usesCleartextTraffic="true">
1717

18+
<profileable android:shell="true" tools:targetApi="q" />
19+
1820
<meta-data
1921
android:name="com.google.android.geo.API_KEY"
2022
android:value="${MAPS_API_KEY}" />

app/src/release/generated/baselineProfiles/baseline-prof.txt

Lines changed: 27661 additions & 0 deletions
Large diffs are not rendered by default.

app/src/release/generated/baselineProfiles/startup-prof.txt

Lines changed: 27661 additions & 0 deletions
Large diffs are not rendered by default.

baselineProfile/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

baselineProfile/build.gradle.kts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
plugins {
2+
alias(libs.plugins.android.test)
3+
alias(libs.plugins.kotlin.android)
4+
alias(libs.plugins.baselineprofile)
5+
}
6+
7+
android {
8+
namespace = "com.yapp.ndgl.baselineprofile"
9+
compileSdk {
10+
version = release(36) {
11+
minorApiLevel = 1
12+
}
13+
}
14+
15+
compileOptions {
16+
sourceCompatibility = JavaVersion.VERSION_11
17+
targetCompatibility = JavaVersion.VERSION_11
18+
}
19+
20+
kotlinOptions {
21+
jvmTarget = "11"
22+
}
23+
24+
defaultConfig {
25+
minSdk = 28
26+
targetSdk = 36
27+
28+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
29+
}
30+
31+
targetProjectPath = ":app"
32+
}
33+
34+
// This is the configuration block for the Baseline Profile plugin.
35+
// You can specify to run the generators on a managed devices or connected devices.
36+
baselineProfile {
37+
useConnectedDevices = true
38+
}
39+
40+
dependencies {
41+
implementation(libs.androidx.junit)
42+
implementation(libs.androidx.espresso.core)
43+
implementation(libs.androidx.uiautomator)
44+
implementation(libs.androidx.benchmark.macro.junit4)
45+
}
46+
47+
androidComponents {
48+
onVariants { v ->
49+
val artifactsLoader = v.artifacts.getBuiltArtifactsLoader()
50+
v.instrumentationRunnerArguments.put(
51+
"targetAppId",
52+
v.testedApks.map { artifactsLoader.load(it)?.applicationId },
53+
)
54+
}
55+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<manifest />
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.yapp.ndgl.baselineprofile
2+
3+
import androidx.benchmark.macro.junit4.BaselineProfileRule
4+
import androidx.test.ext.junit.runners.AndroidJUnit4
5+
import androidx.test.filters.LargeTest
6+
import androidx.test.platform.app.InstrumentationRegistry
7+
import org.junit.Rule
8+
import org.junit.Test
9+
import org.junit.runner.RunWith
10+
11+
/**
12+
* This test class generates a basic startup baseline profile for the target package.
13+
*
14+
* We recommend you start with this but add important user flows to the profile to improve their performance.
15+
* Refer to the [baseline profile documentation](https://d.android.com/topic/performance/baselineprofiles)
16+
* for more information.
17+
*
18+
* You can run the generator with the "Generate Baseline Profile" run configuration in Android Studio or
19+
* the equivalent `generateBaselineProfile` gradle task:
20+
* ```
21+
* ./gradlew :app:generateReleaseBaselineProfile
22+
* ```
23+
* The run configuration runs the Gradle task and applies filtering to run only the generators.
24+
*
25+
* Check [documentation](https://d.android.com/topic/performance/benchmarking/macrobenchmark-instrumentation-args)
26+
* for more information about available instrumentation arguments.
27+
*
28+
* After you run the generator, you can verify the improvements running the [StartupBenchmarks] benchmark.
29+
*
30+
* When using this class to generate a baseline profile, only API 33+ or rooted API 28+ are supported.
31+
*
32+
* The minimum required version of androidx.benchmark to generate a baseline profile is 1.2.0.
33+
**/
34+
@RunWith(AndroidJUnit4::class)
35+
@LargeTest
36+
class BaselineProfileGenerator {
37+
38+
@get:Rule
39+
val rule = BaselineProfileRule()
40+
41+
@Test
42+
fun generate() {
43+
// The application id for the running build variant is read from the instrumentation arguments.
44+
rule.collect(
45+
packageName = InstrumentationRegistry.getArguments().getString("targetAppId")
46+
?: throw Exception("targetAppId not passed as instrumentation runner arg"),
47+
48+
// See: https://d.android.com/topic/performance/baselineprofiles/dex-layout-optimizations
49+
includeInStartupProfile = true,
50+
) {
51+
// This block defines the app's critical user journey. Here we are interested in
52+
// optimizing for app startup. But you can also navigate and scroll through your most important UI.
53+
54+
// Start default activity for your app
55+
pressHome()
56+
startActivityAndWait()
57+
58+
// TODO Write more interactions to optimize advanced journeys of your app.
59+
// For example:
60+
// 1. Wait until the content is asynchronously loaded
61+
// 2. Scroll the feed content
62+
// 3. Navigate to detail screen
63+
64+
// Check UiAutomator documentation for more information how to interact with the app.
65+
// https://d.android.com/training/testing/other-components/ui-automator
66+
}
67+
}
68+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.yapp.ndgl.baselineprofile
2+
3+
import androidx.benchmark.macro.BaselineProfileMode
4+
import androidx.benchmark.macro.CompilationMode
5+
import androidx.benchmark.macro.StartupMode
6+
import androidx.benchmark.macro.StartupTimingMetric
7+
import androidx.benchmark.macro.junit4.MacrobenchmarkRule
8+
import androidx.test.ext.junit.runners.AndroidJUnit4
9+
import androidx.test.filters.LargeTest
10+
import androidx.test.platform.app.InstrumentationRegistry
11+
import org.junit.Rule
12+
import org.junit.Test
13+
import org.junit.runner.RunWith
14+
15+
/**
16+
* This test class benchmarks the speed of app startup.
17+
* Run this benchmark to verify how effective a Baseline Profile is.
18+
* It does this by comparing [CompilationMode.None], which represents the app with no Baseline
19+
* Profiles optimizations, and [CompilationMode.Partial], which uses Baseline Profiles.
20+
*
21+
* Run this benchmark to see startup measurements and captured system traces for verifying
22+
* the effectiveness of your Baseline Profiles. You can run it directly from Android
23+
* Studio as an instrumentation test, or run all benchmarks for a variant, for example benchmarkRelease,
24+
* with this Gradle task:
25+
* ```
26+
* ./gradlew :baselineprofile:connectedBenchmarkReleaseAndroidTest
27+
* ```
28+
*
29+
* You should run the benchmarks on a physical device, not an Android emulator, because the
30+
* emulator doesn't represent real world performance and shares system resources with its host.
31+
*
32+
* For more information, see the [Macrobenchmark documentation](https://d.android.com/macrobenchmark#create-macrobenchmark)
33+
* and the [instrumentation arguments documentation](https://d.android.com/topic/performance/benchmarking/macrobenchmark-instrumentation-args).
34+
**/
35+
@RunWith(AndroidJUnit4::class)
36+
@LargeTest
37+
class StartupBenchmarks {
38+
39+
@get:Rule
40+
val rule = MacrobenchmarkRule()
41+
42+
@Test
43+
fun startupCompilationNone() =
44+
benchmark(CompilationMode.None())
45+
46+
@Test
47+
fun startupCompilationBaselineProfiles() =
48+
benchmark(CompilationMode.Partial(BaselineProfileMode.Require))
49+
50+
private fun benchmark(compilationMode: CompilationMode) {
51+
// The application id for the running build variant is read from the instrumentation arguments.
52+
rule.measureRepeated(
53+
packageName = InstrumentationRegistry.getArguments().getString("targetAppId")
54+
?: throw Exception("targetAppId not passed as instrumentation runner arg"),
55+
metrics = listOf(StartupTimingMetric()),
56+
compilationMode = compilationMode,
57+
startupMode = StartupMode.COLD,
58+
iterations = 10,
59+
setupBlock = {
60+
pressHome()
61+
},
62+
measureBlock = {
63+
startActivityAndWait()
64+
65+
// TODO Add interactions to wait for when your app is fully drawn.
66+
// The app is fully drawn when Activity.reportFullyDrawn is called.
67+
// For Jetpack Compose, you can use ReportDrawn, ReportDrawnWhen and ReportDrawnAfter
68+
// from the AndroidX Activity library.
69+
70+
// Check the UiAutomator documentation for more information on how to
71+
// interact with the app.
72+
// https://d.android.com/training/testing/other-components/ui-automator
73+
},
74+
)
75+
}
76+
}

build-logic/src/main/kotlin/Configuration.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ object Configuration {
55
const val COMPILE_SDK = 36
66
const val TARGET_SDK = 36
77

8-
const val VERSION_CODE = 1
9-
const val VERSION_NAME = "1.0.0"
8+
const val VERSION_CODE = 2
9+
const val VERSION_NAME = "1.0.1"
1010

1111
val JAVA_VERSION = JavaVersion.VERSION_17
1212
const val JVM_TARGET = "17"

0 commit comments

Comments
 (0)