🧵 Kotlin Coroutine
안드로이드 개발을 하다 보면, 네트워크 통신이나 파일 읽기 등 시간이 오래 걸리는 작업을 자주 다루게 됩니다. 이런 작업을 비동기적으로 처리하려면 Coroutine이 필수입니다.
✅ Coroutine이란?
Coroutine(코루틴)은 가벼운 스레드로, 하나의 스레드를 블로킹하지 않고 비동기 작업을 순차적 코드처럼 작성할 수 있게 해줍니다.
🌟 Coroutine의 장점과 Thread와의 차이점
| 항목 |
Coroutine |
Thread |
| 경량성 |
매우 가볍고 수천 개 생성 가능 |
생성 비용 높고 수백 개만 안정적 |
| 메모리 사용 |
적음 |
큼 |
| 컨텍스트 전환 비용 |
거의 없음 (suspend 기반) |
OS 수준의 전환으로 비용 큼 |
| 비동기 처리 |
자연스럽고 직관적인 문법 (suspend, launch, async) |
복잡한 콜백 구조 필요 |
| 생명주기 통합 |
viewModelScope, lifecycleScope 등과 통합 쉬움 |
별도 관리 필요 |
| 정지 및 재개 |
delay처럼 non-blocking 정지 가능 |
sleep은 스레드 자체 블로킹 |
코루틴은 스레드를 블로킹하지 않으면서도 순차적인 코드 작성이 가능해져 가독성과 효율성이 뛰어납니다.
- 메모리 효율적
- 코드 가독성 향상
- 스레드 전환 최소화
🚀 기본 사용법
1. CoroutineScope
1 2 3 4 5
| GlobalScope.launch { val result = fetchData() println(result) }
|
launch는 결과값이 없는 코루틴
async는 결과를 반환하는 코루틴
2. Delay vs Thread.sleep
1 2
| delay(1000L) Thread.sleep(1000L)
|
🧩 async / await
1 2
| val deferred = async { fetchData() } val result = deferred.await()
|
async로 비동기 실행, await로 결과 수신
🧠 CoroutineScope 관리
viewModelScope: ViewModel에서 사용
lifecycleScope: Activity/Fragment에서 사용
MainScope(): 일반 클래스에서 사용 가능
1 2 3 4
| viewModelScope.launch { val result = repository.loadData() _state.value = result }
|
⚠️ 예외 처리
1 2 3 4 5
| try { val result = fetchData() } catch (e: Exception) { Log.e("Error", e.message.toString()) }
|
또는 CoroutineExceptionHandler를 사용할 수 있음.
📌 정리
| 개념 |
설명 |
launch |
단순 비동기 실행 |
async/await |
결과 반환이 필요한 작업 |
delay |
일시 정지 (non-blocking) |
scope |
Coroutine 생명주기 관리 도구 |
Dispatchers.Main, IO, Default |
실행 환경 지정 |