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
- StateFlow: contêiner de estado ativo para a interface
- SharedFlow: barramentos de eventos e eventos de disparo único
- Convertendo Flow frio em ativo com shareIn e stateIn
- Testando StateFlow e SharedFlow com Turbine