Woran erinnert sich Jetpack Compose eigentlich, wie funktioniert es unter der Haube?

Lesezeit: 7 Minuten

Thracians Benutzeravatar
Thrakisch

Wenn Sie sich das grundlegende Tutorial von Codelab ansehen, gibt es einen Ausschnitt, um den Zähler auf der Schaltfläche zu erhöhen, wenn darauf geklickt wird

@Composable
fun MyScreenContent(names: List<String> = listOf("Android", "there")) {
    val counterState = remember { mutableStateOf(0) }

    Column(modifier = Modifier.fillMaxHeight()) {
        Column(modifier = Modifier.weight(1f)) {
            for (name in names) {
                Greeting(name = name)
                Divider(color = Color.Black)
            }
        }
        Counter(
            count = counterState.value,
            updateCount = { newCount ->
                counterState.value = newCount
            }
        )
    }
}


@Composable
fun Counter(count: Int, updateCount: (Int) -> Unit) {
    Button(
        onClick = { updateCount(count + 1) },
        colors = ButtonConstants.defaultButtonColors(
            backgroundColor = if (count > 5) Color.Green else Color.White
        )
    ) {
        Text("I've been clicked $count times")
    }
}

Es ist klar, dass remember { mutableStateOf(0) } speichert den Zustand/Wert. Meine Frage ist, was Remember unter der Haube macht. Benutzen var count = remember { 0 } oder mutableStateOf(0) ohne erinnern erhöht den Wert nicht.

fun MyScreenContent(names: List<String> = listOf("Android", "there")) {
   
    var count = remember { 0 }

    Column(modifier = Modifier.fillMaxHeight()) {
        Column(modifier = Modifier.weight(1f)) {
            for (name in names) {
                Greeting(name = name)
                Divider(color = Color.Black)
            }
        }
        Counter(
            count = count,
            updateCount = { newCount ->
                count = newCount
            }
        )
    }
}

Das obige Snippet aktualisiert den aufgedruckten Wert nicht Texterinnert sich, nur mit gearbeitet zu haben MutableState?

  • Sie können meinen Artikel lesen, um zu erfahren, was es tut und wie es das tut medium.com/@thegoldycopythat/…

    – Abhinav Chauhan

    11. Juni 2022 um 12:27 Uhr


  • @AbhinavChauhan, ich habe es gelesen. Es ist sehr gut. Sie können eine Antwort basierend auf Ihrem Artikel hinzufügen.

    – Thrakisch

    13. Juni 2022 um 6:43

  • Vielen Dank, ich werde mir die Zeit nehmen, die Antwort hinzuzufügen. Danke für den Vorschlag. Sie können auch erwägen, auf Medium zu folgen.

    – Abhinav Chauhan

    14. Juni 2022 um 9:47 Uhr

  • Wirklich hilfreich, sowohl die Frage als auch die Antwort. Danke schön.

    – Joan P.

    20. September 2022 um 15:19 Uhr

Madabrowskis Benutzeravatar
Madabrowski

remember – Ermöglicht Ihnen, sich den Status aus dem vorherigen Recompose-Aufruf zu merken, und zwar genau diesen. Wenn Sie beispielsweise die Farbe beim ersten Durchlauf zufällig auswählen. Die zufällige Farbe wird nur einmal berechnet und später wiederverwendet, wenn eine Neuzusammenstellung erforderlich ist.

Und daher,

remember = den Wert speichern, nur für den Fall, dass recompose aufgerufen wird.

Die zweite wichtige Sache ist nun, zu wissen, wann reCompose eigentlich ausgelöst werden und da kommen die veränderlichen Zustände zu Hilfe.

mutablestate = den Wert speichern und falls ich den Wertauslöser aktualisiere, für alle Elemente, die diese Daten verwenden, neu zusammensetzen.

  • Aus den Materialien, die ich über Compose gelesen habe, war „erinnern“ sehr verwirrend. Ich hatte den Eindruck, dass eine Zustandsvariable gespeichert und in diesem Composable verwendet werden muss, damit ein Composable neu zusammengesetzt werden kann. Jetzt verstehe ich, dass das nicht der Fall ist. Solange das Composable einen veränderlichen Zustand liest, den ich irgendwo deklariere (innerhalb oder außerhalb von Composable-Codes) und solange sich der Status ändert, wird das Composable neu zusammengesetzt. „Denken Sie daran, dass dies nur für einige einfache Dinge gilt, die Sie in einem Composable tun, wie zum Beispiel auf eine Schaltfläche klicken und eine Zahl erhöhen, andernfalls ist es in den meisten meiner Fälle nicht erforderlich.

    – LXJ

    6. April 2022 um 7:17 Uhr


