Automatyczne generowanie profili dla każdej wersji aplikacji za pomocą biblioteki Macrobenchmark Jetpacka i BaselineProfileRule
. Zalecamy używanie wersji com.android.tools.build:gradle:8.0.0
lub nowszej, która zawiera ulepszenia kompilacji przy użyciu profili referencyjnych.
Oto ogólne instrukcje tworzenia nowego profilu bazowego:
- Skonfiguruj moduł Profil podstawowy.
- Zdefiniuj test JUnit, który pomoże wygenerować profile referencyjne.
- Dodaj główne ścieżki użytkownika, które chcesz zoptymalizować.
- Wygeneruj profil podstawowy.
Po wygenerowaniu profilu bazowego przeprowadź test porównawczy na fizycznym urządzeniu, aby zmierzyć poprawę szybkości.
Tworzenie nowego profilu referencyjnego za pomocą AGP 8.2 lub nowszej wersji
Najprostszym sposobem utworzenia nowego profilu bazowego jest użycie szablonu modułu profilu bazowego, który jest dostępny od wersji Android Studio Iguana i Android Gradle Plugin (AGP) 8.2.
Szablon modułu Generatora profili referencyjnych w Android Studio automatyzuje tworzenie nowego modułu służącego do generowania i porównywania profili referencyjnych. Uruchomienie szablonu powoduje wygenerowanie większości typowej konfiguracji, profilu bazowego i kodu weryfikacyjnego. Szablon tworzy kod do generowania i porównywania profili podstawowych, aby mierzyć czas uruchamiania aplikacji.
Konfigurowanie modułu profilu podstawowego
Aby uruchomić szablon modułu Profil bazowy:
- Kliknij Plik > Nowy > Nowy moduł.
- W panelu Szablony wybierz szablon Generator profilu podstawowego i skonfiguruj go:
Pola w szablonie:
- Docelowa aplikacja: określa, dla której aplikacji ma być generowany profil podstawowy. Jeśli w projekcie jest tylko 1 moduł aplikacji, na tej liście znajduje się tylko 1 element.
- Nazwa modułu: nazwa tworzonego modułu profilu podstawowego.
- Nazwa pakietu: nazwa pakietu, którą chcesz przypisać do modułu profilu podstawowego.
- Język: określ, czy wygenerowany kod ma być w języku Kotlin czy Java.
- Język konfiguracji kompilacji: określ, czy chcesz używać skryptów konfiguracji kompilacji w języku Kotlin Script (KTS) czy Groovy.
- Używanie urządzenia zarządzanego przez Gradle: określ, czy chcesz używać urządzeń zarządzanych przez Gradle do testowania aplikacji.
- Kliknij Gotowe, aby utworzyć nowy moduł. Jeśli korzystasz z kontroli źródła, możesz zobaczyć prośbę o dodanie nowo utworzonych plików modułów do kontroli źródła.
Definiowanie generatora profilu podstawowego
Nowo utworzony moduł zawiera testy służące do generowania i porównywania profilu bazowego oraz testowania tylko podstawowego uruchamiania aplikacji. Zalecamy rozszerzenie tych procesów o procesy związane z zapytaniami o udzielenie zgody użytkownika i zaawansowane procesy uruchamiania. Upewnij się, że wszystkie testy związane z uruchamianiem aplikacji znajdują się w bloku rule
, a wartość parametru includeInStartupProfile
jest ustawiona na true
. Z kolei, aby zapewnić optymalną wydajność, sprawdź, czy testy niezwiązane z uruchamianiem aplikacji nie są uwzględnione w profilu uruchamiania. Optymalizacje uruchamiania aplikacji służą do definiowania specjalnej części profilu bazowego o nazwie profil uruchamiania.
Aby ułatwić utrzymanie, warto wyodrębnić te dane z wygenerowanego profilu podstawowego i kodu testu porównawczego, aby można było ich używać w obu przypadkach. Oznacza to, że zmiany w CUJ są konsekwentnie stosowane.
Generowanie i instalowanie profilu podstawowego
Szablon modułu profilu podstawowego dodaje nową konfigurację uruchomienia, aby wygenerować profil podstawowy. Jeśli używasz wersji produktu, Android Studio tworzy wiele konfiguracji uruchomienia, aby umożliwić generowanie oddzielnych profili referencyjnych dla każdej wersji.
Po zakończeniu konfiguracji uruchomienia Generowanie profilu podstawowego wygenerowany profil podstawowy zostanie skopiowany do pliku src/variant/generated/baselineProfiles/baseline-prof.txt
w module, który jest profilowany. Opcje wariantów to typ kompilacji wersji lub wariant kompilacji, który wykorzystuje typ kompilacji wersji.
Wygenerowany profil podstawowy został pierwotnie utworzony w build/outputs
. Pełna ścieżka zależy od wariantu lub wersji aplikacji, której profil jest tworzony, oraz od tego, czy do profilowania używasz urządzenia zarządzanego przez Gradle, czy połączonego urządzenia. Jeśli używasz nazw używanych przez kod i konfiguracje kompilacji wygenerowane przez szablon, profil bazowy zostanie utworzony w pliku build/outputs/managed_device_android_test_additional_output/nonminifiedrelease/pixel6Api31/BaselineProfileGenerator_generate-baseline-prof.txt
. Prawdopodobnie nie będziesz musiał bezpośrednio korzystać z tej wersji wygenerowanego profilu podstawowego, chyba że będziesz go kopiować ręcznie do modułów docelowych (nie zalecane).
Tworzenie nowego profilu referencyjnego za pomocą AGP 8.1
Jeśli nie możesz użyć szablonu modułu profilu referencyjnego, użyj szablonu modułu makrobenchmarku i wtyczki Gradle do profilu referencyjnego, aby utworzyć nowy profil referencyjny. Zalecamy korzystanie z tych narzędzi od wersji Android Studio Giraffe i AGP 8.1.
Oto instrukcje tworzenia nowego profilu referencyjnego za pomocą szablonu modułu Macrobenchmark i wtyczki Gradle do profilu referencyjnego:
- 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 Twoją aplikacją poza jej uruchamianiem. Dzięki temu możesz optymalizować wydajność aplikacji w czasie działania, np. przewijanie list, uruchamianie animacji i przemieszczanie się w aplikacji.
Activity
Zobacz inne przykłady testów, które korzystają z funkcji@BaselineProfileRule
, aby poprawić najważniejsze ścieżki użytkowników. Dodaj wtyczkę Gradle do profilu podstawowego (
libs.plugins.androidx.baselineprofile
). Ułatwia ona generowanie profili podstawowych i ich utrzymywanie w przyszłości.Aby wygenerować profil bazowy, uruchom zadania Gradle
:app:generateBaselineProfile
lub:app:generateVariantBaselineProfile
w terminalu.Uruchom generator jako test z instrumentacją na urządzeniu fizycznym z rootem, w emulatorze lub na urządzeniu zarządzanym przez Gradle. Jeśli używasz urządzenia zarządzanego przez Gradle, jako
aosp
ustawsystemImageSource
, ponieważ do generatora profilu podstawowego potrzebny jest dostęp root.Po zakończeniu zadania generowania profil bazowy jest kopiowany do pliku
app/src/variant/generated/baselineProfiles
.
Tworzenie nowego profilu podstawowego bez szablonów
Zalecamy utworzenie profilu bazowego za pomocą szablonu modułu profilu bazowego w Android Studio (zalecane) lub szablonu Macrobenchmark, ale możesz też użyć samego wtyczki Gradle do profilu bazowego. Więcej informacji o wtyczce Gradle do generowania profilu podstawowego znajdziesz w artykule Konfigurowanie generowania profilu podstawowego.
Oto jak utworzyć profil bazowy, korzystając bezpośrednio z wtyczki Gradle do tworzenia profili bazowych:
- Utwórz nowy moduł
com.android.test
, na przykład:baseline-profile
. Skonfiguruj plik
build.gradle.kts
dla:baseline-profile
:- Zastosuj wtyczkę
androidx.baselineprofile
. - Upewnij się, że
targetProjectPath
wskazuje na moduł:app
. - Opcjonalnie dodaj urządzenie zarządzane przez Gradle (GMD).
W tym przykładzie jest to
pixel6Api31
. Jeśli nie jest to 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 }
Groovy
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
. Ten przykład to test, który uruchamia aplikację i czeka na stan bezczynności.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; }) ) } }
Zaktualizuj plik
build.gradle.kts
w module aplikacji, np.:app
.- Zastosuj wtyczkę
androidx.baselineprofile
. - Dodaj do modułu
:baseline-profile
zależnośćbaselineProfile
.
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")) }
Groovy
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, wykonując zadania
:app:generateBaselineProfile
lub:app:generateVariantBaselineProfile
w Gradle.Po zakończeniu zadania generowania profil bazowy jest kopiowany do pliku
app/src/variant/generated/baselineProfiles
.
Tworzenie nowego profilu bazowego za pomocą AGP 7.3–7.4
Profile bazowe można generować za pomocą AGP 7.3–7.4, ale zdecydowanie zalecamy przejście na co najmniej AGP 8.1, aby móc korzystać z wtyczki Gradle do tworzenia profili bazowych i jego najnowszych funkcji.
Jeśli musisz utworzyć profile bazowe za pomocą AGP 7.3–7.4, musisz wykonać te same czynności, co w przypadku AGP 8.1, z tymi wyjątkami:
- Nie dodawaj wtyczki Gradle do profilu bazowego.
- Aby wygenerować profile bazowe, 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 bazowego tworzy na urządzeniu plik tekstowy w formacie HRF 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 folderu
src/main/
i nazwij plikbaseline-prof.txt
.Dodaj zależność do biblioteki ProfileInstaller w pliku
build.gradle.kts
aplikacji, aby umożliwić lokalną kompilację profilu podstawowego, gdy profile w chmurze są niedostępne. Jest to jedyny sposób na lokalne zainstalowanie profilu podstawowego.dependencies { implementation("androidx.profileinstaller:profileinstaller:1.4.1") }
Skompiluj wersję produkcyjną aplikacji, gdy zastosowane zasady HRF są skompilowane w postaci binarnej i zawarto je w pliku APK lub AAB. Następnie rozpowszechnij aplikację w zwykły sposób.
Porównywanie profilu podstawowego
Aby przeprowadzić test porównawczy profilu bazowego, utwórz nową konfigurację testu z wykorzystaniem pomiarów z Androida na podstawie działania w rynnie, które wykonuje testy porównawcze zdefiniowane w pliku StartupBenchmarks.kt
lub StartupBencharks.java
. Więcej informacji o testowaniu porównawczym znajdziesz w artykułach Tworzenie klasy Macrobenchmark i Automatyzacja pomiarów za pomocą biblioteki Macrobenchmark.
Gdy uruchomisz to w Android Studio, dane wyjściowe kompilacji będą zawierać szczegóły dotyczące ulepszeń szybkości, które 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
Uwzględnij wszystkie wymagane ścieżki kodu
Oto 2 kluczowe wskaźniki pomiaru czasu uruchamiania aplikacji:
- Czas do początkowego wyświetlenia (TTID)
- Czas wyświetlania pierwszej klatki interfejsu aplikacji.
- Czas do pełnego wyświetlenia (TTFD)
- TTID oraz czas potrzebny na wyświetlenie treści wczytanych asynchronicznie po wyświetleniu pierwszej klatki.
TTFD jest zgłaszany, gdy wywoływana jest metoda reportFullyDrawn()
metody ComponentActivity
. Jeśli funkcja reportFullyDrawn()
nigdy nie zostanie wywołana, zamiast niej zostanie zgłoszony identyfikator TTID. Może być konieczne opóźnienie wywołania funkcji reportFullyDrawn()
do czasu zakończenia wczytywania asynchronicznego. Jeśli na przykład interfejs zawiera listę dynamiczną, taką jak RecyclerView
lub lazylist, może ona być wypełniana przez zadanie w tle, które jest wykonywane po pierwszym narysowaniu listy, a zatem po tym, jak interfejs został oznaczony jako w pełni narysowany. W takich przypadkach kod, który jest wykonywany po osiągnięciu przez interfejs stanu pełnego narysowania, nie jest uwzględniany w profilu bazowym.
Aby uwzględnić populację listy w ramach profilu podstawowego, użyj funkcji FullyDrawnReporter
, korzystając z funkcji getFullyDrawnReporter()
i dodaj do niej reportera w kodzie aplikacji. Po zakończeniu wypełniania listy przez zadanie w tle zwróć do raportu. Funkcja FullyDrawnReporter
nie wywołuje metody reportFullyDrawn()
, dopóki wszyscy reporterzy nie zostaną zwolnieni. Dzięki temu profil bazowy zawiera ścieżki kodu wymagane do wypełnienia listy.
Nie zmienia to działania aplikacji dla użytkownika, ale pozwala profilowi bazowemu uwzględnić wszystkie niezbędne ścieżki kodu.
Jeśli Twoja aplikacja korzysta z Jetpack Compose, użyj tych interfejsów API, aby wskazać stan pełnego wyświetlenia:
ReportDrawn
wskazuje, że komponent jest od razu gotowy do interakcji.ReportDrawnWhen
odbiera predykat, np.list.count > 0
, aby wskazać, kiedy kompozyt jest gotowy do interakcji.ReportDrawnAfter
zawiera metodę zawieszania, która po zakończeniu wskazuje, że kompozyt jest gotowy do interakcji.
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy obsługa JavaScript jest wyłączona
- Rejestrowanie danych Macrobenchmark
- Tworzenie testu porównawczego makro
- Biblioteka JankStats