StateFlow vs SharedFlow
StateFlow, SharedFlow
StateFlow, SharedFlow
상속관계, Cold/Hot stream
Flow <- SharedFlow <- StateFlow
Flow
Cold stream, collect 를 할 때마다 emit 된 모든 값들을 받는다.
ex) 어떤 Flow 를 1부터 10사이의 모든 정수를 emit(방출) 한 경우, Collector 가 해당 Flow 를 collect 하면 모든 값(1~10사이의 정수, 이때 까지 emit된 모든 값)들을 전달받음
SharedFlow, StateFlow
Hot stream, collect 이 시작된 시점 이후의 emit 된 값을 전달받음
StateFlow
StateFlow 는 가장 최신의 값만 내보낸다(emit)
MutableStateFlow
값을 바꿀 수 있음
MutableStateFlow 는 인스턴스 생성 시 초기 값 을 필수로 설정해야 한다.
StateFlow 는 State 를 표현하는 Data Model 로 사용하기에 유용함
Flow 에서는 여러 연산자들을 사용해서 다양한 값 로 바꾸고 정의할 수 있음
특히 Combine 연산자는 임의의 함수 를 사용하여 여러 StateFlow 의 값들을 결합 하는 데 유용함
class CounterModel {
private val _counter = MutableStateFlow(0)
val counter = _counter.asStateFlow()
fun increment() {
_counter.update {
count → count + 1
}
}
}
val aModel = CounterModel()
val bModel = CounterModel()
val sumFlow : Flow<Int> = aModel.counter.combine(bModel.counter) {
a, b → a + b
}
MutableStateFlow의 대안으로, stateIn 연산자를 통해서 ColdFlow를 StateFlow로 변환할 수 있음
SharedFlow
가장 최근의 값만 내보내지 않고, collect 이전에 emit 된 값들에 대해 내보낼 값의 개수를 지정하는 것이 가능
Buffer 가 가득 찼을 경우의 처리 동작을 설정 가능
StateFlow 대신 SharedFlow를 사용하는 경우
- 여러 개의 값들을 가지면서, 사용하고자 할 때
- 초기 값을 생략하고자 할 때
- 추가 Buffering이 필요할 때
StateFlow는 SharedFlow이다
StateFlow 는 좁지만 널리 사용되는 상태 공유를 위한 SharedFlow 의 특수 목적, 고성능, 효율적인 구현이다.
StateFlow 는 새로운 Collector(Subscriber) 에게 가장 최근의 값만을 주고, 2개 이상의 값은 담아두지 않음
아래와 같이 MutableSharedFlow 에 매개변수를 지정하고, distinctUntilChanged() 를 사용하면 SharedFlow 를 StateFlow 처럼 사용가능
val shared = MutableSharedFlow(
replay = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST
)
shared.tryEmit(initialValue)
val state = shared.distinctUntilChanged()
MutableSharedFlow 생성 매개변수
replay
collect 시 전달받을 방출된(emitted) 데이터의 개수를 설정
동시성(Concurrency)
모든 StateFlow 의 메서드는 Thread-safe
Coroutine 에서 외부 동기화 없이 안전하게 호출가능
연산자 융합(Operator fusion)
StateFlow 은 flowOn, conflate, CONFLATED or RENDEZVOUS capacity, distinctUntilChanged, cancellable 연산자를 사용하더라도 영향을 받지 않음