Android 개발을 하다보면 "이 작업 메인 스레드에서 처리해도 되나?", "비동기 처리를 더 깔끔하게 할 수 없을까?"같은 고민이 생기기 마련입니다. 특히 네트워크 요청, 디스크 IO, 데이터 변환 같은 시간이 오래 걸리는 작업은 UI를 멈추게 만들 위험이 있기 때문에 비동기 처리가 필수적입니다.
과거에는 이런 문제를 해결하기 위해 콜백·RxJava 등을 사용했지만, Kotlin이 도입되면서 완전히 다른 방식이 등장했습니다. 바로 코루틴(Coroutines) 입니다.
이번 글에서는 코루틴이 무엇인지, 왜 필요한지, 기본 개념 및 예제, 그리고 Compose와 함께 사용할 때의 팁까지 정리해보겠습니다.
코루틴은 Kotlin에서 제공하는 비동기적으로 실행되는 코드를 간소화하기 위해 Android에서 사용할 수 있는 설계 패턴입니다. 쉽게 말하면 스레드를 직접 만들지 않고 비동기 작업을 작성할 수 있게 도와주는 일종의 경량 스레드입니다.
val scope = CoroutineScope(Dispatchers.Main)
suspend fun fetchData(): String {
delay(1000) // 네트워크 요청처럼 1초 지연된다고 가정
return "완료!"
}
scope.launch {
// 여기서부터 코루틴 실행
val result = fetchData()
println(result)
}
코루틴 안에서 시간이 오래 걸리는 작업은 suspend 함수로 분리합니다. suspend 함수는 중단이 가능한 함수로, 중단한다는 것은 스레드를 점유하지 않으면서 작업이 잠시 멈췄다가 이어서 실행될 수 있다는 의미입니다.
코루틴이 어떤 스레드에서 실행될지 결정하는 요소입니다.
코루틴 내에서 작업의 성격에 따라 디스패처를 전환해야할 때가 있습니다. 이 때, withContext를 사용합니다.
suspend fun loadUserData(): User {
// Main 디스패처에서 시작
val userId = getCurrentUserId()
// IO 작업을 위해 디스패처 전환
val user = withContext(Dispatchers.IO) {
database.getUserById(userId) // DB 조회
}
// 다시 Main으로 돌아옴
return user
}
withContext는 지정한 디스패처로 전환 후, 블록 내 작업이 끝나면 다시 원래 디스패처로 돌아옵니다. 단, 아래의 코드 예시와 같이 디스패처 전환을 자주하면 안됩니다.
// ❌ 나쁜 예: 불필요한 디스패처 전환 반복
suspend fun processItems(items: List<Item>) {
items.forEach { item ->
withContext(Dispatchers.IO) { // 매번 전환!
saveToDatabase(item)
}
}
}
// ✅ 좋은 예: 한 번만 전환
suspend fun processItems(items: List<Item>) {
withContext(Dispatchers.IO) { // 한 번만 전환
items.forEach { item ->
saveToDatabase(item)
}
}
}
따라서 작업의 단위가 클 때 디스패치를 전환하고, 반복문 안에서는 가급적 전환하지 않습니다.
코루틴이 다른 비동기 라이브러리와 다른 핵심 개념입니다.
coroutineScope {
launch { ... }
launch { ... }
}
부모 스코프가 살아 있는 동안, 자식 코루틴이 모두 끝날 때까지 함께 관리됩니다.
→ 예측 가능한 생명주기 관리 가능
Android에서는 주로 다음 스코프를 사용합니다
@Composable
fun MyScreen() {
val scope = rememberCoroutineScope()
Button(onClick = {
scope.launch {
delay(1000)
println("완료!")
}
}) {
Text("실행")
}
}
코루틴은 Kotlin에서 비동기 작업을 가장 깔끔하고 안정적으로 처리할 수 있는 핵심 도구입니다.
이전의 콜백 지옥, 복잡한 Rx 체이닝에 비해 훨씬 읽기 쉽고, 스레드 관리도 직접 하지 않아도 됩니다.
Compose와 함께 사용할 때도 최적의 방식이므로, 앱이 점점 비동기 연산을 많이 사용할수록 코루틴은 필수가 됩니다.