Thracians Benutzeravatar
Thrakisch

Um zu erfahren, wie Komposition und Neukomposition funktionieren, können Sie hier nachlesen Unter der Haube von Jetpack Compose-Artikel von Leland Richardson, das innere Werke sehr gut beschreibt, auch YouTube-Video Hier. Und die meisten dieser Antworten verwenden Artikel als Referenz und zitieren die meisten daraus.

Die Implementierung des Composers enthält eine Datenstruktur, die eng mit a verknüpft ist Lückenpuffer. Diese Datenstruktur wird häufig in Texteditoren verwendet.

Ein Lückenpuffer stellt eine Sammlung mit einem aktuellen Index oder Cursor dar. Es wird im Speicher mit einem flachen Array implementiert. Dieses flache Array ist größer als die Datensammlung, die es darstellt, wobei der ungenutzte Raum als Lücke bezeichnet wird.

Grundsätzlich wird Platz in der Nähe Ihrer Composable-Funktions-Slot-Tabelle hinzugefügt, um die Benutzeroberfläche seitdem dynamisch und mit hohen Kosten aktualisieren zu können get, move, insertUnd delete – sind Operationen mit konstanter Zeit, mit Ausnahme der Verschiebung der Lücke. Die Lücke zu verschieben ist An) Dies kommt jedoch nicht oft vor und Sie müssen die gesamte UI-Struktur ändern. Im Durchschnitt ändern UIs die Struktur nicht sehr stark.

@Composable
    fun Counter() {
     var count by remember { mutableStateOf(0) }
     Button(
       text="Count: $count",
       onPress={ count += 1 }
     )
    }

Wenn der Compiler die Composable-Annotation sieht, fügt er zusätzliche Parameter und Aufrufe in den Hauptteil der Funktion ein. Zuerst fügt der Compiler einen Aufruf hinzu composer.start -Methode und übergibt ihr eine zur Kompilierungszeit generierte Schlüssel-Ganzzahl.

fun Counter($composer: Composer) {
 $composer.start(123)
 var count by remember($composer) { mutableStateOf(0) }
 Button(
   $composer,
   text="Count: $count",
   onPress={ count += 1 },
 )
 $composer.end()
}

Wenn dieser Composer ausgeführt wird, geschieht Folgendes:

  1. Composer.start wird aufgerufen und speichert ein Gruppenobjekt
  2. Denken Sie daran, dass ein Gruppenobjekt eingefügt wird
  3. Der von mutableStateOf zurückgegebene Wert, die Zustandsinstanz, wird gespeichert.
  4. Button speichert eine Gruppe, gefolgt von jedem ihrer Parameter.
  5. Und dann kommen wir endlich bei Composer.end an.

Geben Sie hier eine Bildbeschreibung ein

Die Datenstruktur enthält nun alle Objekte aus der Komposition, den gesamten Baum in der Ausführungsreihenfolge, effektiv a Tiefendurchquerung des Baumes.

So remember benötigt, um a zu speichern mutableState() um Wert aus der vorherigen Komposition zu ziehen und mutableState() ist erforderlich, um einen auszulösen.

Und MutableState Schnittstelle verwendet @Stable Anmerkung

@Stable
interface MutableState<T> : State<T> {
    override var value: T
    operator fun component1(): T
    operator fun component2(): (T) -> Unit
}

Stable wird verwendet, um dem Compose-Compiler einige Garantien darüber zu übermitteln, wie sich ein bestimmter Typ oder eine bestimmte Funktion verhält.

