Both Retrofit and Room now support coroutines. But we know that both network requests and database operations are time consuming, so should we switch to the background thread every time we call Retrofit to initiate a network request or Room to call the database’s suspend function to avoid blocking the UI thread, causing the UI to freeze and ANR.

The answer is no, we don’t need to call Retrofit and Room suspend functions in background threads, and this article will explain why.

Every Android application apes may have experienced, thrown when writing network request NetworkOnMainThreadException caused by abnormal program crash; Perform time-consuming operations (such as database calls) on the main thread, resulting in interface delays and even ANR. As a result, a basic discipline was developed: you cannot perform time-consuming operations on the main thread.

In recent years, with the popularity of asynchronous libraries such as RxJava, the most common way to perform network requests or database operations is to use RxJava. However, you still need to explicitly specify the processing thread when performing operations that should not be performed on the main thread.

So we’re so used to caring about the thread when we’re doing IO operations that we think we have to care about it when we’re doing coroutines, but why not?

Because one of the conventions of the Kotlin coroutine (as defined in this blog post) is:

A suspended function does not block the caller thread.

So the maintainer of the suspend function, in our case the Retrofit or Room library, must make sure it doesn’t block the thread that calls it. Whenever a library performs a blocking operation, there must be some internal mechanism to switch to a background thread.

Note though: This is just a convention and there is no guarantee that the resume function wouldn’t actually block the calling thread. A common misconception about coroutines is that you can make them automatically non-blocking simply by defining a suspend function. This is an error; simply perform a thread.sleep () or a time-consuming calculation in the suspend function and you will see that it still blocks the caller Thread.

Fortunately, Retrofit and Room fit this convention. Therefore, it is safe for us to call their suspend function on the main thread because the main thread is not blocked by a suspended function while the IO operation is performed. This concept is sometimes referred to as “main-safe.” However, if you use other libraries, you must verify that they conform to this convention.