0Pricing
Kotlin Academy · Aula

SharedFlow: barramentos de eventos e eventos de disparo único

Configure a repetição de SharedFlow e extraBufferCapacity para transmitir eventos.

SharedFlow: barramentos de eventos e eventos de disparo único é uma aula grátis de Kotlin Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Kotlin Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Kotlin Academy inclui 4 aulas no total.

O Que é SharedFlow

SharedFlow é um fluxo quente que transmite dados para todos os coletores ativos. Ao contrário de StateFlow, ele não tem o conceito de valor atual — é puramente orientado a eventos.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val events = MutableSharedFlow<String>()
    launch { events.collect { println("Collector 1: $it") } }
    launch { events.collect { println("Collector 2: $it") } }
    delay(50)
    events.emit("UserLoggedIn")
    events.emit("DataRefreshed")
    delay(50)
    coroutineContext.cancelChildren()
}

Parâmetro de Repetição

replay armazena em buffer as últimas N emissões. Novos coletores recebem imediatamente até N eventos anteriores. O padrão é 0 (sem repetição).

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val flow = MutableSharedFlow<Int>(replay = 2)
    flow.emit(1); flow.emit(2); flow.emit(3)
    // Late subscriber gets last 2:
    flow.collect { print("$it ") }  // prints 2 3
}

extraBufferCapacity

extraBufferCapacity adiciona espaço ao buffer além da repetição. Os emissores podem emitir sem suspensão até que o buffer fique cheio.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val flow = MutableSharedFlow<Int>(
        replay = 0,
        extraBufferCapacity = 10
    )
    // Can emit up to 10 times without a collector ready:
    repeat(10) { flow.tryEmit(it) }
    launch { flow.collect { print("$it ") } }
    delay(50)
    coroutineContext.cancelChildren()
}

tryEmit para Emissão sem Suspensão

tryEmit(value) emite sem suspender e retorna false se o buffer estiver cheio. Use-o em contextos que não permitem suspensão (retornos de chamada e manipuladores de cliques).

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val flow = MutableSharedFlow<String>(extraBufferCapacity = 5)
    val ok = flow.tryEmit("click")  // non-suspending
    println("Emitted: $ok")
    launch { flow.collect { println(it) } }
    delay(50)
    coroutineContext.cancelChildren()
}

Eventos de Execução Única (Navegação da Interface)

Use SharedFlow com replay=0 para eventos de execução única da interface, como navegação ou exibição de uma barra de notificação — os eventos não são repetidos durante a recomposição.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
class NavViewModel {
    private val _events = MutableSharedFlow<String>()
    val events = _events.asSharedFlow()
    fun navigateTo(route: String) {
        // viewModelScope.launch:
        kotlinx.coroutines.GlobalScope.launch { _events.emit(route) }
    }
}
// Collect in UI:
// viewModel.events.collect { route -> navController.navigate(route) }

SharedFlow versus StateFlow

StateFlow: estado com valor atual (estado da interface). SharedFlow: eventos sem persistência (navegação, barra de notificação e análise). Escolha com base na necessidade de os consumidores receberem o valor mais recente.

import kotlinx.coroutines.flow.*
// StateFlow: always has a value; new subscribers get current value
val uiState = MutableStateFlow("idle")

// SharedFlow: no stored value; events fire and are gone (unless replay>0)
val singleEvents = MutableSharedFlow<String>(replay = 0)

fun main() { println("State = what it is; Event = what happened") }

Barramento de Eventos com SharedFlow

Implemente um barramento de eventos simples para toda a aplicação usando um SharedFlow singleton, substituindo os padrões de PublishSubject do RxJava.

import kotlinx.coroutines.flow.*
object EventBus {
    private val _events = MutableSharedFlow<Any>(extraBufferCapacity = 100)
    val events = _events.asSharedFlow()
    fun post(event: Any) { _events.tryEmit(event) }
}
sealed class AppEvent {
    object UserLoggedOut : AppEvent()
    data class ShowError(val msg: String) : AppEvent()
}
// Usage: EventBus.post(AppEvent.UserLoggedOut)

subscriptionCount

sharedFlow.subscriptionCount é um StateFlow que acompanha o número de coletores ativos — útil para iniciar ou parar produtores upstream.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val flow = MutableSharedFlow<Int>()
    println("Subscribers: ${flow.subscriptionCount.value}")  // 0
    val job = launch { flow.collect { } }
    delay(50)
    println("Subscribers: ${flow.subscriptionCount.value}")  // 1
    job.cancel()
    delay(50)
    println("Subscribers: ${flow.subscriptionCount.value}")  // 0
}

resetReplayCache

resetReplayCache() limpa o cache de repetição armazenado em buffer, o que é útil quando os eventos repetidos estão obsoletos e novos assinantes não devem vê-los.

import kotlinx.coroutines.flow.*
fun main() {
    val flow = MutableSharedFlow<Int>(replay = 3)
    flow.tryEmit(1); flow.tryEmit(2); flow.tryEmit(3)
    println("Replay cache: ${flow.replayCache}")  // [1, 2, 3]
    flow.resetReplayCache()
    println("Replay cache: ${flow.replayCache}")  // []
}

Como lidar com a contrapressão em SharedFlow

Quando os coletores são lentos, use onBufferOverflow para escolher: SUSPEND (padrão), DROP_OLDEST ou DROP_LATEST.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.channels.BufferOverflow
fun main() = runBlocking {
    val flow = MutableSharedFlow<Int>(
        replay = 0,
        extraBufferCapacity = 3,
        onBufferOverflow = BufferOverflow.DROP_OLDEST
    )
    repeat(10) { flow.tryEmit(it) }
    launch {
        flow.collect { println(it) }  // only sees most recent 3
    }
    delay(50)
    coroutineContext.cancelChildren()
}

Coleta com limite de tempo

Colete um SharedFlow com um limite de tempo para processar um número finito de eventos e depois parar, o que é útil para testes ou processamento limitado.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val events = MutableSharedFlow<String>()
    launch { repeat(5) { delay(50); events.emit("Event $it") } }
    withTimeoutOrNull(200) {
        events.collect { println(it) }
    }
    println("Done collecting")
}

Verificação rápida

Qual valor de repetição deve ser usado para eventos de interface de ocorrência única, como navegação?

Recapitulação

SharedFlow é um difusor ativo de eventos. Use replay=0 para eventos de ocorrência única e replay>0 para assinantes tardios. Use tryEmit em contextos que não permitem suspensão. Escolha SharedFlow para eventos e StateFlow para estados.

Perguntas Frequentes

A aula “SharedFlow: barramentos de eventos e eventos de disparo único” é grátis?

Sim — o texto completo de “SharedFlow: barramentos de eventos e eventos de disparo único” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Kotlin Academy, atualize para CoddyKit PRO. O curso de Kotlin Academy inclui 4 aulas no total.

O que vou aprender em “SharedFlow: barramentos de eventos e eventos de disparo único”?

Configure a repetição de SharedFlow e extraBufferCapacity para transmitir eventos. Você pratica Kotlin Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Kotlin Academy?

Nenhuma experiência prévia é necessária. Kotlin Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “SharedFlow: barramentos de eventos e eventos de disparo único”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Kotlin Academy?

Sim. Cada aula de Kotlin Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. StateFlow: contêiner de estado ativo para a interface
  2. SharedFlow: barramentos de eventos e eventos de disparo único
  3. Convertendo Flow frio em ativo com shareIn e stateIn
  4. Testando StateFlow e SharedFlow com Turbine
← Voltar para Kotlin Academy