안드로이드에서 Flow를 수집하는 것을 조금 편하게

8045 단어 안드로이드Kotlin
Android에서 Flow<T>를 다룰 때의 작은 재료입니다.

전치



Android + Kotlin에서 StateFlow<T>, SharedFlow<T> 등을 LiveData<T> 대신 사용할 때,
주로 Activity/Fragment 위에서 lifecycleScope.launchWhenStarted {} 등을 사용해 collect {}를 실행하는 경우가 많다고 생각합니다.
그 때, LiveData<T>에 비해 코루틴 스코프를 개시하는 관계상 중첩이 한층 깊어져 버립니다.

활동
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    lifecycleScope.launchWhenStarted {
        viewModel.flow.collect {
            binding.textView.text = it
        }
    }
}

여러 개collect가 늘어서면LiveData<T>에 비해 미묘하게 가독성이 떨어지므로 중첩이 깊어지지 않도록 쉽게 대책해 봅니다.

Flow<T> 의 확장 함수를 만들어 대처하기



아래와 같은 확장 함수를 준비해, launch 함수로 중첩시키지 않아도 collect 할 수 있도록 해 봅니다.

FlowCollector.kt
inline fun <T> Flow<T>.collectWhenCreated(lifecycleOwner: LifecycleOwner, crossinline action: suspend (value: T) -> Unit): Job {
    return lifecycleOwner.lifecycleScope.launchWhenCreated {
        collect(action)
    }
}

inline fun <T> Flow<T>.collectWhenStarted(lifecycleOwner: LifecycleOwner, crossinline action: suspend (value: T) -> Unit): Job {
    return lifecycleOwner.lifecycleScope.launchWhenStarted {
        collect(action)
    }
}

inline fun <T> Flow<T>.collectWhenResumed(lifecycleOwner: LifecycleOwner, crossinline action: suspend (value: T) -> Unit): Job {
    return lifecycleOwner.lifecycleScope.launchWhenResumed {
        collect(action)
    }
}

launchWhenStarted + collect 바꾸기



이전의 확장 함수를 사용하면 아래와 같이 나타낼 수 있습니다.
한층 더 중첩이 줄어 들었습니다!

활동
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    viewModel.flow.collectWhenStarted(this) {
        binding.textView.text = it
    }
}

조각
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    viewModel.flow.collectWhenStarted(viewLifecycleOwner) {
        binding.textView.text = it
    }
}

일반적인 Flow<T> 처리와 마찬가지로 Fragment에서 View를 업데이트하는 경우 인수에 this 대신 viewLifecycleOwner를 지정해야합니다.
단지 이것뿐입니다만 수수하게 편리하므로 시험해 주세요

좋은 웹페이지 즐겨찾기