2022.03.08 - [Android/AAC, MVVM] - [Android] 코루틴 StateFlow, SharedFlow 사용하기 (vs LiveData)
[Android] 코루틴 StateFlow, SharedFlow 사용하기 (vs LiveData)
2021.05.13 - [Android/AAC, MVVM] - [Android] Room + LiveData + ViewModel + DataBinding 사용하여 MVVM 패턴 사용하기 [Android] Room + LiveData + ViewModel + DataBinding 사용하여 MVVM 패턴 사용하기 202..
hanyeop.tistory.com
안드로이드에서 비동기처리를 위해 코루틴을 사용할 때,
LiveData 대신 Flow를 사용할 수 있다.
하지만 Flow는 스스로 라이프사이클을 알지 못하기 때문에
CoroutineScope 를 잘 이해하고 사용하여 불필요한 메모리 사용을 방지해야 한다.
1️⃣ viewModelScope.launch
class MainViewModel: ViewModel() {
private val _countFlow = MutableSharedFlow<Int>()
val countFlow get() = _countFlow.asSharedFlow()
fun startCounting(){
viewModelScope.launch(Dispatchers.IO) {
for(i in 1 .. 10){
_countFlow.emit(i)
Log.d(TAG, "startCounting: $i")
delay(1000L)
}
}
}
}
viewModelScope를 통해 ViewModel 의 라이프사이클에 맞게 코루틴을 시작, 취소할 수 있다.
ViewModel이 파괴되지 않는한 백그라운드에서도 진행된다.
2️⃣ lifecycleScope.launch
// 백그라운드에서도 계속 코루틴이 진행된다.
lifecycleScope.launch {
mainViewModel.countFlow.collectLatest {
Log.d(TAG, "Activity: $it")
}
}
이제 1번에서 확인한 뷰모델의 Flow를 Collect 해보자.
위처럼 코루틴 진행 중 백그라운드로 이동 (onStop) 하더라도
뷰모델의 작업이 진행되고, 액티비티에서 데이터 수집 또한 계속되고 있는 것을 확인할 수 있다.
둘 다 백그라운드에서도 계속해야 하는 작업이 아니라면 불필요한 메모리 사용이 발생한다.
3️⃣ lifecycleScope.launchWhenStarted
// 백그라운드로 나가면 코루틴 일시 정지, 돌아오면 다시 시작
lifecycleScope.launchWhenStarted {
mainViewModel.countFlow.collectLatest {
Log.d(TAG, "Activity: $it")
}
}
lifecycleScope.launchWhenStarted 를 사용하면
코루틴 진행 중 백그라운드로 이동했을 때 뷰모델 작업이 정지되는 것을 확인할 수 있고
다시 화면으로 돌아오게 되면 정지된 이후 부분부터 작업이 재개되는 것을 확인할 수 있다.
4️⃣ repeatOnLifecycle
// 백그라운드로 나가면 코루틴 수집 정지, 돌아오면 시작
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
mainViewModel.countFlow.collectLatest {
Log.d("TEST123", "Activity: $it")
}
}
}
repeatOnLifecycle 를 사용하면
코루틴 진행 중 백그라운드로 이동했을 때 뷰모델 작업은 계속 진행되며 (viewModelScope)
액티비티의 데이터 수집만 정지 되었다가 다시 화면으로 돌아왔을 때 재개되는 것을 확인할 수 있다.
class MainActivity : AppCompatActivity() {
private val flow: Flow<Int> = flow{
for(i in 0 .. 1000){
emit(i)
delay(1000L)
}
}
(..)
// 백그라운드로 나가면 코루틴 취소, 돌아오면 처음부터 시작
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
flow.collectLatest {
Log.d("TEST123", "Activity: $it")
}
}
}
}
만약 위처럼 액티비티에서 진행되는 작업에 repeatOnLifecycle 사용할 경우
백그라운드로 이동 시 작업이 정지되며, 다시 화면으로 돌아오면 처음부터 다시 시작되는 것을 확인할 수 있다.
공부하며 작성한 내용이라 틀린 부분이 있을 수 있습니다.
틀린 부분이 있다면 말씀해주세요!
전체 코드
https://github.com/HanYeop/AndroidStudio-Practice2/tree/master/FlowLifeCycleEx
GitHub - HanYeop/AndroidStudio-Practice2: (2021.05.20~) 안드로이드 학습 내용 저장소
(2021.05.20~) 안드로이드 학습 내용 저장소. Contribute to HanYeop/AndroidStudio-Practice2 development by creating an account on GitHub.
github.com