Bei Anwendung auf eine Klasse oder Schnittstelle gibt Stable an, dass Folgendes wahr sein muss:

  1. Das Ergebnis von equal wird immer dasselbe Ergebnis für dieselben zwei Instanzen zurückgeben.
  2. Wenn sich eine öffentliche Eigenschaft dieses Typs ändert, wird die Zusammensetzung benachrichtigt.
  3. Alle Arten von öffentlichem Eigentum sind stabil. Bei Anwendung auf eine Funktion oder eine Eigenschaft gibt die Annotation „Stable]an, dass die Funktion dasselbe Ergebnis zurückgibt, wenn dieselben Parameter übergeben werden. Dies ist nur sinnvoll, wenn die Parameter und Ergebnisse selbst stabil, unveränderlich oder primitiv sind.

Die Invarianten, die diese Annotation impliziert, werden vom Compose-Compiler für Optimierungen verwendet und weisen ein undefiniertes Verhalten auf, wenn die oben genannten Annahmen nicht erfüllt sind. Daher sollte man diese Anmerkung nicht verwenden, es sei denn, man ist sicher, dass diese Bedingungen erfüllt sind.

Andere Quelle mit einem Video Das beschreibt, wie Compose funktioniert.

  • Anschaulich erklärt! Dies hätte die akzeptierte Antwort sein sollen!

    – sud007

    11. Mai um 18:47 Uhr

Thracians Benutzeravatar
Thrakisch

Codelab-Beispiel Erwähnungen über erinnern Und veränderlicher Zustand als

Das Reagieren auf Zustandsänderungen ist das Herzstück von Compose. Compose-Apps wandeln Daten in eine Benutzeroberfläche um, indem sie Composable-Funktionen aufrufen. Wenn sich Ihre Daten ändern, rufen Sie diese Funktionen mit den neuen Daten ab und erstellen so eine aktualisierte Benutzeroberfläche. Compose bietet Tools zum Beobachten von Änderungen in den Daten Ihrer App, die Ihre Funktionen automatisch abrufen – dies wird als Neuzusammensetzen bezeichnet. Compose prüft auch, welche Daten von einem einzelnen Composable benötigt werden, sodass nur Komponenten neu zusammengestellt werden müssen, deren Daten sich geändert haben, und die Zusammenstellung derjenigen übersprungen werden kann, die nicht betroffen sind.

Unter der Haube verwendet Compose ein benutzerdefiniertes Kotlin-Compiler-Plugin, sodass die zusammensetzbaren Funktionen erneut aufgerufen werden können, um die UI-Hierarchie zu aktualisieren, wenn sich die zugrunde liegenden Daten ändern.

Um einem Composable einen internen Status hinzuzufügen, verwenden Sie die Funktion mutableStateOf, die einen Composable-Variablenspeicher bereitstellt. Um nicht bei jeder Neuzusammensetzung einen anderen Zustand zu haben, merken Sie sich den veränderlichen Zustand mithilfe von „Erinnern“. Und wenn es mehrere Instanzen des Composable an verschiedenen Stellen auf dem Bildschirm gibt, erhält jede Kopie ihre eigene Version des Zustands. Sie können sich den internen Zustand als eine private Variable in einer Klasse vorstellen.

remember{X} Und remember{mutableStateOf(X)} sind in verschiedenen Szenarien nützlich.

Der erste ist erforderlich, wenn Ihr Objekt nicht bei jeder Neuzusammenstellung instanziiert werden muss und es einen weiteren Auslöser gibt, der die Zusammensetzung auslöst.

Ein Beispiel hierfür ist remember{Paint()}, jedes Objekt, das nicht mehr als einmal instanziiert werden muss oder für dessen Instanziierung viel Speicher erforderlich ist. Wenn ein Composable, das dieses Objekt besitzt, neu zusammengesetzt wird, ändern sich die Eigenschaften Ihres Objekts dank nicht rememberwenn Sie es nicht verwenden remember Ihr Objekt wird bei jeder Neuzusammensetzung instanziiert und alle zuvor festgelegten Eigenschaften werden zurückgesetzt.

Wenn Sie eine benötigen trigger(mutableStateOf) und Sie müssen den neuesten Wert (merken) wie in der Frage auswählen remember{mutableStateOf()}

Variablen werden bei jedem gelöscht compositon.

Benutzen remember erhält den vorherigen Wert.

Ich denke, es entspricht der Deklaration eines veränderlichen Zustands in ViewModel.

1452880cookie-checkWoran erinnert sich Jetpack Compose eigentlich, wie funktioniert es unter der Haube?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy