Si t'estàs ficant al món d'Android, segur que t'has topat amb l'etern dilema de com manejar les dades a la capa de presentació. Durant molt de temps, LiveData va ser el rei absolut, però amb l'arribada de les corrutines de Kotlin, han aparegut eines molt més potents i flexibles. Parlem de StateFlow i SharedFlow , que bà sicament són l'evolució natural per gestionar fluxos de dades de manera reactiva i eficient.
La veritat és que, encara que al principi puguin semblar conceptes similars, cadascú té la seva pròpia raó de ser. No és el mateix voler que la pantalla recordi on es va quedar la llista de notÃcies que llançar un avÃs rà pid d'un Toast que només s'ha de veure una vegada. Per no embolicar-nos, desglossarem com funcionen aquests fluxos calents i per què hauries de considerar deixar enrere LiveData en els teus projectes moderns.
El concepte de Flow: Fred o Calent?
Per entendre StateFlow i SharedFlow, primer cal agafar la diferència entre un flux fred i un de calent. Un Flow està ndard és fred , el que significa que és com una recepta: no passa res fins que algú decideix executar-la (trucar a collect). El problema és que, si tens tres subscriptors, el codi del productor sexecuta tres vegades, el que pot picar la bateria o fer peticions redundants a lAPI.
Aquà és on entren els fluxos calents. Tant StateFlow com SharedFlow són estratègicament calents , la qual cosa implica que el productor roman actiu independentment de si hi ha algú escoltant o no. Això permet que múltiples col·lectors comparteixin la mateixa font de dades , evitant que l'app faci el mateix treball una vegada i una altra, una cosa vital per mantenir la fluïdesa del sistema.
StateFlow: El substitut ideal per a LiveData
StateFlow és bà sicament un contenidor d'estat. La seva caracterÃstica principal és que sempre manté un valor actual , el qual es pot consultar de forma sÃncrona mitjançant la propietat .value. És l'eina perfecta per gestionar l'estat de la interfÃcie d'usuari, com si una pantalla carrega o si les dades d'un perfil s'han actualitzat correctament.
A diferència de LiveData, StateFlow exigeix ​​un valor inicial al seu constructor, cosa que elimina la incertesa de tenir estats nuls en arrencar. A més, implementa un comportament de conflació i deduplicació : si emets el mateix valor dues vegades seguides, el flux simplement ho ignora. Això és genial per evitar que la UI es refresqui innecessà riament quan la dada realment no ha canviat.
Per implementar-lo en un ViewModel, el més recomanable és fer servir una propietat de suport MutableStateFlow privada i exposar-la com un StateFlow immutable. Aixà ens assegurem que només el ViewModel pugui alterar l'estat, respectant el flux de dades unidireccional i evitant que la vista faci entremaliadures amb les dades.
SharedFlow: El bus d'esdeveniments per a accions úniques
Si StateFlow és per a l'estat, SharedFlow és per als esdeveniments. Imagina que vols mostrar un dià leg derror o navegar a una altra pantalla. Si fas servir StateFlow, en rotar el dispositiu, el nou col·lector rebria l'últim valor i l'esdeveniment es dispararia de nou , la qual cosa és un error garrafal. SharedFlow soluciona això perquè es pot configurar amb un replay igual a zero.
Aquest flux és molt més flexible i ens permet ajustar parà metres com el buffer de desbordament . Si el buffer s'omple, podem triar que l'emissor se suspengui o que se'n descarti el valor més antic o el més recent. Un avantatge clau és que SharedFlow permet emetre valors repetits ; si necessites enviar tres vegades el mateix avÃs de «Error de connexió», SharedFlow ho farà sense pestanyar, mentre que StateFlow els filtraria.
Comparativa tècnica: StateFlow vs SharedFlow vs LiveData
Perquè no hi hagi dubtes en una entrevista tècnica o en dissenyar la teva arquitectura, cal mirar els punts crÃtics. LiveData és senzill i gestiona el cicle de vida automà ticament , però està molt lligat a Android. StateFlow i SharedFlow, en ser part de Kotlin Coroutines, són independents de la plataforma , la qual cosa facilita enormement les proves unità ries i la creació de capes de domini netes.
- StateFlow: Obliga a tenir valor inicial, té .value, deduplica valors i és ideal per a estats dUI.
- SharedFlow: No requereix valor inicial, és configurable quant a replay i és l'opció correcta per a esdeveniments efÃmers.
- LiveData: No requereix valor inicial, és conscient del cicle de vida però menys potent en transformacions asÃncrones.
La importà ncia de la recol·lecció segura
Un error molt comú és llançar un collect dins un scope de corrutina simple a l'Activity. Això és perillós perquè el flux seguirà processant dades encara que l'app estigui en segon pla , cosa que pot provocar crashes o un consum excessiu de CPU. La solució moderna és utilitzar l'API repeatOnLifecycle(Lifecycle.State.STARTED).
Aquesta funció fa que la recol·lecció s'activi quan la vista és visible i es cancel·li automà ticament en arribar a l'estat STOPPED . En el cas de Jetpack Compose, la recomanació és fer servir collectAsStateWithLifecycle() , que integra aquesta lògica de forma nativa i assegura que l'aplicació sigui eficient amb els recursos del dispositiu.
Transformant fluxos freds en calents
De vegades tenim un flux que ve de base de dades (com Room) o d'un repositori i és fred. Per convertir-lo en un calent, fem servir els operadors stateIn o shareIn . Aquests operadors requereixen un CoroutineScope i una estratègia inicial. La més habitual és SharingStarted.WhileSubscribed(5000).
Aquesta configuració és brillant perquè manté el flux actiu mentre hi ha subscriptors i, si es tanca la pantalla, espera 5 segons abans d'aturar el productor. Això és fonamental perquè, durant una rotació de pantalla , el flux no es destrueixi i es torni a crear, evitant aixà peticions innecessà ries al servidor oa la base de dades local.
Dominar aquestes eines implica entendre que l'estat ha de ser persistent i deduplicat mitjançant StateFlow mentre que les accions puntuals han de fluir a través de SharedFlow. En combinar-ho amb la recol·lecció conscient del cicle de vida i la transformació de fluxos freds mitjançant stateIn, aconseguim una arquitectura Android robusta, totalment reactiva i optimitzada per al rendiment real en dispositius mòbils. Comparteix la guia i ajuda a altres a conèixer del tema.
