StateFlow, SharedFlow

상속관계, Cold/Hot stream

Flow <- SharedFlow <- StateFlow

Flow

Cold stream, collect 를 할 때마다 emit 된 모든 값들을 받는다.

ex) 어떤 Flow 를 1부터 10사이의 모든 정수를 emit(방출) 한 경우, Collector 가 해당 Flowcollect 하면 모든 값(1~10사이의 정수, 이때 까지 emit된 모든 값)들을 전달받음

SharedFlow, StateFlow

Hot stream, collect 이 시작된 시점 이후의 emit 된 값을 전달받음

StateFlow

StateFlow 는 가장 최신의 값만 내보낸다(emit)

MutableStateFlow

값을 바꿀 수 있음

MutableStateFlow 는 인스턴스 생성 시 초기 값 을 필수로 설정해야 한다.
StateFlowState 를 표현하는 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() 를 사용하면 SharedFlowStateFlow 처럼 사용가능

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)

StateFlowflowOn, conflate, CONFLATED or RENDEZVOUS capacity, distinctUntilChanged, cancellable 연산자를 사용하더라도 영향을 받지 않음