GDSC에서 안드로이드 스터디를 진행하며 Flow에 관해 공부했었다.
그 중, StateFlow와 SharedFlow의 차이점에 대해 조금 더 공부하고자 포스팅을 한다.
그 전에 짚고 넘어갈 점이 있다면, StateFlow와 SharedFlow는 모두 핫 스트림이란 점이다.
콜드 스트림과 핫 스트림의 차이는 아래와 같다.
- 콜드 스트림: 구독자가 스트림을 시작할 때마다 데이터 재생성 및 방출
- 각 구독자는 스트림을 독립적으로 소비
- 각자의 시작점부터 데이터 수신
- 핫 스트림: 데이터를 생성하고 방출하는 주체가 구독자와 독립적으로 동작
- 스트림이 이미 존재하고 있음
- 구독자가 현재의 스트림 상태를 얻거나 중간부터 데이터 수신 가능
- 이벤트 발생 시 모든 구독자에게 동시에 데이터 전달
우선 SharedFlow부터 살펴 보기로 하자.
SharedFlow는 무엇일까?
- SharedFlow: 수집하는 모든 소비자에게 값을 내보내는 핫 스트림 플로우
- 여러 구독자 간에 데이터 공유 가능
- 내부적으로 상태를 유지하고 있기에 현재 상태를 새로운 구독자에게 전달하지만 과거에 있던 정보를 보여주는 것
- Flow를 상속받고 있음
SharedFlow는 Flow를 상속받고 있으며, 여러 구독자가 데이터를 공유할 수 있는 플로우다.
emit 함수를 통해 새로운 이벤트를 방출하고, 구독 중인 모든 구독자에게 이를 전달하게 된다.
SharedFlow는 아래와 같이 생성하고, 방출할 수 있다.
// 생성
val sharedFlow = MutableSharedFlow<Int>()
// 방출
sharedFlow.emit(1)
sharedFlow.emit(2)
sharedFlow.emit(3)
SharedFlow는 중복 값을 필터링 하여 emit 된 값이 중복된다면 collect 하지 않는 특성을 가지고 있으며, 만약 Flow를 SharedFlow로 변경하고 싶다면, SharedIn을 사용할 수 있다.
public fun <T> Flow<T>.shareIn(
scope: CoroutineScope,
started: SharingStarted,
replay: Int = 0
): SharedFlow<T>
위의 코드를 작성하면 Flow가 주어진 코루틴 스코프의 스트림을 SharedFlow로 변경할 수 있다.
그렇다면 StateFlow란 무엇일까?
- StateFlow: 상태를 가지고 있는 Flow
- 상태를 가지고 있기 때문에 새로운 수신자가 등록되면 현재 상태를 즉시 전달 가능
- SharedFlow를 상속 받고 있음
이렇게 간단하게 정의할 수 있다. 단어 그대로 상태를 갖는 Flow다.
StateFlow는 현재 상태와 새로 변경된 상태를 계속 내보내게 된다.
상태를 변경하기 위해서는 MutableStateFlow의 value 값에 할당해주면 된다.
private val stateFlow = MutableStateFlow("First State")
위의 코드가 StateFlow를 생성한 코드다.
이 코드에서 상태를 변경하고자 한다면 아래와 같이 작성하면 된다.
exmaple.value = "Seconde Flow"
앞서 말한 것처럼 value를 사용해 상태를 변경해준 코드다.
StateFlow는 상태를 가지고 있는 Flow이기 때문에 주로 UI처럼 상태 변화에 민감한 애플리케이션에서 사용된다.
만약 Flow를 SharedFlow처럼 핫 스트림으로 변경하고 싶다면, 또다른 방법으로 StateIn을 사용할 수 있다.
fun <T> Flow<T>.stateIn(
scope: CoroutineScope,
started: SharingStarted,
initialValue: T
): StateFlow<T>
위의 코드를 작성하면 Flow가 주어진 코루틴 스코프의 스트림을 StateFlow로 변경할 수 있다.
오늘은 간단하게 SharedFlow와 StateFlow의 차이에 대해서 알아봤다.
사실 이걸 작성하면서도 완전히 이해된 것은 아니라 앞으로도 계속 Flow에 대해서 공부를 해봐야 할 것 같다.
다음에는 이해도를 높이기 위해 Flow 자체에 대한 포스팅을 올려보겠다.