A versão Kotlin das APIs Home usa fluxos, um recurso da linguagem Kotlin que oferece recursos avançados para lidar com fluxos de dados assíncronos, incluindo transformação, filtragem, mapeamento, conversão de e para coleções e assim por diante.
As corrotinas estão estreitamente associadas aos fluxos e oferecem uma abstração elegante para a gravação de código assíncrono e liberam o desenvolvedor de ter que gravar rotinas de callback explicitamente. Os fluxos funcionam em conjunto com as corrotinas, servindo como uma maneira de extrair dados de corrotinas de forma assíncrona, sem precisar aguardar a conclusão de uma função ou linha de execução.
Os dados são extraídos de um fluxo pelo consumidor em um processo chamado coleta.
Os fluxos do Kotlin têm uma função collect()
que pode ser usada para esse fim. O que
acontece em um fluxo durante a coleta depende do tipo de fluxo.
Os fluxos do Kotlin (Flow<T>
) são frios por padrão, o que significa que o código do builder
de fluxos produz dados somente quando collect()
é chamado. Um fluxo quente, por outro lado,
produz dados imediatamente, armazenando-os em buffer na memória como uma fila sempre que os
dados são consumidos. Como ele mantém dados na memória, um fluxo quente é considerado
como stateful.
Os fluxos podem ser convertidos de frio para quente usando o operador shareIn
. Consulte Como converter fluxos frios em quentes usando
shareIn
.
Você também pode usar SharedFlow
ou StateFlow
para transformar um fluxo frio em um
quente.
Como o app de exemplo usa fluxos
O app de exemplo usa modelos de visualização no Jetpack Compose conectado aos fluxos nas APIs Home. Muitos dos elementos da interface de exemplo do app são orientados por estado, mas podem ser usados para interação. O app de exemplo também combina o estado dos dispositivos com um estado "otimista" na interface para uma experiência do usuário em tempo real. O termo otimista significa que o app presume que uma determinada ação foi concluída e atualiza imediatamente a interface para refletir o resultado esperado sem esperar a confirmação. Se a ação falhar, a interface será atualizada para refletir o estado real.
No app de exemplo, os fluxos são criados para cada camada do modelo de visualização (estruturas,
ambientes, dispositivos). Por exemplo, ele faz isso para estruturas com a seguinte
chamada em 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()
coleta todos os valores do fluxo especificado e os emite para o
coletor. O stateIn()
compartilha o valor emitido mais recentemente de uma única
instância em execução do fluxo upstream com vários assinantes downstream. Consulte
a referência
kotlinx.coroutines.flow
para mais informações.
Jetpack Compose
Para armazenar objetos de fluxo na memória local e evitar que eles sejam encerrados,
use a API
remember
do Kotlin.
No Jetpack Compose, se você usar isso com
collectAsStateWithLifecycle()
,
o Jetpack vai gerenciar automaticamente a inscrição e a remoção de inscrição de fluxos com base em
se a interface do aplicativo que mostra esse estado está realmente em primeiro plano ou
não.
Uma chamada simples no app de exemplo faz isso. Usando a função getStructuresState()
mostrada anteriormente:
val structuresList by
remember(globalViewModel) { globalViewModel.getStructuresState() }.collectAsStateWithLifecycle()
Agora, quando qualquer estado da estrutura muda (como o name
), a
função combinável que o usa reflete esse estado atualizado automaticamente.
No app de exemplo, essa é a função HomeActivityContent()
.
Recursos
Para mais informações sobre Kotlin, fluxos, corrotinas e Jetpack Compose, consulte os seguintes recursos:
- Desenvolver apps Android com o Kotlin
- Conheça o Kotlin para Android
- Corrotinas do Kotlin no Android. Estes codelabs específicos podem ser úteis:
- Fluxos Kotlin no Android e, mais especificamente, StateFlow.
- Estado e Jetpack Compose, especificamente a
função
collectAsStateWithLifecycle()
. Essa função gerencia automaticamente a inscrição e a desinscrição dos fluxos com base em se a IU que mostra esse estado está realmente em primeiro plano ou não. - Se você estiver trabalhando com a API Automation, leia sobre builders com segurança de tipo do Kotlin para entender como a DSL Automation funciona.