Automatycznie generuj profile dla każdej wersji aplikacji za pomocą biblioteki Jetpack
Macrobenchmark i
BaselineProfileRule. Zalecamy używanie wersji com.android.tools.build:gradle:8.0.0 lub nowszej, która zapewnia lepszą kompilację podczas korzystania z profili podstawowych.
Oto ogólne kroki tworzenia nowego profilu podstawowego:
- Skonfiguruj moduł profilu podstawowego.
- Zdefiniuj test JUnit, który pomoże wygenerować profile podstawowe.
- Dodaj najważniejsze ścieżki użytkownika, które chcesz zoptymalizować.
- Wygeneruj profil podstawowy.
Po wygenerowaniu profilu podstawowego przeprowadź test porównawczy na urządzeniu fizycznym, aby zmierzyć poprawę szybkości.
Tworzenie nowego profilu podstawowego za pomocą AGP 8.2 lub nowszego
Najłatwiejszym sposobem utworzenia nowego profilu podstawowego jest użycie szablonu modułu profilu podstawowego, który jest dostępny od wersji Android Studio Iguana i wtyczki Androida do obsługi Gradle (AGP) 8.2.
Szablon modułu generatora profilu podstawowego w Android Studio automatyzuje tworzenie nowego modułu do generowania i testowania porównawczego profili podstawowych. Uruchomienie szablonu generuje większość typowej konfiguracji kompilacji, profilu podstawowego oraz kodu weryfikacyjnego. Szablon tworzy kod do generowania i testowania porównawczego profili podstawowych w celu pomiaru czasu uruchamiania aplikacji.
Konfigurowanie modułu profilu podstawowego
Aby uruchomić szablon modułu profilu podstawowego, wykonaj te czynności:
- Kliknij File > New > New Module (Plik > Nowy > Nowy moduł).
- W panelu
Templates (Szablony) wybierz szablon Baseline Profile Generator (Generator profilu podstawowego) i skonfiguruj go:
Figure 1. (Rysunek 1.) Szablon modułu generatora profilu podstawowego. Pola w szablonie są następujące:
- Target application (Aplikacja docelowa): określa, dla której aplikacji ma zostać wygenerowany profil podstawowy. Jeśli w projekcie masz tylko 1 moduł aplikacji, na tej liście będzie tylko 1 element.
- Module name (Nazwa modułu): nazwa, którą chcesz nadać tworzonemu modułowi profilu podstawowego.
- Package name (Nazwa pakietu): nazwa pakietu, którą chcesz nadać modułowi profilu podstawowego.
- Language (Język): czy wygenerowany kod ma być w języku Kotlin czy Java.
- Build configuration language (Język konfiguracji kompilacji): czy w skryptach konfiguracji kompilacji chcesz używać skryptu Kotlin (KTS) czy Groovy.
- Use Gradle-managed device (Użyj urządzenia zarządzanego przez Gradle): jeśli do testowania aplikacji używasz urządzeń zarządzanych przez Gradle.
- Kliknij Finish (Zakończ), aby utworzyć nowy moduł. Jeśli używasz kontroli źródła, może pojawić się prośba o dodanie nowo utworzonych plików modułu do kontroli źródła.
Definiowanie generatora profilu podstawowego
Nowo utworzony moduł zawiera testy, które służą do generowania i testowania porównawczego profilu podstawowego oraz do testowania tylko podstawowego uruchamiania aplikacji. Zalecamy rozszerzenie tych testów o najważniejsze ścieżki użytkownika i zaawansowane procesy uruchamiania. Upewnij się, że wszystkie testy związane z uruchamianiem aplikacji znajdują się w bloku rule z ustawioną wartością includeInStartupProfile na true. Z kolei, aby uzyskać optymalną wydajność, upewnij się, że wszystkie testy niezwiązane z uruchamianiem aplikacji nie są uwzględniane w profilu uruchamiania. Optymalizacje uruchamiania aplikacji
służą do definiowania specjalnej części profilu podstawowego, zwanej
profilem uruchamiania.
Aby ułatwić utrzymanie, warto wyodrębnić te najważniejsze ścieżki użytkownika poza wygenerowany profil podstawowy i kod testu porównawczego, aby można było ich używać w obu przypadkach. Oznacza to, że zmiany w najważniejszych ścieżkach użytkownika są stosowane konsekwentnie.
Generowanie i instalowanie profilu podstawowego
Szablon modułu profilu podstawowego dodaje nową konfigurację uruchamiania, która służy do generowania profilu podstawowego. Jeśli używasz wariantów produktu, Android Studio tworzy wiele konfiguracji uruchamiania, dzięki czemu możesz generować osobne profile podstawowe dla każdego wariantu.
Po zakończeniu konfiguracji uruchamiania Generate Baseline Profile (Wygeneruj profil podstawowy) wygenerowany profil podstawowy jest kopiowany do
pliku
src/variant/generated/baselineProfiles/baseline-prof.txt
w profilowanym module. Opcje wariantu to rodzaj kompilacji do publikacji lub wariant kompilacji obejmujący rodzaj kompilacji do publikacji.
Wygenerowany profil podstawowy jest pierwotnie tworzony w katalogu build/outputs. Pełna ścieżka jest określana przez wariant lub wersję profilowanej aplikacji oraz przez to, czy do profilowania używasz urządzenia zarządzanego przez Gradle czy podłączonego urządzenia. Jeśli używasz nazw używanych przez kod i konfiguracje kompilacji wygenerowane przez szablon, profil podstawowy jest tworzony w pliku build/outputs/managed_device_android_test_additional_output/nonminifiedrelease/pixel6Api31/BaselineProfileGenerator_generate-baseline-prof.txt. Prawdopodobnie nie będziesz musiał(-a) bezpośrednio korzystać z tej wersji wygenerowanego profilu podstawowego, chyba że ręcznie skopiujesz go do modułów docelowych (niezalecane).
Tworzenie nowego profilu podstawowego za pomocą AGP 8.1
Jeśli nie możesz użyć szablonu modułu profilu podstawowego, utwórz nowy profil podstawowy za pomocą szablonu modułu Macrobenchmark i wtyczki Gradle profilu podstawowego. Zalecamy korzystanie z tych narzędzi od wersji Android Studio Giraffe i AGP 8.1.
Aby utworzyć nowy profil podstawowy za pomocą szablonu modułu Macrobenchmark i wtyczki Gradle profilu podstawowego:
- Skonfiguruj moduł Macrobenchmark w projekcie Gradle.
- Zdefiniuj nową klasę o nazwie
BaselineProfileGenerator:class BaselineProfileGenerator { @get:Rule val baselineProfileRule = BaselineProfileRule() @Test fun startup() = baselineProfileRule.collect( packageName = "com.example.app", profileBlock = { startActivityAndWait() } ) }
Generator może zawierać interakcje z aplikacją wykraczające poza uruchamianie aplikacji. Dzięki temu możesz zoptymalizować wydajność aplikacji w czasie działania, np. przewijanie list, uruchamianie animacji i nawigowanie w obrębie
Activity. Zobacz inne przykłady testów, które używają@BaselineProfileRuledo poprawy najważniejszych ścieżek użytkownika. Dodaj wtyczkę Gradle profilu podstawowego (
libs.plugins.androidx.baselineprofile). Wtyczka ułatwia generowanie profili podstawowych i ich utrzymywanie w przyszłości.Aby wygenerować profil podstawowy, uruchom w terminalu zadania Gradle
:app:generateBaselineProfilelub:app:generateVariantBaselineProfile.Uruchom generator jako test instrumentowany na urządzeniu fizycznym z rootem, emulatorze lub urządzeniu zarządzanym przez Gradle. Jeśli używasz urządzenia zarządzanego przez Gradle, ustaw
aospjakosystemImageSource, ponieważ do generatora profilu podstawowego potrzebujesz dostępu do roota.Po zakończeniu zadania generowania profil podstawowy jest kopiowany do
app/src/variant/generated/baselineProfiles.
Tworzenie nowego profilu podstawowego bez szablonów
Zalecamy utworzenie profilu podstawowego za pomocą szablonu modułu profilu podstawowego w Android Studio profilu podstawowego (preferowane) lub szablonu Macrobenchmark, ale możesz też użyć samej wtyczki Gradle profilu podstawowego. Więcej informacji o wtyczce Gradle profilu podstawowego znajdziesz w artykule Konfigurowanie generowania profilu podstawowego.
Aby utworzyć profil podstawowy bezpośrednio za pomocą wtyczki Gradle profilu podstawowego:
- Utwórz nowy moduł
com.android.test, np.:baseline-profile. Skonfiguruj plik
build.gradle.ktsdla modułu:baseline-profile:- Zastosuj wtyczkę
androidx.baselineprofile. - Upewnij się, że
targetProjectPathwskazuje moduł:app. - Opcjonalnie dodaj urządzenie zarządzane przez Gradle
(GMD).
W tym przykładzie jest to
pixel6Api31. Jeśli nie zostanie określone, wtyczka używa podłączonego urządzenia, emulowanego lub fizycznego. - Zastosuj wybraną konfigurację, jak pokazano w tym przykładzie.
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 }
Dynamiczny
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 }
- Zastosuj wtyczkę
Utwórz test profilu podstawowego w module testowym
:baseline-profile. Poniższy przykład to test, który generuje profil podstawowy na potrzeby uruchamiania aplikacji.Kotlin
class BaselineProfileGenerator { @get:Rule val baselineProfileRule = BaselineProfileRule() @Test fun startup() = baselineProfileRule.collect( packageName = "com.example.app", profileBlock = { uiAutomator { startApp(PACKAGE_NAME) } } ) }
Java
public class BaselineProfileGenerator { @Rule Public BaselineProfileRule baselineRule = new BaselineProfileRule(); @Test Public void startupBaselineProfile() { baselineRule.collect( "com.myapp", (scope -> { scope.startActivityAndWait(); Return Unit.INSTANCE; }) ) } }
Zaktualizuj plik
build.gradle.ktsw module aplikacji, np.:app.- Zastosuj wtyczkę
androidx.baselineprofile. - Dodaj zależność
baselineProfiledo modułu: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 on the `:baseline-profile` module. baselineProfile(project(":baseline-profile")) }
Dynamiczny
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' }
- Zastosuj wtyczkę
Wygeneruj profil, uruchamiając zadania Gradle
:app:generateBaselineProfilelub:app:generateVariantBaselineProfile.Po zakończeniu zadania generowania profil podstawowy jest kopiowany do
app/src/variant/generated/baselineProfiles.
Tworzenie nowego profilu podstawowego za pomocą AGP 7.3–7.4
Profile podstawowe można generować za pomocą AGP 7.3–7.4, ale zdecydowanie zalecamy uaktualnienie do co najmniej AGP 8.1, aby móc korzystać z wtyczki Gradle profilu podstawowego i jej najnowszych funkcji.
Jeśli musisz utworzyć profile podstawowe za pomocą AGP 7.3–7.4, wykonaj te same czynności co w przypadku AGP 8.1, z tymi wyjątkami:
- Nie dodawaj wtyczki Gradle profilu podstawowego.
- Aby wygenerować profile podstawowe, wykonaj zadanie Gradle
./gradlew [emulator name][flavor][build type]AndroidTest. Na przykład./gradlew :benchmark:pixel6Api31BenchmarkAndroidTest. - Musisz ręcznie zastosować wygenerowane reguły profilu podstawowego do kodu.
Ręczne stosowanie wygenerowanych reguł
Generator profilu podstawowego tworzy na urządzeniu plik tekstowy w formacie HRF (Human Readable Format) i kopiuje go na komputer hosta. Aby zastosować wygenerowany profil do kodu:
Znajdź plik HRF w folderze kompilacji modułu, w którym generujesz profil:
[module]/build/outputs/managed_device_android_test_additional_output/[device].Profile są zgodne ze wzorcem nazewnictwa
[class name]-[test method name]-baseline-prof.txt, który wygląda tak:BaselineProfileGenerator-startup-baseline-prof.txt.Skopiuj wygenerowany profil do katalogu
src/main/i zmień nazwę pliku nabaseline-prof.txt.Aby włączyć lokalną kompilację profilu podstawowego, gdy profile w chmurze są niedostępne, dodaj zależność do biblioteki ProfileInstaller w pliku
build.gradle.ktsaplikacji. Jest to jedyny sposób na lokalne wczytanie profilu podstawowego.dependencies { implementation("androidx.profileinstaller:profileinstaller:1.4.1") }Skompiluj wersję produkcyjną aplikacji, podczas gdy zastosowane reguły HRF są kompilowane do postaci binarnej i dołączane do pliku APK lub AAB. Następnie rozpowszechnij aplikację w zwykły sposób.
Testowanie porównawcze profilu podstawowego
Aby przeprowadzić test porównawczy profilu podstawowego, utwórz nową konfigurację uruchamiania testu instrumentowanego na Androida za pomocą działania w rynnie, które wykonuje testy porównawcze zdefiniowane w pliku StartupBenchmarks.kt lub StartupBencharks.java. Więcej informacji o testach porównawczych
znajdziesz w artykułach Tworzenie klasy Macrobenchmark
i Automatyzowanie pomiarów za pomocą biblioteki Macrobenchmark.
Gdy uruchomisz tę konfigurację w Android Studio, dane wyjściowe kompilacji będą zawierać szczegóły dotyczące poprawy szybkości, jaką zapewnia profil podstawowy:
StartupBenchmarks_startupCompilationBaselineProfiles timeToInitialDisplayMs min 161.8, median 178.9, max 194.6 StartupBenchmarks_startupCompilationNone timeToInitialDisplayMs min 184.7, median 196.9, max 202.9
Przechwytywanie wszystkich wymaganych ścieżek kodu
Dwa kluczowe wskaźniki do pomiaru czasu uruchamiania aplikacji:
- Czas do początkowego wyświetlania (TTID)
- Czas potrzebny do wyświetlenia pierwszej klatki interfejsu aplikacji.
- Czas do pełnego wyświetlenia (TTFD)
- TTID plus czas potrzebny do wyświetlenia treści, które są ładowane asynchronicznie po wyświetleniu pierwszej klatki.
TTFD jest zgłaszany po wywołaniu
reportFullyDrawn()
metody
ComponentActivity. Jeśli metoda reportFullyDrawn() nie zostanie nigdy wywołana, zamiast niej zgłaszany jest TTID. Może być konieczne opóźnienie wywołania metody reportFullyDrawn() do momentu zakończenia ładowania asynchronicznego. Jeśli na przykład interfejs zawiera listę dynamiczną, taką jak RecyclerView lub lista leniwa, lista może być wypełniana przez zadanie w tle, które kończy się po pierwszym narysowaniu listy, a tym samym po oznaczeniu interfejsu jako w pełni narysowanego. W takich przypadkach kod, który jest uruchamiany po osiągnięciu przez interfejs stanu pełnego narysowania, nie jest uwzględniany w profilu podstawowym.
Aby uwzględnić wypełnianie listy w profilu podstawowym, pobierz
FullyDrawnReporter za pomocą
getFullyDrawnReporter()
i dodaj do niego reportera w kodzie aplikacji. Zwolnij reportera, gdy zadanie w tle zakończy wypełnianie listy. Metoda reportFullyDrawn() nie jest wywoływana przez FullyDrawnReporter do momentu zwolnienia wszystkich reporterów. Dzięki temu profil podstawowy zawiera ścieżki kodu wymagane do wypełnienia listy.
Nie zmienia to zachowania aplikacji w przypadku użytkownika, ale pozwala profilowi podstawowemu uwzględnić wszystkie niezbędne ścieżki kodu.
Jeśli Twoja aplikacja używa Jetpack Compose, użyj tych interfejsów API, aby wskazać stan pełnego narysowania:
ReportDrawnwskazuje, że element kompozycyjny jest natychmiast gotowy do interakcji.ReportDrawnWhenprzyjmuje predykat, np.list.count > 0, aby wskazać, kiedy element kompozycyjny jest gotowy do interakcji.ReportDrawnAfterprzyjmuje metodę zawieszającą, która po zakończeniu wskazuje, że element kompozycyjny jest gotowy do interakcji.
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy język JavaScript jest wyłączony.
- Przechwytywanie danych Macrobenchmark
- Pisanie testu Macrobenchmark
- Biblioteka JankStats