티스토리 뷰
ColdFlow
콜드 플로우는 구독을 하면 데이터가 계속 흐르는 파이프이다. 따라서 누군가 collect()를 호출 즉, 구독을 해야 받을 수 있다. 콜드 플로우는 구독을 시작해야 emit이 가능하다.
Flow
콜드 플로우이다.
Flow는 Coroutines의 일부분으로, 비동기 데이터 스트림을 처리하는 API이다. Flow는 소비자가 구독을 하면 데이터 생산이 시작되며, 이는 메모리 효율성을 높여준다는 장점이 있다. 비동기로 처리하게 되면 UI를 차단하지 않고 효율적으로 업데이트가 가능하다는 장점이 있다.
HotFlow
핫 플로우는 구독자가 있든 없든 이미 데이터가 흐르고 있는 파이프이다. 즉, 구독자가 있던 없던 emit을 통해 값을 계속 발행할 수 있다.
대표적인 예로는 StateFlow와 SharedFlow가 있다.
StateFlow
핫 플로우이다.
StateFlow는 초기값이 반드시 필요하며, 구독자가 언제 들어와도 전달할 값이 있어야한다. 값이 업데이트 되면 기존 값은 사라진다.
초기값이 있으면 처음부터 내보낼 값이 존재하기 때문에 상태를 처음부터 안정적으로 제공할 수 있다.
또한, StateFlow는 새로운 상태를 내보내는 관찰 가능한 데이터이다. StateFlow는 항상 단 하나의 최신 값을 유지하며, 값을 업데이트하면 이전 값은 덮어쓰여 사라진다. 구독자가 collect를 시작하면 그때의 최신 값만 받는다.
이러한 특징이 초기 상태와 최신 상태가 필요한 UI 상태에 맞기 때문에 안드로이드의 UI 상태는 StateFlow를 사용한다.
StateFlow는 읽기 전용 데이터로 값을 할당해주기 위해서는 MutableStateFlow를 사용하여 값을 할당한다.
private val _uiState = MutableStateFlow(LatestNewsUiState.Success(emptyList()))
val uiState: StateFlow<LatestNewsUiState> = _uiState
compose에서 Flow를 사용하려면 collectAsState()나 collectAsStateWithLifeCycle() 함수를 통해 변환해주어야 한다. 변환을 해주어야 Compose에서 State<T>를 관찰하며, 값이 바뀌면 자동으로 리컴포지션을 발생시키기 때문이다.
단순 collectAsState 를 사용하면 Composable이 살아있는 동안만 수집하게 된다. 따라서 백그라운드 상태에서도 불필요한 수집을 계속하게 된다.
collectAsStateWithLifeCycle는 안드로이드 생명주기와 자동으로 연결된다는 장점이 있지만 KMP에서는 사용하지 못한다.
SharedFlow
핫 플로우이다.
SharedFlow는 상태를 가지지 않으며, Stateless 방식으로 동작한다. 또한, 여러 수신자와 데이터를 공유하는데 적합하여 이벤트를 발송하는 방식으로 사용한다. SharedFlow가 이벤트 발생에 사용되는 이유는 다음과 같다.
- StateFlow는 마지막 상태를 계속 유지한다. 따라서 화면 회전 등으로 재구성될 때 이벤트가 다시 발생할 위험이 있다.
- SharedFlow 는 replay를 0으로 설정하면 emit 한 값은 바로 사라지고, 새로운 구독자에게 과거 이벤트를 전달하지 않는다. 따라서 이벤트를 한 번만 발생시킬 수 있다.
LiveData VS StateFlow, SharedFlow
동작 방식
LiveData는 안드로이드 컴포넌트의 생명주기를 인식하고, UI가 활성화되었을 때만 데이터를 업데이트한다. 이는 메모리 누수 방지와, 메모리 안전성을 높여준다는 장점이 있다.
Flow는 안드로이드의 생명주기와 독립적으로 작용한다. 즉, 생명주기를 관리하지 않는 다른 Coroutines에서도 사용할 수 있다. 또한, Coroutines을 활용하므로 비동기 작업에 유리하다.
한계
LiveData는 값의 변화에 대한 구독에 중점을 두기 때문에, 클릭이나 토스트 메시지 같은 단발성 이벤트를 처리하는데 어려움이 있다. 또한 메인스레드에서 동작하기 때문에 비동기 작업을 처리하기 까다롭다.
'코틀린' 카테고리의 다른 글
| Reflection (1) | 2025.10.03 |
|---|---|
| 디미터의 법칙 (0) | 2025.03.30 |
| 코틀린 문법(Sealed Interface) (0) | 2025.03.30 |
| 코틀린 문법(배열) (0) | 2024.08.19 |
| Kotlin에서 property, JAVA에서의 field와 property (0) | 2024.08.05 |