💡 StateFlow 와 SharedFlow 는 업데이트 상태를 최적으로 내보내주고, 여러 소비자에게 값을 내보내게 할 수 있도록하는 Flow APIs 이다.https://developer.android.com/kotlin/flow/stateflow-and-sharedflow?hl=en
StateFlow는 현재 및 새로운 상태 업데이트를 콜렉터에 내보내는 state-holder 관찰 가능한 flow 이다.
현재 상태 값은 value 속성을 통해 읽을 수 있습니다.
상태를 업데이트하고 flow로 보내려면 MutableStateFlow 클래스의 value 속성에 새 값을 할당합니다.
Android 에서 StateFlow는 관찰 가능한 변경 가능 상태를 유지해야하는 클래스에 매우 적합하다.
아래 예제에 따라, StateFlow는 LatestNewsViewModel에서 노출될 수 있으므로 View 는 UI 상태 업데이트를 수신할 수 있고, 본질적으로 화면 상태가 구성 변경 후에도 조성할 수 있다.
class LatestNewsViewModel(
private val newsRepository: NewsRepository
) : ViewModel() {
// Backing property to avoid state updates from other classes
private val _uiState = MutableStateFlow(LatestNewsUiState.Success(emptyList()))
// The UI collects from this StateFlow to get its state updates
val uiState: StateFlow<LatestNewsUiState> = _uiState
init {
viewModelScope.launch {
newsRepository.favoriteLatestNews
// Update View with the latest favorite news
// Writes to the value property of MutableStateFlow,
// adding a new element to the flow and updating all
// of its collectors
.collect { favoriteNews ->
_uiState.value = LatestNewsUiState.Success(favoriteNews)
}
}
}
}
// Represents different states for the LatestNews screen
sealed class LatestNewsUiState {
data class Success(val news: List<ArticleHeadline>): LatestNewsUiState()
data class Error(val exception: Throwable): LatestNewsUiState()
}
MutableStateFlow 업데이트를 담당하는 클래스는 생산자이고, StateFlow에서 수집하는 모든 클래스는 소비자입니다. flow builder를 사용하여 구축된 cold flow 와는 달리, StateFlow 는 hot flow 이다. 흐름에서 수집해도 생산자 코드가 트리거되지 않는다. StateFlow는 항상 활성 상태이고, 메모리에 있으며, 가비지 수집 루트에서 이에 대한 다른 참조가 없는 경우, 가비지 수집 대상이 된다.
새 소비자가 flow로부터 수집을 시작하면, 스트림의 마지막 상태와 모든 후속 상태를 받는다. LiveData 처럼 관찰 가능한 클래스로 이 동작을 찾아볼 수 있다.
[In View]
class LatestNewsActivity : AppCompatActivity() {
private val latestNewsViewModel = // getViewModel()
override fun onCreate(savedInstanceState: Bundle?) {
...
// Start a coroutine in the lifecycle scope
lifecycleScope.launch {
// repeatOnLifecycle launches the block in a new coroutine every time the
// lifecycle is in the STARTED state (or above) and cancels it when it's STOPPED.
repeatOnLifecycle(Lifecycle.State.STARTED) {
// Trigger the flow and start listening for values.
// Note that this happens when lifecycle is STARTED and stops
// collecting when the lifecycle is STOPPED
latestNewsViewModel.uiState.collect { uiState ->
// New value received
when (uiState) {
is LatestNewsUiState.Success -> showFavoriteNews(uiState.news)
is LatestNewsUiState.Error -> showError(uiState.exception)
}
}
}
}
}
}
androidx.lifecycle:lifecycle-runtime-ktx:2.4.0 library and higher.StateFlow 와 LiveData 는 유사점을 가지고 있다.
다른점
StateFlow 는 hot flow 이다. flow가 수집되는 한 다른 참조가 가비지 수집 루트에 존재하는 동안 메모리에 남아 있다. shareIn 연산자를 사용하여 cold flow 를 hot 으로 전환할 수 있다.
shareIn 함수는 수집하는 모든 소비자에게 값을 내보내는 hot flow 인 SharedFlow 를 반환한다.