
Flow를 UI에서 구독할 때 불필요한 리소스 낭비를 방지하는 것이 중요합니다.
SharingStarted.WhileSubscribed()를 사용하면 구독자가 있을 때만 데이터를 방출하고, 없으면 정지하는 방식으로 Flow를 최적화할 수 있다는 것을 알게 되었습니다.
이번 글에서는 SharingStarted.WhileSubscribed()가 무엇인지, 그리고 어떤 상황에서 유용한지 공부한 내용을 정리해두겠습니다.
1. SharingStarted란?
SharingStarted는 Flow를 여러 곳에서 공유할 때 흐름을 언제 시작하고, 언제 중지할지를 결정하는 전략입니다.
이를 활용하면 ViewModel에서 Flow 데이터를 공유하고, UI에서 구독할 때 불필요한 연산을 줄일 수 있습니다.
SharingStarted 옵션 비교
옵션 | 동작 방식 |
Eagerly | 앱이 실행되면 즉시 Flow를 시작하고 항상 유지합니다. |
Lazily | 구독이 생길 때만 시작하지만, 구독이 없어지면 정지됩니다. |
WhileSubscribed() | 구독이 있을 때만 데이터를 방출하고, 없으면 정지됩니다. |
이 중 WhileSubscribed()는 UI에서 구독자가 있을 때만 Flow를 유지하고, 구독자가 없어지면 정지하여 리소스를 절약하는 데 효과적입니다.
2. WhileSubscribed()의 기본 사용법
예를 들어, 1초마다 새로운 데이터를 방출하는 Flow를 UI에서 StateFlow로 변환하여 사용할 때, WhileSubscribed()를 적용할 수 있습니다.
ViewModel에서 Flow를 공유하는 코드
class MyViewModel : ViewModel() {
private val _dataFlow = flow {
while (true) {
emit("New Data: ${System.currentTimeMillis()}")
delay(1000) // 1초마다 데이터 방출
}
}
val sharedFlow = _dataFlow
.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5000), // 5초 동안 구독자가 없으면 정지
"Initial Data"
)
}
설명
- _dataFlow는 1초마다 새로운 데이터를 방출하는 Flow입니다.
- stateIn()을 사용하여 Flow를 StateFlow로 변환하여 UI에서 활용할 수 있습니다.
- SharingStarted.WhileSubscribed(5000)을 적용하면
→ 구독자가 없으면 5초 뒤 Flow가 정지됩니다.
→ 5초 이내에 구독자가 다시 생기면 흐름이 유지됩니다.
3. WhileSubscribed()가 동작하는 방식
구독자 변화에 따른 Flow의 상태
시점 | Flow 상태 |
ViewModel이 생성됨 | Flow가 아직 시작되지 않음 |
UI에서 sharedFlow 구독 시작 | 데이터 방출 시작 |
UI에서 구독 중단 (예: 화면 이동) | 5초 대기 후 Flow 정지 |
다시 구독 시작 | 데이터 방출 재개 |
구독이 있을 때만 데이터를 유지하고, 없으면 정지하여 불필요한 연산을 방지할 수 있습니다.
4. stopTimeoutMillis 옵션 활용하기
SharingStarted.WhileSubscribed(stopTimeoutMillis = 5000)
이 옵션의 역할
- 구독이 끊긴 후에도 일정 시간(5초) 동안 Flow를 유지합니다.
- 5초 이내에 다시 구독이 시작되면 Flow를 중단하지 않고 그대로 유지됩니다.
- 네트워크가 순간적으로 끊기거나, UI가 잠깐 변경되더라도 부드러운 데이터 유지가 가능합니다.
예제: stopTimeoutMillis 설정을 활용한 부드러운 전환
val sharedFlow = _dataFlow.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(3000), // 3초 후 정지
"Initial Data"
)
구독이 없어지더라도 3초 이내에 다시 구독이 시작되면 Flow를 유지합니다.
너무 짧은 값(예: 0ms)으로 설정하면 UI 이동 시 데이터 흐름이 끊길 수 있으므로 적절한 값 설정이 필요합니다.
결론
- WhileSubscribed()는 UI에서 Flow를 사용할 때 리소스를 절약하는데 유용한 전략입니다.
- 구독이 있을 때만 데이터를 방출하고, 구독이 끊기면 정지하여 불필요한 작업을 방지할 수 있습니다.
- stopTimeoutMillis 옵션을 사용하면 부드러운 상태 전환이 가능합니다.
반응형
'Android > Coroutine' 카테고리의 다른 글
[Android/Coroutine] Cold Stream vs Hot Stream 쉽게 이해하기: 언제 어떤 것을 써야 할까? (0) | 2025.03.28 |
---|---|
[Android/Coroutine] 구조화된 동시성이란? (0) | 2025.03.07 |
[Android/Coroutine] launch vs async 차이점 정리 (0) | 2025.02.19 |
코루틴과 스레드, 그리고 프로세스: 그 유사성과 차이 (0) | 2025.01.24 |
[Android/Kotlin] 코루틴: Kotlin에서 비동기 프로그래밍을 간소화하는 방법 (1) | 2024.05.29 |