Groo

lifecycleScope와 viewModelScope의 한계 본문

프로그래밍 언어/Kotlin

lifecycleScope와 viewModelScope의 한계

김주엽 2022. 4. 18. 23:20

아래 내용은 모두 해당 원글을 기반으로 요약정리한 내용입니다.

그림은 저자가 직접 제작한 것임을 알려드립니다. (출처: Kt World)


CoroutineScope는 Coroutine Job이 실행되는 Scope이다.

CoroutineScope가 해제되면 해당 Scope에 속한 Job들은 모두 취소된다.

안드로이드의 생명주기에 따라 CoroutineScope를 관리하지 않는다면 Job들이 계속해 동작하여 메모리 누수를 일으킨다.

val shoutFlow = flow {
    for (i in 1..100) {
        emit("${i}번째 관객 소리질러~~~")
        delay(1000)
    }
}

fun collectShoutFlow() {
    // Application의 생명주기를 따른다
    GlobalScope.launch {
        shoutFlow.collect {
            println(it)
        }
    }
}

// 1번째 관객 소리질러~~~
// 2번째 관객 소리질러~~~
// 3번째 관객 소리질러~~~
// onStop 발생
// 4번째 관객 소리질러~~~
// 5번째 관객 소리질러~~~
// 6번째 관객 소리질러~~~
// onStart 발생
// 7번째 관객 소리질러~~~
// 8번째 관객 소리질러~~~
// onDestroy 발생
// Coroutine Job 취소됨

Activity에서는 lifecycle의 coroutineScope를 활용할 수 있다.

class MainActivity : AppCompatActivity() {

    private val shoutFlow = flow {
        for (i in 1..100) {
            emit("${i}번째 관객 소리질러~~~")
            delay(1000)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Activity의 생명주기를 따른다
        // lifecycleScope로 작성해도 무관한다
        lifecycle.coroutineScope.launch {
            shoutFlow.collect {
                println(it)
            }
        }
    }
}

// 1번째 관객 소리질러~~~
// 2번째 관객 소리질러~~~
// 3번째 관객 소리질러~~~
// onStop 발생
// 4번째 관객 소리질러~~~
// 5번째 관객 소리질러~~~
// 6번째 관객 소리질러~~~
// onStart 발생
// 7번째 관객 소리질러~~~
// 8번째 관객 소리질러~~~
// onDestroy 발생
// Coroutine Job 취소됨

viewModel에서는 viewModelScope를 활용할 수 있다.

viewModelScope는 바인딩 된 View가 onDestroy 될 시점에 ViewModel의 onCleared가 먼저 불리면서 Job들이 취소된다.

class MainViewModel : ViewModel() {

    private val shoutFlow = flow {
        for (i in 1..100) {
            emit("${i}번째 관객 소리질러~~~")
            delay(1000)
        }
    }

    init {
        viewModelScope.launch {
            shoutFlow.collect {
                println(it)
            }
        }
    }
}

// 1번째 관객 소리질러~~~
// 2번째 관객 소리질러~~~
// 3번째 관객 소리질러~~~
// onStop 발생
// 4번째 관객 소리질러~~~
// 5번째 관객 소리질러~~~
// 6번째 관객 소리질러~~~
// onStart 발생
// 7번째 관객 소리질러~~~
// 8번째 관객 소리질러~~~
// onCleared 발생
// Coroutine Job 취소됨
// onDestroy 발생

lifecycleScope는 onDestroy 시점에 viewModelScope는 onCleared 시점에 Coroutine Job이 취소된다.

그러나 앱이 백그라운드로 이동하거나 또는 완전히 종료되지 않은 시점인 onStop에서는 Job이 계속해 동작한다는 한계가 있다.


lifecycleScope와 viewModelScope의 생명주기에 대해서 알아봤다.

평소에 잘 알지도 못하면서 그냥 막 사용했다는 것에 반성한다.

오늘 하루도 수고했다 😔

Comments