멀티쓰레딩을 처리하는데 사용할 수 있는 현재 프레임워크는 쓰레드로부터 안전한 실행을 보장할 수 있는 다른 간단한 방법이 없기 때문에 콜백 지옥 및 Blocking 상태로 이어진다. 코루틴은 성능 좋고 간단한 방식으로 동시성을 관리할 수 있다.
다음과 같이 멀티태스킹은 function A와 function B를 교차하면서 실행하면서 쓰레드를 최대한 활용할 수 있다. 코루틴과 쓰레드 모두 멀티태스킹을 지원하지만 코루틴은 사용자가 조작하여 기능을 실행할 수 있어 멀티태스킹을 매우 쉽게 만든다. 코루틴은 쓰레드를 관리하는 프레임워크에 가깝다.
코루틴은 두가지 유형이 있다.
- stackless
- stackful
코틀린은 stackless 코루틴에 해당하므로 네이티브 쓰레드에 매핑되지 않는다. 따라서 프로세서에서 컨텍스트 전환이 필요하지 않아 빠르고 가볍다.
1. 코루틴을 써야하는 이유
네트워크 콜을 메인 쓰레드에서 할 수 없다.
fun fetchUser(): User {
// make network call
// return user
}
fun showUser(user: User) {
// show user
}
fun fetchAndShowUser() {
val user = fetchUser()
showUser(user)
}
fetchAndShowUser()를 실행하면 NetworkOnMainThreadException이 발생한다.
이를 해결하기 위한 방법으로
1. Callback
fun fetchAndShowUser() {
fetchUser { user ->
showUser(user)
}
}
2. RxJava
fetchUser()
.subscribeOn(Schedulers.io())
.observerOn(AndroidSchedulers.mainThread())
.subscribe { user ->
showUser(user)
}
3. Coroutines
suspend fun fetchAndShowUser() {
val user = fetchUser() // fetch on IO thread
showUser(user) // back on UI thread
}
코루틴의 장점은 동기방식으로 비동기 코드를 작성할 수 있다는 것이다.
2. to need to know
- Dispatchers
- suspend
- launch VS async
- job VS deferred
- channel VS flow
- scope
- concurrency
dependency 추가
dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:x.x.x"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:x.x.x"
}
코루틴을 사용하면 코드는 아래와 같다.
suspend fun fetchUser(): User {
return GlobalScope.async(Dispatchers.IO) {
// make network call
// return user
}.await()
}
suspend fun fetchAndShowUser() {
val user = fetchUser() // fetch on IO thread
showUser(user) // back on UI thread
}
fun showUser(user: User) {
// show user
}
Dispatcher : 디스패처는 작업을 수행할 쓰레드를 결정하는데 코루틴을 돕는다.
- io (네트워크 및 디스크 관련 작업, CPU 집약적인 작업)
- default
- main (android ui thread)
suspend : suspend(일시중지)기능은 started, pause, resume을 할 수 있는 기능이다.
suspend 함수는 다른 suspend함수에서만 호출될수 있다. onCreate()는 suspend할 수 없기 때문에 아래와 같이 코루틴에서 호출해야한다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GlobalScope.launch(Dispatchers.Main) {
val user = fetchUser() // fetch on IO thread
showUser(user) // back on UI thread
}
}
showUser()는 Dispatchers.Main을 사용하여 실행하였기 때문에 UI 쓰레드에서 동작한다.
코틀린에서는 코루틴을 시작하는 두가지 함수가 있다.
launch : no return
async : 작업을 수행한 후 결과를 리턴
job : 코루틴의 실행을 표현하는 객체 중 하나로, 취소가 가능하고 완료되면 라이프 사이클도 끝난다.
deferred : 결과값을 가지고 있는 job이다. 초기화된 이후 미래에 완료 예정인 하나로 묶여진 명령이다.
'Application Programming > Android' 카테고리의 다른 글
[Android] Manifest merger failed (0) | 2021.08.25 |
---|---|
[Android] Jetpack Compose (0) | 2021.08.05 |
[Android/Kotlin] Kotlin extension (0) | 2021.07.08 |
[Android/Kotlin] Room을 사용하여 로컬 데이터베이스에 데이터 저장 (0) | 2021.07.08 |
[Android/Firebase] Firebase CRUD (0) | 2021.07.03 |