[Kotlin] Coroutine으로 비동기 작업 마스터 하기

이영한·2021년 9월 11일
3

kotlin

목록 보기
1/1
post-thumbnail

1. Coroutine을 왜 써야 하나?

앱 개발을 하다보면 데이터 입출력, 네트워크 작업과 같은 비동기 작업이 필수적으로 필요합니다. 비동기 작업을 다루는 여러 방법이 있는데 그중 가장 효율적인 방법은 코루틴입니다. 코루틴이 비동기 작업에 좋은 이유는 아래와 같습니다

  1. suspend modifier 지원 : suspend modifier를 통해 특정 함수가 코루틴 내에서만 사용되도록 강제할 수 있습니다

  2. thread 관리 편리 : 코루틴이 실행될 스레드를 지정 가능합니다

  3. 취소 기능 : 코루틴을 Job으로 받아서 언제든 취소가 가능합니다.

  4. scope 제공 : 코루틴을 특정 컴포넌트의 라이프 사이클 내에서만 작동되도록 scope 설정이 가능합니다.

2. Coroutine Scope, Coroutine Context

  • Coroutine Scope
    코루틴이 실행되는 범위입니다. CoroutineScope중 viewModelScope이 있는데, viewModelScope에서 코루틴을 실행하면 viewModel 라이프 사이클 안에서만 코루틴이 작동합니다.

  • Coroutine Context
    코루틴과 관련된 Element의 집합입니다. 코루틴의 이름, 코루틴의 디스패쳐, 코루틴 Job 등이 모두 포함됩니다.

3. Coroutine 사용 방법

1) launch

launch는 코루틴을 만드는 코루틴 빌더로 새로운 코루틴을 병렬적으로 실행시킵니다. viewModelScope에서 launch하는 경우로 예를 들어 봅시다.

 viewModelScope.launch(Dispatcher.Dispatchers.IO) {
         getNote()  //Asynchronous Task
 }
 
 fun getNote() : Note {
      	return noteDAO.getNote()
}

코드는 viewModelScope에서 IO Dispatcher를 이용하여 코루틴을 실행한다는 의미입니다. 앞서 CoroutineScope에서 설명드린 대로 코루틴은 viewModel의 lifeCycle내에서만 동작합니다.

2) withContext
withContext를 사용하면 코루틴이 실행될 dispatcher를 미리 지정할 수 있습니다. 보통 suspend function 내에서 사용되는데, 아래와 같이 사용됩니다.

 viewModelScope.launch() {
         getNote() 
         anotherFun()
 }
 
 suspend fun getNote() : Note {
        return withContext(Dispatchers.IO){
            noteDAO.getNote()
        }
    }

여기서 suspend modifier는 해당 함수가 코루틴 내에서 작동해야 함을 나타내며, 코루틴 내에서 사용하지 않으면 에러 발생시킵니다.

viewModelScope.launch에서 따로 디스패처를 지정하지 않은 것도 withContext를 사용했을 때의 차이입니다. 이 경우에는 코루틴 기본 디스패처에서 코루틴이 진행되다가 withContext부분의 코드는 IO thread에서 처리됩니다.

코루틴은 withContext가 완료될 때까지 정지하게 됩니다. 즉, getNote가 완료될때까지 anotherFun()은 불리지 않게 됩니다.

4. Job

Job은 코루틴을 제어하는 헨들러입니다. launch함수를 통해서 코루틴을 만들게 되면 Job변수로 코루틴 인스턴스를 받을 수 있습니다. 아래 예시는 안드로이드 개발자 문서에 나타나 있는 Job 예시 입니다.

	// Handle to the coroutine, you can control its lifecycle
       val job = scope.launch {
           // New coroutine
       }

       if (...) {
           // Cancel the coroutine started above, this doesn't affect the scope
           // this coroutine was launched in
           job.cancel()
       }

scope.launch{} 에서 코루틴이 실행되며 해당 코루틴을 제어하는 Job이 반환됩니다. 이를 cancel(), join(), start()등의 함수를 통해 제어할 수 있습니다.



[참고자료]
https://kt.academy/article/cc-coroutine-context
https://developer.android.com/kotlin/coroutines?hl=ko
https://medium.com/androiddevelopers/easy-coroutines-in-android-viewmodelscope-25bffb605471

profile
간단하게 개발하고 싶습니다

0개의 댓글