-
안드로이드 코루틴 (Coroutine Builder) 코드안드로이드 학습/Android 기술면접 대비 2024. 11. 18. 13:16
Coroutine Builder에는 주로 4가지가 있다.
1. launch
- 사용 목적: 결과를 반환하지 않고 코루틴을 실행.
- 특징:
- 반환값이 없는 Job 객체를 반환함.
- 주로 fire-and-forget 작업(결과보다는 실행 자체가 중요한 작업)에 적합.
- 예외가 발생해도 기본적으로 상위 코루틴에 전달됨.
private fun coroutineLaunch() { val sb = StringBuilder() runBlocking { setStringWithStringBuilder(sb, "1. Thread Name : ${Thread.currentThread().name}", resultTextView) val result = launch { setStringWithStringBuilder(sb, "2. Thread Name : ${Thread.currentThread().name}", resultTextView) delay(1000L) // 지연 후 다시 이 코루틴을 재개 setStringWithStringBuilder(sb, "3. Thread Name : ${Thread.currentThread().name}", resultTextView) } setStringWithStringBuilder(sb, "4. Thread Name : ${Thread.currentThread().name}", resultTextView) result.join() setStringWithStringBuilder(sb, "5. Thread Name : ${Thread.currentThread().name}", resultTextView) } setStringWithStringBuilder(sb, "6. Thread Name : ${Thread.currentThread().name}", resultTextView) }
join()이나 run() 메소드를 이용해서 결과값을 먼저 나오게도 가능하다.
1 > 4 > 2 > 3 > 5 > 6 순서로 실행된다.
2. async
- 사용 목적: 결과를 반환하는 코루틴을 실행.
- 특징:
- Deferred 객체를 반환하며, await()를 호출해 결과를 얻을 수 있음.
- 주로 비동기적인 연산 작업에서 사용.
- 결과를 기다리기 위해 명시적으로 await()를 호출해야 함.
private fun coroutineAsync() { val myCharacter = CoroutineCharacter(null, null, null) val sb = StringBuilder() runBlocking { myCharacter.name = "John" setStringWithStringBuilder(sb, "1. myCharacter : $myCharacter", resultTextView) Log.d("coroutineAsync", "1. $myCharacter") val result = async { delay(1000L) myCharacter.weapon = "sword" setStringWithStringBuilder(sb, "2. myCharacter : $myCharacter", resultTextView) Log.d("coroutineAsync", "2. $myCharacter") } myCharacter.age = 11 setStringWithStringBuilder(sb, "3. myCharacter : $myCharacter", resultTextView) Log.d("coroutineAsync", "3. $myCharacter") result.await() setStringWithStringBuilder(sb, "4. myCharacter : $myCharacter", resultTextView) Log.d("coroutineAsync", "4. $myCharacter") } }
결과 :
1. CoroutineCharacter(name=John, age=null, weapon=null)
3. CoroutineCharacter(name=John, age=11, weapon=null)
2. CoroutineCharacter(name=John, age=11, weapon=sword)
4. CoroutineCharacter(name=John, age=11, weapon=sword)1,3번 먼저 실행한 후 중간에 await이 있기 때문에 async 내부 코드 실행 후 나머지 코드가 실행된다.
3. runBlocking
코루틴을 지원하지 않는 코드(예: 일반 함수)에서 코루틴 블록을 동기적으로 실행하기 위해 사용.
- 새로운 코루틴을 시작하고, 그 코루틴이 완료될 때까지 현재 스레드를 블록(block) 함.
- 주로 테스트나 진입점(main 함수)에서 사용.
- 실행 중인 스레드를 잠시 멈추기 때문에 메인 스레드에서 과도하게 사용하면 성능 문제가 발생할 수 있음.
5초이상 작업이 발생할 경우 시스템에 의해 ANR이 발생할 수 있다.
private fun coroutineRunBlocking() { val myCharacter = CoroutineCharacter(null, null, null) val sb = StringBuilder() myCharacter.name = "John" setStringWithStringBuilder(sb, "1.myCharacter : $myCharacter", resultTextView) Log.d("coroutineRunBlocking", "1. $myCharacter") runBlocking { delay(1000L) myCharacter.weapon = "sword" setStringWithStringBuilder(sb, "2. myCharacter : $myCharacter", resultTextView) Log.d("coroutineRunBlocking", "2. $myCharacter") } myCharacter.age = 11 setStringWithStringBuilder(sb, "3. myCharacter : $myCharacter", resultTextView) Log.d("coroutineRunBlocking", "3. $myCharacter") }
결과
1. CoroutineCharacter(name=John, age=null, weapon=null)
2. CoroutineCharacter(name=John, age=null, weapon=sword)
3. CoroutineCharacter(name=John, age=11, weapon=sword)runBlocking 같은 경후 현재 Thread도 멈추고 실행 되기 때문데 1,2,3번의 순서대로 실행된다.
4. withContext
- 사용 목적: 코루틴 내부에서 특정 디스패처(예: Dispatchers.IO, Dispatchers.Main)로 컨텍스트를 전환하기 위해 사용.
- 특징:
- 코루틴 내부에서만 사용 가능.
- 호출되는 동안 비동기적으로 실행되며, 현재 코루틴의 진행을 일시 중단(suspend)함.
- 컨텍스트를 전환하고 작업이 완료될 때까지 기다린 후 원래 컨텍스트로 돌아감.
- async와 차이점은 async는 결과 값을 얻으로면 await()를 호출해야 하지만 withContext는 처음부터 결과 리턴까지 대기하는 형태
private fun coroutineWithContext() { val myCharacter = CoroutineCharacter(null, null, null) val sb = StringBuilder() runBlocking { myCharacter.name = "John" setStringWithStringBuilder(sb, "myCharacter : $myCharacter", resultTextView) Log.d("coroutineWithContext", "1. $myCharacter") withContext(Dispatchers.IO) { delay(1000L) myCharacter.weapon = "sword" setStringWithStringBuilder(sb, "myCharacter : $myCharacter", resultTextView) Log.d("coroutineWithContext", "2. $myCharacter") } myCharacter.age = 11 setStringWithStringBuilder(sb, "myCharacter : $myCharacter", resultTextView) Log.d("coroutineWithContext","3. $myCharacter") } }
결과 :
1. CoroutineCharacter(name=John, age=null, weapon=null)
2. CoroutineCharacter(name=John, age=null, weapon=sword)
3. CoroutineCharacter(name=John, age=11, weapon=sword)'안드로이드 학습 > Android 기술면접 대비' 카테고리의 다른 글
안드로이드 Coroutine Flow - 2 (Flow 사용) (0) 2024.11.28 안드로이드 Coroutine Flow - 1 (Flow란?) (0) 2024.11.27 (DI - 1편) 의존성 주입이란 (0) 2024.11.16 (DI - 3편) DI 라이브러리 Hilt Annotations (0) 2024.11.16 (DI - 2편) 안드로이드 의존성 수동 주입 (0) 2024.11.16