안녕하세요.
코틀린에서 코루틴을 사용하는 방법에 대해 알아보겠습니다.
스케줄러의 코루틴 관리
스케줄러가 코루틴을 suspend & resume 해서 관리합니다.
suspend
현재 코루틴 실행을 일시 중지하고 모든 로컬 변수를 저장합니다.
resume
정지되었던 위치부터 정지된 코루틴을 재개합니다.
비동기 작업을 하고 싶으면 suspend 키워드를 함수 앞에 붙여주면 됩니다.
suspend fun doSomething() {
...
}
Dispatcher
Dispatcher는 코루틴이 실행되는 스레드 또는 스레드 풀을 관리하는 개념입니다.
Kotlin은 코루틴을 어떤 스레드에서 실행할지 정하는데에 사용할 수 있는 3가지 dispatcher를 제공합니다.
Dispatchers.Main
android 기본 스레드에서 코루틴을 실행할 때 사용합니다.
UI를 그리거나, 빠른 작업을 실행하기 위해서만 사용해야 합니다.
ex) suspend 함수 호출, LiveData 객체 업데이트
Dispatchers.IO
기본 스레드 외부에서 네트워크 I/O를 실행할 때 사용합니다.
ex) 파일에서 읽거나 쓰며 네트워크 작업을 할 때
Dispatchers.Default
기본 스레드 외부에서 CPU를 많이 사용하는 작업을 할 때 사용합니다.
ex) JSON 파싱
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
suspend fun printInMainThread() {
println("Printed in the main thread")
}
suspend fun printInBgThread() {
println("Printed in the background thread: ${Thread.currentThread().name}")
}
fun main() = runBlocking {
println("Start main coroutine")
// Main Dispatcher에서 실행되는 코루틴
launch(Dispatchers.Main) {
printInMainThread()
}
// IO Dispatcher에서 실행되는 코루틴
launch(Dispatchers.IO) {
printInBgThread()
delay(1000) // 1초 동안 일시 중단
printInBgThread()
}
// Default Dispatcher에서 실행되는 코루틴
launch(Dispatchers.Default) {
printInBgThread()
}
println("End main coroutine")
}
코루틴 실행
코루틴을 실행하는 방법으로는 2가지가 있습니다.
launch
호출자에게 결과를 반환하지 않습니다.
→ 반환값이 없는 일반적인 비동기 작업에 사용되며, 결과에 신경을 쓰지 않습니다.
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
doSomething1()
}
launch {
doSomething2()
}
}
suspend fun doSomething1() {
delay(1000L)
println("routine 1")
}
suspend fun doSomething2() {
delay(500L)
println("routine 2")
}
async
await 함수로 결과를 반환합니다.
→ 반환값이 있는 비동기 작업에 사용되며, 결과를 받아와 활용하는데 주로 사용합니다.
import kotlinx.coroutines.*
fun main() = runBlocking {
val task1 = async { doSomething1() }
val task2 = async { doSomething2() }
val result1 = task1.await()
val result2 = task2.await()
println("result : $result1 and $result2")
}
suspend fun doSomething1() : String {
delay(1000L)
return "routine 1"
}
suspend fun doSomething2() : String {
delay(500L)
return "routine 2"
}
코루틴 스코프
코루틴이 실행되는 범위를 나타내는 개념입니다.
여러 가지가 있지만, 안드로이드에서 자주 사용되는 것을 보겠습니다.
viewModelScope
ViewModel의 생명 주기에 맞춰 관리됩니다.
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class MyViewModel : ViewModel() {
fun performTask() {
viewModelScope.launch {
// viewModelScope 내에서 코루틴 실행
delay(1000)
println("Task completed")
}
}
}
lifecycleScope
액티비티 또는 프래그먼트의 생명 주기에 맞춰 관리됩니다.
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class MyFragment : Fragment() {
fun performTask() {
lifecycleScope.launch {
// lifecycleScope 내에서 코루틴 실행
delay(1000)
println("Task completed")
}
}
}
Job
launch 또는 async로 만드는 각 코루틴은 Job 인스턴스를 반환합니다.
- 각 코루틴을 고유하게 식별하기 위해
- 수명 주기를 직접 관리하기 위해
Job 객체로 할 수 있는 메서드 중 2가지만 보겠습니다.
Join
특정 코루틴이 완료될 때까지 다른 코드 블록이나 코루틴이 대기할 수 있습니다.
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
fun main() = runBlocking {
// launch로 생성한 코루틴
val job = launch {
repeat(3) {
delay(300)
println("Job is working... $it")
}
}
println("Main coroutine is doing something else")
// job이 완료될 때까지 대기
job.join()
println("Main coroutine is finished")
}
Main coroutine is doing something else
Job is working... 0
Job is working... 1
Job is working... 2
Main coroutine is finished
cancel
코루틴을 취소하는 함수입니다.
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
fun main() = runBlocking {
// Job을 사용하여 코루틴 실행
val job = launch {
repeat(5) {
println("Working... $it")
delay(500)
}
}
delay(1000)
// Job을 취소하여 코루틴 중단
job.cancel()
println("Main coroutine is finished")
}
Working... 0
Working... 1
Main coroutine is finished
Reference
Kotlin 코루틴으로 앱 성능 향상 | Android Developers
'Kotlin' 카테고리의 다른 글
[Kotlin] Sealed Class (3) | 2024.09.22 |
---|---|
[Kotlin] Extension Function (확장 함수) (0) | 2024.09.10 |
[Kotlin] Null Safety (0) | 2024.07.29 |
[Kotlin] Coroutine (3) - 예외 처리 (1) | 2023.12.01 |
[Kotlin] Coroutine (1) - 코루틴이란? (0) | 2023.11.30 |