Stabilitätsprobleme diagnostizieren

Wenn Leistungsprobleme aufgrund einer unnötigen oder übermäßigen Neuzusammensetzung auftreten, sollten Sie die Stabilität Ihrer App debuggen. In diesem Leitfaden werden verschiedene Methoden beschrieben.

Layout Inspector

Mit dem Layout Inspector in Android Studio können Sie sehen, welche zusammensetzbaren Funktionen in Ihrer App neu erstellt werden. Außerdem wird angezeigt, wie oft eine Komponente in der Funktion „Compose“ neu zusammengesetzt oder übersprungen wurde.

Anzahl der Neuzusammensetzungen und Überspringungen im Layout Inspector

Compiler-Berichte erstellen

Der Compose-Compiler kann die Ergebnisse seiner Stabilitätsinferenz zur Prüfung ausgeben. Anhand dieser Ausgabe können Sie bestimmen, welche Ihrer zusammensetzbaren Funktionen überspringbar sind und welche nicht. In den folgenden Unterabschnitten wird die Verwendung dieser Berichte zusammengefasst. Ausführlichere Informationen finden Sie in der technischen Dokumentation.

Einrichten

Compiler-Compiler-Berichte sind standardmäßig nicht aktiviert. Sie können sie mit einem Compiler-Flag aktivieren. Die genaue Einrichtung hängt von Ihrem Projekt ab. Für die meisten Projekte können Sie jedoch das folgende Skript in die Stammdatei build.gradle einfügen.

Groovig

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"
                )
            }
        }
    }
}

Task ausführen

Führen Sie die Task wie folgt aus, um Fehler an der Stabilität Ihrer zusammensetzbaren Funktionen zu beheben:

./gradlew assembleRelease -PcomposeCompilerReports=true

Beispielausgabe:

Diese Aufgabe gibt drei Dateien aus. Es folgen Beispielausgaben von JetSnack.

  • <modulename>-classes.txt: Ein Bericht zur Stabilität der Klassen in diesem Modul. Sample (Beispiel).
  • <modulename>-composables.txt: Ein Bericht dazu, wie neustartbar und überspringbar die zusammensetzbaren Funktionen im Modul sind. Sample (Beispiel).
  • <modulename>-composables.csv:Eine CSV-Version des Berichts zu zusammensetzbaren Funktionen, die Sie in eine Tabelle importieren oder mithilfe eines Skripts verarbeiten können. Beispiel

Bericht zu zusammensetzbaren Funktionen

In der Datei composables.txt sind alle zusammensetzbaren Funktionen für das jeweilige Modul aufgeführt, einschließlich der Stabilität ihrer Parameter und ob sie neustartbar oder überspringbar sind. Das folgende hypothetische Beispiel von 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
)

Diese zusammensetzbare Funktion SnackCollection ist vollständig neustartfähig, überspringbar und stabil. Dies ist in der Regel vorzuziehen, aber sicherlich nicht obligatorisch.

Sehen wir uns ein weiteres Beispiel an.

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
)

Die zusammensetzbare Funktion „HighlightedSnacks“ ist nicht überspringbar. Die Funktion „Compose“ wird bei der Neuzusammensetzung nie übersprungen. Dies geschieht auch dann, wenn sich keiner der zugehörigen Parameter geändert hat. Der Grund dafür ist der Parameter unstable, snacks.

Kursbericht

Die Datei classes.txt enthält einen ähnlichen Bericht zu den Klassen im jeweiligen Modul. Das folgende Snippet ist die Ausgabe für die Klasse 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
}

Im Folgenden finden Sie die Definition von Snack:

data class Snack(
    val id: Long,
    val name: String,
    val imageUrl: String,
    val price: Long,
    val tagline: String = "",
    val tags: Set<String> = emptySet()
)

Der Compiler „Compose“ hat Snack als instabil markiert. Das liegt daran, dass der Typ des tags-Parameters Set<String> ist. Dies ist ein unveränderlicher Typ, da er kein MutableSet ist. Standardsammlungsklassen wie Set, List und Map sind jedoch letztendlich Schnittstellen. Daher kann die zugrunde liegende Implementierung weiterhin änderbar sein.

Beispielsweise könnten Sie val set: Set<String> = mutableSetOf("foo") schreiben. Die Variable ist konstant und ihr deklarierter Typ ist nicht änderbar, ihre Implementierung ist jedoch weiterhin änderbar. Der Compiler Compose kann die Unveränderlichkeit dieser Klasse nicht sicher sein, da er nur den deklarierten Typ erkennt. Daher wird tags als instabil gekennzeichnet.