Android

[Android, Kotlin] Retrofit, Room과 같은 동작에서의 Coroutine 쓰레드 처리

코루틴을 사용한 비동기 처리를 구현한다.

이 때, 비동기를 사용하는 주된 이유 중 하나는 네트워킹, 데이터베이스의 Read/Write와 같은 무거운 작업의 처리를 위함인데, 네트워킹 동작의 대표적인 라이브러리인 Retrofit, 데이터베이스 동작의 대표적인 라이브러리인 Room을 코루틴 내에서 사용할 때, 당연하게 IO Dispatcher로의 Thread Switching 을 해야 한다고 인식하고 있었다.

그러나 Retrofit, Room을 통한 네트워킹 , db 동작을 수행 할 때, IO 스레드로 전환 할 필요 없이 main 스레드에서 수행하면 된다.

아래 글이 이해가 잘 가도록 정리가 잘 되어 있어 단박에 이해할 수 있었다.

참고 : https://www.lukaslechner.com/do-i-need-to-call-suspend-functions-of-retrofit-and-room-on-a-background-thread/

 

Do I need to call suspend functions of Retrofit and Room on a background thread? | Lukas Lechner

After publishing my open source project about Coroutines on Android, which currently includes 16 of the most common, real-world use cases of using Coroutines in an Android application, one of the most common questions I get from developers was whether or n

www.lukaslechner.com

 

위 글을 정리하자면,

NetworkOnMainThreadException과 같은 Exception의 발생을 피하기 위해서는 네트워킹과 같은 메인 스레드를 Blocking 시킬 위험이 있는 작업은 백그라운드 스레드로 스위칭 하는 것이 맞다.

그러나 Coroutine을 활용한 suspend function의 경우, 호출한 스레드를 suspend(정지) 시키는 것이지, block(차단)하는 것이 아니므로 suspend function이 수행되면 suspend 호출 스레드는 일시 정지되고, 해당 suspend function이 모두 수행된 후 resume(재개)된다.

이러한 코루틴의 매커니즘에 의해 굳이 retrofit, room을 사용할 때는 백그라운드 스레드에서 동작 할 필요 없이, suspend 한정자를 사용하여 main 스레드에서 동작하도록 하면 된다.

다만, 그렇다고 해서 모든 라이브러리의 네트워킹, db 동작을 메인 스레드에서 동작하도록 해도 된다는 것은 아니다. 코루틴이 항상 메인 스레드를 non-blocking하지는 않는다. retrofit, room은 main-safety가 보장된 라이브러리이므로 메인 스레드에서 동작해도 무방하나, 사용하는 라이브러리마다 main-safety가 보장되는 지에 대해 유의하여 필요에 따라 백그라운드 스레드로 스위칭이 필요하다.

- 코루틴은 호출자가 아닌, 라이브러리 자체에 스레드 스위칭의 필요성을 넘긴다라고 생각하는 것이 쉬울 것 같다.

- main-safety : 메인 스레드를 차단하지 않는 안전한 함수