SharedFlow: 이벤트 버스와 일회성 이벤트
이벤트 브로드캐스팅을 위해 SharedFlow의 replay와 extraBufferCapacity를 구성해 보세요.
SharedFlow: 이벤트 버스와 일회성 이벤트은(는) CoddyKit의 무료 Kotlin Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Kotlin Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Kotlin Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
SharedFlow란 무엇입니까?
SharedFlow는 현재 활성 상태인 모든 수집기에 이벤트를 방송하는 핫 흐름입니다. StateFlow와 달리 현재 값이라는 개념이 없으며, 순수하게 이벤트 중심으로 작동합니다.
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()
}replay 매개변수
replay는 최근 N개의 방출을 버퍼에 저장합니다. 새 수집기는 과거 이벤트를 최대 N개까지 즉시 받습니다. 기본값은 0이며, 다시 방출하지 않습니다.
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는 replay 외에 추가 버퍼 공간을 제공합니다. 버퍼가 가득 찰 때까지는 송신자가 일시 중단되지 않고 값을 방출할 수 있습니다.
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
tryEmit(value)는 일시 중단 없이 값을 방출하며, 버퍼가 가득 차면 false를 반환합니다. 일시 중단 함수를 사용할 수 없는 컨텍스트(콜백, 클릭 처리기)에서 사용합니다.
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()
}일회성 이벤트(UI 탐색)
탐색이나 Snackbar 표시 같은 일회성 UI 이벤트에는 replay=0인 SharedFlow를 사용합니다. 재구성될 때 이벤트가 다시 방출되지 않습니다.
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와 StateFlow 비교
StateFlow: 현재 값이 있는 상태(UI 상태)입니다. SharedFlow: 저장되지 않는 이벤트(탐색, Snackbar, 분석)입니다. 소비자에게 최신 값이 필요한지에 따라 선택합니다.
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") }SharedFlow를 사용한 이벤트 버스
싱글턴 SharedFlow를 사용하여 앱 전체에서 사용할 수 있는 간단한 이벤트 버스를 구현하고, RxJava PublishSubject 패턴을 대체합니다.
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는 활성 수집기의 수를 추적하는 StateFlow입니다. 업스트림 생산자를 시작하거나 중지할 때 유용합니다.
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()는 버퍼에 저장된 재방출 캐시를 지웁니다. 재방출된 이벤트가 오래되어 새 구독자에게 보이지 않아야 할 때 유용합니다.
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}") // []
}SharedFlow의 백프레셔 처리
수집기가 느릴 때는 onBufferOverflow를 사용하여 SUSPEND(기본값), DROP_OLDEST 또는 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()
}시간 제한을 둔 수집
시간 제한을 두고 SharedFlow를 수집하면 유한한 수의 이벤트를 처리한 후 중지할 수 있어 테스트나 범위를 제한한 처리에 유용합니다.
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")
}빠른 확인
탐색과 같은 일회성 UI 이벤트에는 어떤 replay 값을 사용해야 할까요?
요약
SharedFlow는 핫 이벤트 브로드캐스터입니다. 일회성 이벤트에는 replay=0을 사용하고, 늦게 구독하는 구독자에게 이벤트 기록을 전달하려면 replay>0을 사용합니다. 일시 중단할 수 없는 컨텍스트에서는 tryEmit을 사용합니다. 이벤트에는 SharedFlow를, 상태에는 StateFlow를 선택합니다.
자주 묻는 질문
“SharedFlow: 이벤트 버스와 일회성 이벤트” 강의는 무료인가요?
네 — “SharedFlow: 이벤트 버스와 일회성 이벤트” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Kotlin Academy 강의 전체를 잠금 해제할 수 있습니다. Kotlin Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“SharedFlow: 이벤트 버스와 일회성 이벤트”에서 뭘 배우나요?
이벤트 브로드캐스팅을 위해 SharedFlow의 replay와 extraBufferCapacity를 구성해 보세요. 브라우저에서 직접 실행하는 실습 코드로 Kotlin Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Kotlin Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Kotlin Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“SharedFlow: 이벤트 버스와 일회성 이벤트” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Kotlin Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Kotlin Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- StateFlow: UI를 위한 핫 상태 보유자
- SharedFlow: 이벤트 버스와 일회성 이벤트
- shareIn과 stateIn으로 콜드 Flow를 핫 Flow로 변환하기
- Turbine으로 StateFlow와 SharedFlow 테스트하기