collectAsStateWithLifecycle – Flows sammeln, ohne im Hintergrund zu verschwenden
collectAsState sammelt einen Flow auch, wenn die App im Hintergrund ist. collectAsStateWithLifecycle stoppt automatisch, sobald der Screen nicht mehr sichtbar ist – der richtige Standard für UI-State aus dem ViewModel.
Du hast einen StateFlow im ViewModel und willst ihn im Compose-UI lesen. Der naheliegende Weg ist collectAsState() – der hat aber einen Haken: Er sammelt den Flow auch dann weiter, wenn die App im Hintergrund ist. Bei einem Flow, der Standort, Netzwerk oder Sensoren anzapft, kostet das unnötig Akku und Daten. Die lifecycle-bewusste Variante löst das.
Vorher: collectAsState
@Composable
fun NewsScreen(vm: NewsViewModel) {
// sammelt weiter, auch wenn der Screen im Hintergrund ist
val state by vm.uiState.collectAsState()
NewsList(state.articles)
}Nachher: collectAsStateWithLifecycle
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@Composable
fun NewsScreen(vm: NewsViewModel) {
// pausiert automatisch unterhalb von STARTED (App im Hintergrund),
// nimmt beim Zurückkehren wieder auf
val state by vm.uiState.collectAsStateWithLifecycle()
NewsList(state.articles)
}Die Funktion steckt in der Abhängigkeit androidx.lifecycle:lifecycle-runtime-compose.
Was genau passiert
collectAsStateWithLifecycle bindet die Sammlung an den Lifecycle des Screens. Sinkt der Zustand unter STARTED (Nutzer wechselt die App, Bildschirm aus), wird die Collection abgebrochen; kehrt der Nutzer zurück, startet sie neu und liefert den aktuellsten Wert. Bei collectAsState läuft der Coroutine-Collector dagegen so lange, wie der Composable in der Komposition ist – auch unsichtbar.
Empfehlung
- UI-State aus dem ViewModel (
StateFlow/SharedFlow) →collectAsStateWithLifecycleals Standard. - Reine In-Memory-Flows ohne teure Quelle →
collectAsStategenügt, ist aber selten „falscher". - Achte darauf, dass dein
StateFlowviastateIn(..., SharingStarted.WhileSubscribed(5_000))erzeugt wird – so stoppt auch die *Upstream*-Quelle, wenn niemand mehr sammelt.
So bleibt deine App sparsam mit Akku und Datenvolumen – ein Detail, das Nutzer langfristig merken. Du willst so eine App? Sprich mich an.
Quellen
Du brauchst mehr als ein Snippet?
Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.
Projekt anfragen →Verwandte Snippets
derivedStateOf – abgeleiteten Zustand berechnen, ohne Recompositions zu verschwenden
Wenn du aus einem sich schnell ändernden State einen selten wechselnden Wert ableitest (z. B. "Nach-oben-Button ab Item 5"), verhindert derivedStateOf, dass dein UI bei jedem Scroll-Pixel neu zeichnet.
Modifier-Reihenfolge in Compose – warum padding vor background alles ändert
In Jetpack Compose ist die Reihenfolge der Modifier keine Kosmetik, sondern Logik. background vor padding färbt auch den Rand ein, padding vor background nicht. Ein Beispiel, das den Groschen fallen lässt.
remember vs. rememberSaveable – Zustand, der die Drehung übersteht
remember hält Zustand über Recompositions, verliert ihn aber bei Konfigurationsänderungen wie der Bildschirmdrehung. rememberSaveable rettet einfache Werte automatisch über den Bundle-Mechanismus.