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
stateIn und shareIn – aus einem kalten Flow wird geteilter Zustand
Jeder Sammler eines kalten Flows startet die Arbeit neu – zwei Beobachter, zwei Datenbankabfragen. stateIn und shareIn machen daraus einen Strom, den sich alle teilen, samt aktuellem Wert und Abschalten bei Inaktivität.
Room-Migrationen – das Schema ändern, ohne Nutzerdaten zu verlieren
Eine neue Spalte in der Entity, und beim nächsten Start ist der Spielstand weg – weil fallbackToDestructiveMigration die Datenbank einfach löscht. So machst du es richtig, inklusive Test.
viewModelScope – Coroutinen, die mit dem Bildschirm verschwinden
Eine Coroutine, die nach dem Schließen des Bildschirms weiterläuft, schreibt in ein ViewModel, das niemand mehr sieht – und hält im schlimmsten Fall die ganze Activity im Speicher. viewModelScope beendet sie automatisch.