Komplett guide till StateFlow och SharedFlow: Överträffar LiveData på Android

  • Grundläggande skillnad mellan kalla (Flow) och varma (StateFlow och SharedFlow) flöden för datahantering.
  • Kriterier för att välja mellan StateFlow för beständiga tillstånd och SharedFlow för tillfälliga händelser.
  • Säkra insamlingsstrategier med repeatOnLifecycle för att optimera resursförbrukningen i användargränssnittet.

StateFlow och SharedFlow: Överträffar LiveData på Android

Om du ger dig in i Android-världen har du säkert stött på det ständiga dilemmat med hur man hanterar data i presentationslagret. Under lång tid regerade LiveData, men med Kotlin-koroutinernas ankomst har mycket kraftfullare och mer flexibla verktyg dykt upp. Vi pratar om StateFlow och SharedFlow , som i huvudsak är den naturliga utvecklingen för att hantera dataflöden reaktivt och effektivt.

Sanningen är den att även om de till en början kan verka som liknande koncept, har var och en sitt eget syfte. Att vilja att skärmen ska komma ihåg var nyhetsflödet slutade är inte detsamma som att vilja skicka en snabb avisering för en Toast som bara ska visas en gång. För att undvika förvirring, låt oss gå igenom hur dessa heta strömmar fungerar och varför du bör överväga att lämna LiveData kvar i dina moderna projekt.

Flödesbegreppet: Kallt eller varmt?

För att förstå StateFlow och SharedFlow måste du först förstå skillnaden mellan ett kallt och ett hett flöde. Ett standardflöde är kallt , vilket betyder att det är som ett recept: ingenting händer förrän någon bestämmer sig för att köra det (anropa "collect"). Problemet är att om du har tre prenumeranter körs producentens kod tre gånger, vilket kan tömma batteriet eller skapa redundanta API-förfrågningar.

Det är här heta strömmar kommer in i bilden. Både StateFlow och SharedFlow är strategiskt heta , vilket innebär att producenten förblir aktiv oavsett om någon lyssnar eller inte. Detta gör det möjligt för flera samlare att dela samma datakälla , vilket förhindrar att appen gör samma arbete upprepade gånger – avgörande för att upprätthålla systemets flyt.

StateFlow: Den perfekta ersättningen för LiveData

StateFlow är i huvudsak en tillståndsbehållare. Dess huvudsakliga funktion är att den alltid bibehåller ett aktuellt värde , vilket kan efterfrågas synkront med hjälp av egenskapen .value. Det är det perfekta verktyget för att hantera användargränssnittets tillstånd, till exempel om en skärm laddas eller om profildata har uppdaterats.

Konfiguration och struktur av flermodulsprojekt i Android Studio
Relaterad artikel:
Komplett guide till att konfigurera och strukturera flermodulprojekt i Android Studio

Till skillnad från LiveData kräver StateFlow ett initialvärde i sin konstruktor, vilket eliminerar osäkerheten kring att ha nulltillstånd vid start. Dessutom implementerar den sammanslagnings- och dedupliceringsbeteende : om du genererar samma värde två gånger i rad ignorerar flödet det helt enkelt. Detta är utmärkt för att förhindra att användargränssnittet uppdateras i onödan även om data inte har ändrats.

För att implementera detta i en ViewModel är det bästa tillvägagångssättet att använda en privat MutableStateFlow-fallback-egenskap och exponera den som ett oföränderligt StateFlow. Detta säkerställer att endast ViewModel kan ändra tillståndet, samtidigt som det enkelriktade dataflödet respekteras och vyn förhindras från att manipulera data.

SharedFlow: Händelsebussen för unika åtgärder

Om StateFlow är för "state" (tillstånd) är SharedFlow för "events" (händelser). Tänk dig att du vill visa en feldialogruta eller navigera till en annan skärm. Om du använder StateFlow skulle rotation av enheten göra att den nya samlaren får det sista värdet, och händelsen skulle utlösas igen – ett allvarligt fel. SharedFlow löser detta eftersom det kan konfigureras med ett replay-värde på noll.

Det här flödet är mycket mer flexibelt och låter oss justera parametrar som överflödesbufferten . Om bufferten fylls kan vi välja att pausa avsändaren eller ignorera det äldsta eller nyaste värdet. En viktig fördel är att SharedFlow låter dig skicka upprepade värden ; om du behöver skicka samma "Anslutningsfel"-meddelande tre gånger, kommer SharedFlow att göra det utan att tveka, medan StateFlow skulle filtrera bort dem.

Teknisk jämförelse: StateFlow vs SharedFlow vs LiveData

För att undvika förvirring i en teknisk intervju eller när du utformar din arkitektur är det viktigt att beakta de kritiska punkterna. LiveData är enkelt och hanterar livscykeln automatiskt , men det är väldigt kopplat till Android. StateFlow och SharedFlow, som är en del av Kotlin Coroutines, är plattformsoberoende , vilket avsevärt förenklar enhetstestning och skapandet av rena domänlager.

  • StateFlow: Tvingar fram ett initialt värde, har .value, deduplicerar värden och är idealisk för UI-tillstånd.
  • Delat flödeDet kräver inget initialvärde, är konfigurerbart vad gäller uppspelning och är rätt alternativ för kortvariga händelser.
  • LiveDataDen kräver inget initialvärde, den är medveten om livscykeln men mindre kraftfull i asynkrona transformationer.

Vikten av säker skörd

Ett mycket vanligt misstag är att köra en `collect` inom ett enkelt coroutine-omfång i aktiviteten. Detta är farligt eftersom flödet fortsätter att bearbeta data även när appen är i bakgrunden , vilket kan orsaka krascher eller överdriven CPU-användning. Den moderna lösningen är att använda API:et `repeatOnLifecycle(Lifecycle.State.STARTED)`.

Den här funktionen gör att insamlingen aktiveras när vyn är synlig och automatiskt avbryts när den når tillståndet STOPPAD . För Jetpack Compose rekommenderas att använda `collectAsStateWithLifecycle()` , vilket integrerar denna logik direkt och säkerställer att applikationen är effektiv med enhetsresurser.

Omvandla kalla flöden till varma

Ibland har vi ett flöde som kommer från en databas (som Room) eller ett repository, och det är kallt. För att göra det varmt använder vi operatorerna `stateIn` eller `shareIn` . Dessa operatorer kräver en `CoroutineScope` och en startstrategi. Den vanligaste är `SharingStarted.WhileSubscribed(5000)`.

Den här konfigurationen är lysande eftersom den håller strömmen aktiv så länge det finns prenumeranter, och om skärmen är stängd väntar den 5 sekunder innan strömmen stoppas. Detta är avgörande så att strömmen inte förstörs och återskapas under en skärmrotation , vilket undviker onödiga förfrågningar till servern eller den lokala databasen.

MVI-arkitektur i Android
Relaterad artikel:
Komplett guide till MVI-arkitektur i Android

Att behärska dessa verktyg innebär att förstå att tillstånd måste vara persistent och deduplicerat med StateFlow, medan engångsåtgärder bör flöda genom SharedFlow. Genom att kombinera detta med livscykelmedvetenhet och kallflödestransformation med stateIn uppnår vi en robust, helt reaktiv Android-arkitektur optimerad för verklig prestanda på mobila enheter. Dela den här guiden och hjälp andra att lära sig om detta ämne.


Surfshark Antivirus för Android
Det kan intressera dig:
Så här tar du bort virus på Android: En komplett och uppdaterad guide för att rengöra din telefon
Lägg till som prioriterad källa i Google