JEP's Diary

Kotlin Flow 본문

카테고리 없음

Kotlin Flow

지으니88 2022. 3. 8. 19:02

공식페이지1

공식페이지2, Codelab

 

Kotlin에서 Flow는 단일 값만 반환하는 suspend functions와 달리 여러 값을 순차적으로 내보낼 수 있는 타입이다. 

Flow는 비동기식으로 계산될 수 있는 데이터의 스트림 개념이다.

내보낸 값들은 동일한 유형이어야 한다. 예를 들어 Flow<Int>는 정수 값을 내보내는 Flow이다. 

Flow는 값 시퀀스를 생성하는 Iterator와 매우 유사하지만 suspend function를 사용하여 값을 비동기식으로 생성하고 사용한다. 

 

데이터 스트림에는 세 가지 항목이 있다.

생산자 : 스트림에 추가되는 데이터를 생산한다. 코루틴 덕분에 Flow에서 비동기적으로 데이터가 생산될 수도 있다.

중개자(선택사항) : 스트림에 내보내는 각각의 값이나 스트림 자체를 수정할 수 있다.

소비자 : 스트림의 값을 사용한다. 

StateFlow

  • 현재 상태와 새로운 상태 업데이트를 collector에게 내보내는 관찰 가능한 상태 홀더 Flow이다. 상태를 업데이트하고 흐름에 전송하려면 MutableStateFlow 클래스의 value 속성에 새 값을 할당한다. 
  • MutableStateFlow 업데이트를 담당하는 클래스가 생산자, StateFlow에서 수집(collecting)되는 모든 클래스가 소비자이다.
  • flow 빌더를 사용하여 빌드된 cold Flow와 달리, StateFlow는 hot Flow이다. Flow에서 수집해도 생산자 코드가 트리거 되지 않는다. 따라서 새로운 소비자가 Flow에서 수집을 시작하면 스트림의 마지막 상태와 후속 상태가 수신된다. 
  • Flow를 StateFlow로 변환하려면 stateIn 중간연산자를 사용한다.
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(news: List<ArticleHeadline>): LatestNewsUiState()
    data class Error(exception: Throwable): LatestNewsUiState()
}

StateFlow, Flow, LiveData

  • StateFlow와 LiveData는 비슷한점이 있다. 둘 다 관찰 가능한 데이터 홀더 클래스이며, 앱 아키텍쳐에서 사용될때 비슷한 패턴을 따른다.
  • StateFlow와 LiveData의 다른점
    • StateFlow의 경우 초기 상태를 생성자에 전달해야하지만 LiveData의 경우는 전달하지 않는다.
    • 뷰가 STOPPED 상태가 되면 LiveData.observe()는 소비자를 자동으로 등록 취소를 하지만, StateFlow 또는 다른 Flow에서 수집하는 경우 자동으로 수집을 중지하지않는다. LiveData와 동일한 동작을 하려면 Lifecycle.repeatOnLifecycle 블록에서 Flow를 수집해야한다.

 

참고

https://kotlinworld.com/175?category=973477