La versión de Kotlin de las APIs de Home usa flujos, una función del lenguaje Kotlin que proporciona capacidades potentes para controlar flujos de datos asíncronos, como transformar, filtrar, asignar, convertir a colecciones y viceversa, entre otros.
Las corrutinas están asociadas estrechamente con los flujos y proporcionan una abstracción elegante para escribir código asíncrono y liberar al desarrollador de tener que escribir rutinas de devolución de llamada de forma explícita. Los flujos funcionan en conjunto con las corrutinas y sirven como una forma de recuperar datos de las corrutinas de forma asíncrona, sin tener que esperar a que se complete una función o un subproceso.
El consumidor recupera datos de un flujo en un proceso llamado recopilación.
Los flujos de Kotlin tienen una función collect()
que se puede usar para este propósito. Lo que sucede en un flujo durante la recopilación depende del tipo de flujo.
Los flujos de Kotlin (Flow<T>
) son fijos de forma predeterminada, lo que significa que el código del compilador de flujos solo produce datos cuando se llama a collect()
. Por el contrario, un flujo caliente produce datos de inmediato y los almacena en búfer en la memoria como una cola para cada vez que se consumen los datos. Debido a que mantiene los datos en la memoria, un flujo activo se considera
con estado.
Los flujos se pueden convertir de fríos a calientes con el operador shareIn
(consulta Cómo convertir flujos fríos en flujos calientes con shareIn
). También puedes usar SharedFlow
o StateFlow
para convertir un flujo frío en un flujo caliente.
Cómo usa flujos la app de ejemplo
La app de ejemplo usa modelos de vista en Jetpack Compose conectados a los flujos de las APIs de Home. Muchos de los elementos de la IU de la app de ejemplo se basan en el estado, pero se puede interactuar con ellos. La app de ejemplo también combina el estado de los dispositivos con un estado "optimista" en la IU para brindar una experiencia del usuario en tiempo real. El término optimista significa que la app supone que una acción determinada se realizó correctamente y actualiza de inmediato la IU para reflejar el resultado esperado sin esperar confirmación. Si resulta que la acción falló, la IU se actualiza para reflejar el estado real.
En la app de ejemplo, se crean flujos para cada capa del modelo de vista (estructuras,
cuartos y dispositivos). Por ejemplo, lo hace para las estructuras con la siguiente llamada en GlobalViewModel.kt
:
fun getStructuresState(): StateFlow<List<StructureModel>?> =
homeClient
.structures()
.map { structures -> structures.map { StructureModel(it.name, it) }.sortedBy { it.name } }
.handleErrors()
.flowOn(Dispatchers.IO)
.stateIn(scope = viewModelScope, started = SharingStarted.WhileSubscribed(), null)
emitAll()
recopila todos los valores del flujo determinado y los emite al recopilador. stateIn()
comparte el valor emitido más recientemente de una sola instancia en ejecución del flujo ascendente con varios suscriptores descendentes. Consulta la referencia de kotlinx.coroutines.flow
para obtener más información.
Jetpack Compose
Para almacenar objetos de flujo en la memoria local y evitar que se cierren, usa la API de remember
de Kotlin.
En Jetpack Compose, si usas esto con collectAsStateWithLifecycle()
, Jetpack administra automáticamente la suscripción y la cancelación de la suscripción a los flujos según si la IU de la aplicación que muestra ese estado está en primer plano o no.
Una llamada simple en la app de ejemplo hace esto. Usa la función getStructuresState()
que se mostró antes:
val structuresList by
remember(globalViewModel) { globalViewModel.getStructuresState() }.collectAsStateWithLifecycle()
Ahora, cuando cambie cualquier estado de la estructura (como name
), la función de Composable que la use reflejará ese estado actualizado automáticamente.
En la app de ejemplo, esta es la función HomeActivityContent()
.
Recursos
Para obtener más información sobre Kotlin, flujos, corrutinas y Jetpack Compose, consulta los siguientes recursos:
- Desarrolla apps para Android con Kotlin
- Aprende a usar Kotlin para Android
- Corrutinas de Kotlin en Android. Estos codelabs específicos pueden ser útiles:
- Flujos de Kotlin en Android y, más específicamente, StateFlow.
- El estado y Jetpack Compose, específicamente la función
collectAsStateWithLifecycle()
. Esta función administra automáticamente la suscripción y la cancelación de la suscripción a los flujos según si la IU que muestra ese estado está en primer plano o no. - Si trabajas con la API de Automation, es útil leer sobre los compiladores de acceso seguro a tipos de Kotlin para comprender cómo funciona el DSL de Automation.