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 |