Remote Compose ist eine Jetpack-Bibliothek, mit der Sie in Ihrer App eine Benutzeroberfläche mit Compose-ähnlichen APIs erstellen und in Systemprozessen wie App-Widgets oder Wear OS-Widgets anzeigen können. Ihre App zeichnet die Benutzeroberfläche als kompaktes Dokument auf. Ein Player im Hostprozess rendert es und verarbeitet Interaktionen, Statusänderungen und Animationen lokal, ohne Ihre App aufzurufen.
In diesem Leitfaden wird die Remote Compose-Architektur und der Unterschied zu Standard-Jetpack Compose erläutert. In diesem Leitfaden geht es um das Erstellen von Benutzeroberflächen mit Komponenten.
Anwendungsfälle für Remote Compose
Remote Compose kann auf jeder Oberfläche mit einem unterstützten Player verwendet werden. Unter Android werden damit App-Widgets und Wear OS-Widgets unterstützt.
Funktionsweise: Architektur mit drei Blöcken
Der grundlegende architektonische Unterschied zwischen Remote Compose und Standard-Jetpack Compose besteht darin, dass die UI-Definition von der Ausführung in drei übergeordneten Blöcken entkoppelt wird:
- Dokument erstellen: Ihre App führt Ihre
@RemoteComposable-Funktionen aus, um ein Dokument aufzuzeichnen: eine kompakte, serialisierte Beschreibung der Benutzeroberfläche, einschließlich Layout, Remote-Status und Aktionen. Wenn sich Ihre Daten ändern, kann Ihre Anwendung ein neues Dokument aufzeichnen und senden. - Dokument an den Remote-Host übertragen: Ihre App übergibt das Dokument an den Host, also den Prozess, der es anzeigt, z. B. einen Launcher oder Wear OS.
- Dokument wiedergeben: Ein Remote Compose-Player im Host rendert das Dokument und verarbeitet Layout, Eingabe, UX-Statusänderungen und Animationen lokal, ohne Ihre App aufzurufen.
Diese Architektur bietet wesentliche Vorteile, die die Latenz direkt reduzieren:
- Kleine Dokumentgröße: Serialisierte Dokument-Snapshots bleiben kompakt und leicht.
- Weniger Roundtrips: Da der Remote-Host-Player Interaktionen und Statusänderungen lokal verarbeitet, werden Roundtrips zurück zur Anwendung oder zum Server minimiert.
Webseite/HTML-Analogie: Remote Compose funktioniert ähnlich wie das Bereitstellen einer Webseite. Der Anwendungsserver generiert und sendet einmal eine HTML-/Dokumentstruktur. Der Browserhost rendert sie und verarbeitet Interaktionen lokal, ohne ständig das Backend abzufragen.
Komponenten
Remote Compose bietet allgemeine UI-Komponenten zum Strukturieren von Layouts. Verwenden Sie Remote Compose-Komponenten und RemoteModifier anstelle der entsprechenden Standard-Compose-Komponenten. Dazu gehören grundlegende Layoutcontainer sowie adaptive Komponenten, die speziell für dynamische Bildschirmgrößen entwickelt wurden:
- Grundlegende Layoutkomponenten: Gängige Compose-ähnliche Layoutelemente wie
RemoteBox,RemoteRowundRemoteColumn. - Adaptive Layoutkomponenten: Spezielle Komponenten wie
RemoteFitBox,RemoteCollapsibleRowundRemoteCollapsibleColumn, die sich sauber an Remote-Oberflächen anpassen. - Material Design-Theming: Das Theming funktioniert bei Wear OS-Widgets genauso, mit einer Hierarchie von Farben und Typografie, die von
RemoteMaterialThemebereitgestellt wird. So können Sie ein einheitliches Branding und Designsystem in Ihrer App und Ihren Widgets implementieren.
Benutzerdefinierte Zeichnung mit RemoteCanvas
Verwenden Sie für benutzerdefinierte Grafiken und zeitbasierte Animationen RemoteCanvas, um Zeichenbefehle aufzuzeichnen, die der Player auf dem Host ausführt. In diesem Leitfaden geht es um das Erstellen von Benutzeroberflächen mit Komponenten.
Wichtige Unterschiede
In den folgenden Abschnitten werden die wichtigsten Konzepte erläutert, um zu verstehen, wie Remote Compose Status, Logik und Aktionen verwaltet.
Symbolische Statusreferenzen
In Standard-Compose enthalten Statuscontainer aktive, lesbare Werte im lokalen App-Speicher, die durch App-Code (Lambdas) geändert werden, wenn etwas passiert. In Remote Compose fungieren Zustandsdeklarationen als symbolische Referenzen. Anstatt aktive Werte im lokalen App-Speicher zu speichern, deklarieren sie Bindungen, die der Remote-Player zur Laufzeit lokal verwaltet und aktualisiert. Beachten Sie beim Deklarieren des Status in Remote Compose Folgendes:
- Verwenden Sie Remote Compose-Factory-Funktionen, um Status wie
rememberMutableRemoteInt,rememberMutableRemoteFloatoderrememberMutableRemoteStringzu deklarieren. - Ihr Anwendungscode kann den Wert einer Remote-Zustandsvariablen während der Komposition nicht direkt prüfen oder lesen.
- Der Player speichert und aktualisiert diese Werte lokal, wenn der Nutzer mit dem Dokument interagiert.
Remotestatus im Vergleich zum Kotlin-Kontrollfluss
Ihr Kotlin-Code wird nur ausgeführt, wenn Ihre App das Dokument erstellt. Kotlin-Anweisungen wie „if“, „when“ und „for“ können das Dokument anhand von Werten formen, die zu diesem Zeitpunkt bekannt sind, z. B. eine Zeile für jedes Element in einer Liste wiederholen. Sie können jedoch nicht auf einen Remote-Status reagieren, der sich später ändert. Beachten Sie bei der Arbeit mit Remote Compose Folgendes:
- Verzweigungslogik: Der dynamische Wechsel der Benutzeroberfläche erfolgt mit
RemoteStateLayout, indem der Status verschiedenenRemoteComposable-Slots zugeordnet wird. - Textauswertung: Vermeiden Sie die standardmäßige Kotlin-String-Interpolation ("
$remoteValue"), die nur beim Erstellen des Dokuments ausgewertet wird. Übergeben Sie stattdessenRemoteStringanRemoteText.
Dynamische Stile mit RemoteModifier
Bei dynamischem Styling auf dem Host wird die Komposition nicht noch einmal ausgeführt. Stattdessen werden Remote-Zustandsvariablen direkt an Modifikatoren wie RemoteModifier.background(remoteColor) übergeben.
Kontext aus Remote-Systemen
CompositionLocal-Anbieter wie LocalConfiguration oder LocalDensity spiegeln nur die lokale App-Umgebung zum Zeitpunkt der Aufzeichnung des Dokuments wider. Sie werden auf dem Remote-Host nicht dynamisch aktualisiert, wenn sich die Größe der Oberfläche ändert, sich der Anzeigestatus ändert oder die Zeit voranschreitet. Verwenden Sie stattdessen Werte, die der Player zur Laufzeit auf dem Host auflöst, z. B. die aktuelle Größe der Komponente, RemoteConfiguration oder RemoteDensity.
Deklarative Aktionen
In Standard-Compose sind Klick-Handler Lambdas, die in Ihrer App ausgeführt werden. Der Host kann den Code Ihrer App nicht ausführen. Daher hängen Sie in Remote Compose stattdessen Aktionen an, z. B. mit RemoteModifier.clickable(action). Eine Aktion kann den Remote-Status direkt auf dem Host mit valueChange aktualisieren oder mit pendingIntentAction oder hostAction an Ihre App oder den Host übergeben. Wenn Sie mehrere Aktionen mit einem Klick ausführen möchten, verwenden Sie combinedAction.
Vergleich der Paradigmen auf hoher Ebene
Feature-Domain |
Standard-Jetpack Compose |
Remote Compose |
|---|---|---|
Klick- und Touch-Ereignisse |
In-Process-synchrone Lambdas |
Deklarative serialisierte Action-Objekte |
Bedingte Logik |
Kotlin-Kontrollfluss mit „if“ und „when“ |
Der Standard-Kotlin- Bei der dynamischen Verzweigung wird |
Kontrollflussschleifen |
Standardmäßige Kotlin-Schleifen vom Typ „for“ und „while“ |
Standard-Kotlin-Schleifen (repeat, for, forEach) werden nur ausgeführt, wenn das Dokument erstellt wird. Sie können den Remote-Status auf dem Host nicht in einer Schleife durchlaufen. |
Ausführungshost |
App-Prozess |
Launcher (AppWidget), Wear OS-Widgets oder beliebige Formfaktoren mit einem unterstützenden Player |
Prozesslebenszyklus |
Der Prozess muss aktiv bleiben, damit die Neuzusammensetzung und das Rendering erfolgen können |
Der Prozess zeichnet ein Dokument mit einem Snapshot der Benutzeroberfläche auf. Die Remote Player-Engine parst den Komponentenbaum, verfolgt Statusänderungen und zeichnet die Benutzeroberfläche lokal neu, ohne die App aufzurufen. |
Nebenwirkungen |
Koroutinen-Lebenszyklen (LaunchedEffect) |
Nicht auf dem Host verfügbar. Die Komposition wird in Ihrer App ausgeführt, um das Dokument zu erstellen. Daher können Coroutine-Effekte die Remote-UI nicht steuern, es sei denn, die Integration hält eine Komposition offen. |
Zustandsparadigma |
Zustandswerte des lokalen Arbeitsspeichers |
Factory-Funktionen (rememberMutableRemoteInt(), rememberNamedRemoteColor()), die symbolische Statusreferenzen anstelle von Rohwerten zurückgeben. |