SharedFlow & StateFlow

유정현·2024년 5월 30일
0

이전 포스트에서 cold stream과 hot stream을 다루었다.
이번에는 hot stream(flow)인 stateflow와 sharedflow를 다루고자 한다.

내부 구조

SharedFlow의 내부는 다음과 같이 구성된다

interface SharedFlow<out T> : Flow<T> {
  ...
}

StateFlow의 내부는 다음과 같이 구성된다

interface StateFlow<out T> : SharedFlow<T> {
    /**
     * The current value of this state flow.
     */
    public val value: T
}

구현 관계를 보면 SharedFlow는 StateFlow의 추상화된 버전이다.

정리하자면 Flow들은 다음과 같은 계층 구조를 가지고 있다.
Flow <- SharedFlow <- StateFlow

StateFlow

  • SharedFlow의 구체화 버전이다.
  • 구성 변경 시 기존 구독자뿐만 아니라 새로운 구독자에게 가장 최근의 데이터를 방출한다.
  • 중단되지 않는 방식으로 .value 속성을 사용하여 get 또는 set 할 수 있다.
private val _stateFlow = MutableStateFlow("Hello")
    val stateFlow = _stateFlow.asStateFlow()

    fun triggerStateFlow() {
        _stateFlow.value = "StateFlow"
    }

StateFlow는 LiveData와 유사하지만 다른 점이 state를 가질 수 있다는 것이다. 그래서 초기값이 필요하다.

SharedFlow

  • stateflow의 일반화 버전이다.
  • 시간이 지남에 따라 동일한 이벤트를 트리거해야 하는 경우에 더 적합하도록 동일한 값을 재방출한다.
private val _sharedFlow = MutableSharedFlow<String>()
    val sharedFlow = _sharedFlow.asSharedFlow()

    fun triggerSharedFlow() {
        viewModelScope.launch {
            _sharedFlow.emit("SharedFlow")
        }
    }

SharedFlow는 이벤트 형태로 값을 전달한다.

StateFlow vs SharedFlow

activity에서 state를 변화시키고 이를 Toast로 출력

with(binding) {
            btnStateflow.setOnClickListener { viewModel.triggerStateFlow() }
            btnSharedflow.setOnClickListener { viewModel.triggerSharedFlow() }
        }

        // stateflow
        lifecycleScope.launch {
            viewModel.stateFlow.collectLatest {
                Toast.makeText(this@MainActivity, it, Toast.LENGTH_SHORT).show()
            }
        }

        // sharedflow
        lifecycleScope.launch {
            viewModel.sharedFlow.collectLatest {
                Toast.makeText(this@MainActivity, it, Toast.LENGTH_SHORT).show()
            }
        }
  • stateflow

    stateflow 버튼을 클릭하면 토스트 메세지가 처음 한번 보여진다. 하지만 이후에 버튼을 다시 클릭해도 상태가 변하지 않기 때문에 토스트 메세지가 보여지지 않는다.
  • sharedflow

    sharedflow는 상태가 아닌 이벤트를 전달하기 때문에 여러번 버튼을 클릭하면 계속 토스트 메시지를 확인할 수 있다.

0개의 댓글