somoly.tistory.com
Published 2023. 10. 5. 15:03
Kotlin Coroutine 개념 Kotlin

Kotlin Coroutine 개념

 

예시

suspend fun fetchDocs() {                             // Dispatchers.Main
    val result = get("https://developer.android.com") // Dispatchers.IO for `get`
    show(result)                                      // Dispatchers.Main
}

suspend fun get(url: String) = withContext(Dispatchers.IO) { /* ... */ }

예시에서 get() 은 기본 스레드에서 실행되지만 네트워크 요청을 시작하기 전 Coroutine 을 정지(suspend)합니다. 네트워크 요청이 완료되면 get() 은 callback 을 사용하여 기본 스레드에 알리는 대신 정지(spspend)된 Coroutine 을 재개(resume) 합니다.

 

CoroutineScope

Coroutine 은 CoroutineScope 내에서만 실행 가능

CoroutineScope 는 Coroutine 이 실행될 수 있는 범위

launch, async 를 사용하여 Coroutine 을 추적, 진행 중인 작업은 scope.cancel() 을 호출하여 취소 가능

class ExampleClass {

    // Job and Dispatcher are combined into a CoroutineContext which
    // will be discussed shortly
    val scope = CoroutineScope(Job() + Dispatchers.IO)

    fun exampleMethod() {
        // Starts a new coroutine within the scope
        scope.launch {
            // New coroutine that can call suspend functions
            fetchDocs()
        }
    }

    fun cleanUp() {
        // Cancel the scope to cancel ongoing coroutines work
        scope.cancel()
    }
}

 

Job

class ExampleClass {
    ...
    fun exampleMethod() {
        // 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()
        }
    }
}

 

CoroutineContext

CoroutineContext 는 CoroutineScope 의 property 중 하나이며, CoroutineScope 와 생명주기를 함게 함

CoroutineScope 내에 있는 Coroutine(들)이 전역적으로 사용될 수 있도록 해주는 정보 저장소

Job: 코루틴의 수명 주기를 제어

CoroutineDispatcher: 적절한 스레드에 작업을 전달

CoroutineName: 디버깅에 유용한 Coroutine 이름

CoroutineExceptionHandler: 예외 처리 핸들러

 

 

class ExampleClass {
    val scope = CoroutineScope(Job() + Dispatchers.IO)

    fun exampleMethod() {
        // Starts a new coroutine on Dispatchers.Main as it's the scope's default
        val job1 = scope.launch {
            // New coroutine with CoroutineName = "coroutine" (default)
        }

        // Starts a new coroutine on Dispatchers.Default
        val job2 = scope.launch(Dispatchers.Default + CoroutineName("BackgroundCoroutine")) {
            // New coroutine with CoroutineName = "BackgroundCoroutine" (overridden)
        }
    }
}

 

Handling coroutine exceptions

class ExampleClass {
    val scope = CoroutineScope(Job() + Dispatchers.IO)

    @JvmStatic
    fun main() = runBlocking {
        scope.launch { // launch child coroutine in a scope
            try {
                 // do something
            } catch (e: Throwable) {
                 // handle exception
            }
        }
    }
}

 

Uncaught exceptions with no handler

object ExampleClass {
    val scope = CoroutineScope(Job() + Dispatchers.IO)

    @JvmStatic
    fun main() {
    	val handler = CoroutineExceptionHandler { _, exception -> 
    	    println("CoroutineExceptionHandler got $exception")
    	}
    
        scope.launch(handler) {
    	    println("The child throws an exception")
            throw AssertionError()
        }
        
        println("The scope is completed")
    }
}

'Kotlin' 카테고리의 다른 글

kotlin euc-kr to utf-8 conversion  (0) 2023.09.09
Apache POI sheet.autoSizeColumn() Speed Up  (0) 2023.08.08
kotlin logger  (0) 2023.06.26
Kotlin Collections overview  (0) 2023.03.26
profile

somoly.tistory.com

@RxCats

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!