Jeśli masz problemy z wydajnością, które wynikają z niepotrzebnych lub nadmiernej zmiany układu aplikacji, debuguj jej stabilność. W tym przewodniku omawiamy kilka sposobów, które pomogą Ci to zrobić.
Inspektor układu
Za pomocą Inspektora układu w Android Studio możesz sprawdzić, które funkcje kompozycyjne są rekomponowane w Twojej aplikacji. Pokazuje on, ile razy funkcja Tworzenie ponownie skomponowała lub pominęła dany komponent.
Tworzenie raportów kompilatora
Kompilator Compose może wyświetlić wyniki swojego wnioskowania dotyczącego stabilności na potrzeby kontroli. Na podstawie tych danych wyjściowych możesz określić, które elementy kompozycyjne można pominąć, a które nie. Poniżej opisujemy, jak korzystać z tych raportów. Szczegółowe informacje znajdziesz w dokumentacji technicznej.
Skonfiguruj
Raporty kompilatora kompilatora nie są domyślnie włączone. Można je aktywować
za pomocą flagi kompilatora. Dokładna konfiguracja zależy od projektu, ale w większości projektów możesz wkleić ten skrypt do pliku głównego build.gradle
.
Odlotowy
subprojects {
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
kotlinOptions {
if (project.findProperty("composeCompilerReports") == "true") {
freeCompilerArgs += [
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" +
project.buildDir.absolutePath + "/compose_compiler"
]
}
if (project.findProperty("composeCompilerMetrics") == "true") {
freeCompilerArgs += [
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" +
project.buildDir.absolutePath + "/compose_compiler"
]
}
}
}
}
Kotlin
subprojects {
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
kotlinOptions {
if (project.findProperty("composeCompilerReports") == "true") {
freeCompilerArgs += listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=${project.buildDir.absolutePath}/compose_compiler"
)
}
if (project.findProperty("composeCompilerMetrics") == "true") {
freeCompilerArgs += listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=${project.buildDir.absolutePath}/compose_compiler"
)
}
}
}
}
Uruchamianie zadania
Aby debugować stabilność elementów kompozycyjnych, uruchom to zadanie:
./gradlew assembleRelease -PcomposeCompilerReports=true
Przykładowe dane wyjściowe
To zadanie generuje 3 pliki. Oto przykładowe dane wyjściowe z usługi JetSnack.
<modulename>-classes.txt
: raport o stabilności klas w tym module. Przykład.<modulename>-composables.txt
: raport o tym, jak ponownie dostępne i pomijalne są w module kompozycje. Przykład.<modulename>-composables.csv
: wersja w formacieCSV
raportu o elementach kompozycyjnych, którą można zaimportować do arkusza kalkulacyjnego lub przetworzyć za pomocą skryptu. Próbka
Raport dotyczący elementów kompozycyjnych
Plik composables.txt
zawiera szczegółowe informacje o poszczególnych funkcjach kompozycyjnych danego modułu, w tym o stabilności ich parametrów oraz o tym, czy można je ponownie uruchomić czy pominąć. Oto hipotetyczny przykład usługi JetSnack:
restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun SnackCollection(
stable snackCollection: SnackCollection
stable onSnackClick: Function1<Long, Unit>
stable modifier: Modifier? = @static Companion
stable index: Int = @static 0
stable highlight: Boolean = @static true
)
Ten element kompozycyjny SnackCollection
jest w pełni możliwy do ponownego uruchomienia, możliwy do pominięcia i stabilny. Zwykle jest to korzystne, ale nie jest obowiązkowe.
Z drugiej strony posłużmy się innym przykładem.
restartable scheme("[androidx.compose.ui.UiComposable]") fun HighlightedSnacks(
stable index: Int
unstable snacks: List<Snack>
stable onSnackClick: Function1<Long, Unit>
stable modifier: Modifier? = @static Companion
)
Elementu kompozycyjnego HighlightedSnacks
nie można pominąć. Funkcja tworzenia wiadomości
nie pomija jej podczas zmiany kompozycji. Dzieje się tak nawet wtedy, gdy żaden z parametrów nie uległ zmianie.
Przyczyną jest parametr unstable
(snacks
).
Raport dotyczący zajęć
Plik classes.txt
zawiera podobny raport na temat klas w danym module. Ten fragment kodu jest wynikiem działania klasy Snack
:
unstable class Snack {
stable val id: Long
stable val name: String
stable val imageUrl: String
stable val price: Long
stable val tagline: String
unstable val tags: Set<String>
<runtime stability> = Unstable
}
Oto definicja słowa Snack
w celach informacyjnych:
data class Snack(
val id: Long,
val name: String,
val imageUrl: String,
val price: Long,
val tagline: String = "",
val tags: Set<String> = emptySet()
)
Kompilator Compose oznaczył wersję Snack
jako niestabilną. Wynika to z faktu, że typ parametru tags
to Set<String>
. Ten typ jest stały, ponieważ nie jest to MutableSet
. Jednak interfejsy to standardowe klasy kolekcji, takie jak Set, List
i Map
. Dlatego też podstawowa implementacja
może się zmieniać.
np. val set: Set<String> = mutableSetOf("foo")
. Zmienna jest stała, a jej zadeklarowany typ nie jest zmienny, ale jej implementacja nadal jest zmienny. Kompilator Compose nie może mieć pewności o niezmienności tej klasy, ponieważ widzi tylko zadeklarowany typ. Oznacza to, że tags
jest niestabilny.