Garanta sua assinatura com até 35%OFF antes do reajuste. Quero aproveitar

Kotlin: dominando StateFlow e SharedFlow para concorrência impecável
Rocketseat

Rocketseat

6 min de leitura
Kotlin
Você sabia que o Kotlin é a linguagem oficial para desenvolvimento Android e que gigantes como Google, Twitter e Amazon a utilizam em seus aplicativos? E adivinhe só: StateFlow e SharedFlow são peças-chave para o sucesso dessas empresas quando o assunto é concorrência e reatividade. Quer saber como a Rocketseat também utiliza essas ferramentas para criar experiências incríveis? Então você está no lugar certo!
Imagine que você está desenvolvendo uma aplicação que precisa responder a dados em tempo real, como mensagens de chat ou atualizações de clima. Garantir que a interface esteja sempre sincronizada com o estado atual sem perder informações importantes pode ser desafiador. É aqui que o StateFlow e o SharedFlow, ferramentas poderosas da biblioteca kotlinx.coroutines, entram em cena. Neste artigo, vamos desmistificar esses conceitos e mostrar como aplicá-los em seus projetos Kotlin, garantindo código mais robusto e eficiente.

Entendendo Flows no Kotlin

Antes de mergulharmos no StateFlow e no SharedFlow, é fundamental entender o conceito de Flow, que serve como base para essas ferramentas. Para isso, vamos trazer um exemplo diretamente do universo Rocketseat.
Pense em um Flow como uma esteira de aprendizado na Rocketseat. Cada valor emitido representa uma etapa do seu progresso em um curso da plataforma. Desde "Preparando o Ambiente" até a "Entrega do Projeto Final", cada etapa é processada de forma assíncrona, garantindo que você avance em seu próprio ritmo sem interromper o restante da aplicação.
Aqui está um exemplo prático:
import kotlinx.coroutines.flow.* import kotlinx.coroutines.runBlocking import kotlinx.coroutines.delay fun rocketseatFlow(): Flow<String> = flow { val etapas = listOf( "Preparando o Ambiente", "Fundamentos do Kotlin", "Primeiro Projeto com Jetpack Compose", "Testes Automatizados", "Publicação na Play Store" ) for (etapa in etapas) { delay(6000) // Simulando o tempo de conclusão de cada etapa emit(etapa) // Emitindo a próxima etapa } } fun main() = runBlocking { rocketseatFlow().collect { etapa -> println("Progresso na formação: $etapa") } }
Nesse exemplo, a função rocketseatFlow simula as etapas de uma formação da Rocketseat, com cada etapa sendo emitida após um intervalo de 6 segundos. A função collect consome essas etapas e as imprime no console, criando uma experiência contínua de progresso no aprendizado.
Essa abordagem simples demonstra o poder dos Flows em lidar com sequências de dados assíncronas. E na Rocketseat, é assim que transformamos aprendizado em jornadas reativas e dinâmicas para os nossos devs!

StateFlow: o guardião do estado

O StateFlow é um tipo especializado de Flow projetado para armazenar e compartilhar o estado atual de forma segura. Ele garante que qualquer coletor sempre receba o estado mais recente, tornando-o perfeito para gerenciar estados reativos em aplicações Kotlin, como o estado de uma interface de usuário.

Características principais

  • Valor inicial obrigatório: sempre começa com um estado inicial definido.
  • Atualizações confladas: emite apenas o valor mais recente, ignorando atualizações intermediárias.
  • Imutabilidade para coletores: exponha o StateFlow como somente leitura para segurança.

Criando e usando um StateFlow

Considere um cenário em que você precisa criar um painel de controle na Rocketseat para gerenciar alunos em tempo real. É necessário exibir o número de alunos ativos no momento e atualizar esse valor conforme os eventos chegam. Veja como o StateFlow pode ser utilizado:
import kotlinx.coroutines.flow.* import kotlinx.coroutines.runBlocking import kotlinx.coroutines.launch class ActiveStudentsManager { private val _activeStudents = MutableStateFlow(0) // Estado inicial val activeStudents: StateFlow<Int> = _activeStudents.asStateFlow() // Expondo como somente leitura fun studentJoined() { _activeStudents.value += 1 } fun studentLeft() { _activeStudents.value -= 1 } } fun main() = runBlocking { val manager = ActiveStudentsManager() // Coletor de estado launch { manager.activeStudents.collect { count -> println("Número de alunos ativos: $count") } } // Alterando o estado manager.studentJoined() manager.studentLeft() }
Nesse exemplo, criamos um gerenciador de alunos ativos. Sempre que um aluno entra ou sai, o estado é atualizado, e o coletor exibe o valor mais recente. Essa abordagem é eficiente e garante que todos os interessados no estado da aplicação tenham acesso imediato às atualizações.

SharedFlow: compartilhando o fluxo

O SharedFlow é perfeito para transmitir eventos em tempo real para múltiplos coletores. Diferente do StateFlow, ele não mantém um estado atual, mas funciona como um transmissor contínuo de informações. Ideal para notificações ou eventos que não precisam ser persistidos.

Características principais

  • Sem estado inicial: não exige um valor inicial.
  • Configuração de replay: pode "repetir" eventos passados para novos coletores.
  • Flexibilidade no buffer: configurável para diferentes comportamentos de buffer.

Criando e usando um SharedFlow

Agora, imagine que estamos construindo o sistema de eventos de uma mentoria ao vivo na Rocketseat. Durante a sessão, mensagens de chat são enviadas para todos os participantes conectados. Veja como isso seria implementado:
import kotlinx.coroutines.flow.* import kotlinx.coroutines.runBlocking import kotlinx.coroutines.launch class MentoringChat { private val _messages = MutableSharedFlow<String>(replay = 3) // Repassa as últimas 3 mensagens val messages = _messages.asSharedFlow() suspend fun sendMessage(message: String) { _messages.emit(message) } } fun main() = runBlocking { val chat = MentoringChat() // Coletores de mensagens launch { chat.messages.collect { message -> println("Participante 1 recebeu: $message") } } launch { chat.messages.collect { message -> println("Participante 2 recebeu: $message") } } // Enviando mensagens chat.sendMessage("Bem-vindos à mentoria Rocketseat!") chat.sendMessage("Preparem suas perguntas!") chat.sendMessage("Começando em 3... 2... 1!") }
Aqui, usamos o SharedFlow para gerenciar as mensagens de um chat de mentoria. Cada participante conectado recebe todas as mensagens enviadas. Além disso, configuramos um replay de três mensagens para garantir que novos participantes também tenham acesso ao histórico recente.

Integração e boas práticas

Integrar StateFlow e SharedFlow é como montar uma orquestra: cada instrumento tem seu papel, e juntos criam uma harmonia perfeita. Essas ferramentas permitem construir sistemas reativos que lidam tanto com estados contínuos quanto com eventos dinâmicos, garantindo aplicações Kotlin mais eficientes e organizadas.
Suponha a plataforma da Rocketseat como um exemplo prático. Enquanto o StateFlow pode ser usado para monitorar o progresso do aluno em um curso — exibindo o percentual concluído ou as aulas assistidas — o SharedFlow pode cuidar de eventos como notificações em tempo real, como novas perguntas em uma mentoria ou comentários feitos durante um curso ou formação.

Dicas valiosas para usar StateFlow e SharedFlow

  1. Encapsule os fluxos com segurança
    1. Exponha apenas versões imutáveis de seus fluxos (asStateFlow() ou asSharedFlow()). Isso protege sua lógica interna de alterações acidentais e garante que apenas as ações controladas possam modificar os dados.
      private val _state = MutableStateFlow(0) val state: StateFlow<Int> = _state.asStateFlow() // Apenas leitura externa
  1. Gerencie recursos com responsabilidade
    1. Sempre cancele corrotinas quando elas não forem mais necessárias. Isso evita vazamentos de memória e melhora significativamente o desempenho da aplicação. Um exemplo clássico é gerenciar os coletores de Flow no ciclo de vida de uma Activity no Android. Utilizando o lifecycleScope, você garante que a coleta dos dados seja encerrada automaticamente quando a Activity sair do estado ativo, como no exemplo a seguir:
      // Dentro de uma Activity lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { myViewModel.myFlow.collect { value -> println("Recebendo valor: $value") // Atualize a UI com o valor recebido } } }
      Nesse código, o Flow definido no myViewModel começa a ser coletado quando a Activity atinge o estado STARTED. Assim que o ciclo de vida muda para STOPPED, a coleta é cancelada automaticamente. Isso protege os recursos e evita vazamentos de memória.
      Agora, considere que estamos em um app da Rocketseat, onde queremos exibir a lista de alunos conectados em uma mentoria ao vivo. Ao usar o lifecycleScope da maneira correta, garantimos que essa lista seja atualizada em tempo real enquanto a mentoria está ativa, e que as atualizações parem assim que a tela é fechada.
      Gerenciar recursos com responsabilidade não é apenas uma boa prática: é essencial para manter a performance e a estabilidade das suas aplicações, entregando a melhor experiência para o usuário.
  1. Transforme dados de forma inteligente
    1. Simplifique a lógica da sua aplicação com operadores como combine, map e filter. Eles ajudam a transformar os dados para atender às suas necessidades sem modificar a origem.
      val combinedFlow = flow1.combine(flow2) { value1, value2 -> value1 + value2 } combinedFlow.collect { println("Valor combinado: $it") }
  1. Teste e depure seus fluxos
    1. Antes de implementar, use ferramentas como Turbine para testar o comportamento dos fluxos. Isso garante que você saiba exatamente como seus dados fluem na aplicação, mesmo em cenários complexos.
  1. Aproveite a flexibilidade do SharedFlow
    1. Configure o replay e o buffer para atender diferentes necessidades. Por exemplo, em uma aplicação de eventos ao vivo, configure o replay para garantir que novos usuários recebam as últimas mensagens enviadas.
Ao aplicar essas práticas, você não apenas aumenta a qualidade do seu código, mas também entrega uma experiência de usuário mais fluida e confiável. Combine as capacidades do StateFlow e do SharedFlow com a paixão pela tecnologia, e o resultado será nada menos que incrível.

Recursos extras para dominar o StateFlow e SharedFlow

Chegamos ao final da nossa jornada de aprendizado sobre StateFlow e SharedFlow, mas ela não precisa terminar aqui! Para se tornar um verdadeiro mestre da concorrência e reatividade em Kotlin, mergulhe fundo nos recursos abaixo:
  • Documentação Oficial do StateFlow: a fonte definitiva de conhecimento sobre StateFlow. Explore todos os detalhes, métodos e parâmetros disponíveis. Essencial para consultas aprofundadas.

Conclusão: sua jornada começa agora!

Explorar as possibilidades do StateFlow e do SharedFlow é mais do que dominar conceitos técnicos: é abrir as portas para criar aplicações Kotlin mais robustas, eficientes e modernas. Com essas ferramentas, você está pronto para construir soluções que impressionam pela qualidade e performance.
Mas o que diferencia os programadores que apenas entendem desses conceitos daqueles que transformam carreiras e alcançam grandes conquistas? A prática, o suporte certo e um aprendizado estruturado. E aqui entra a formação Android com Kotlin da Rocketseat: o caminho definitivo para você se tornar um especialista no desenvolvimento de apps Android.

Por que escolher a Rocketseat para sua jornada?

  • Domine as tecnologias que o mercado deseja: aprenda Kotlin, Jetpack Compose, Clean Architecture e muito mais, em aulas que vão direto ao ponto, ministradas por instrutores experientes, como Bernardo Michel Slailati.
  • Aprenda fazendo: trabalhe em projetos e desafios reais que não só consolidam seu aprendizado, mas também constroem um portfólio que brilha aos olhos de recrutadores.
  • Conquiste oportunidades nas maiores empresas: Spotify, Uber e Slack são apenas algumas das gigantes que utilizam Kotlin. Domine essas tecnologias e aumente suas chances de se destacar no mercado de trabalho, que está em constante busca por profissionais qualificados em Kotlin.
  • Ganhe suporte personalizado: desde tutorias individuais até mentorias de carreira, a Rocketseat vai além de ensinar. Ela te guia em cada passo, ajudando a transformar habilidades em uma carreira de sucesso.
Clique no link abaixo, confira todos os detalhes e dê o primeiro passo em direção à sua transformação como desenvolvedor Android:
Artigos_

Explore conteúdos relacionados

Descubra mais artigos que complementam seu aprendizado e expandem seu conhecimento.

Aprenda programação do zero e DE GRAÇA

No Discover você vai descomplicar a programação, aprender a criar seu primeiro site com a mão na massa e iniciar sua transição de carreira.

COMECE A ESTUDAR AGORA