Retrofitのコルーチン関数にwithContext(Dispatchers.IO)は必要ない

Androidのネットワーク通信で頻出ライブラリであるRetrofitは、Version 2.6.0からコルーチンに対応しています。

そして、ネットワーク通信を行うコルーチンの実行はメインセーフティにすることが推奨されています。

では、Retrofitのコルーチン関数を呼ぶ際、メインセーフティにするために withContext(Dispatchers.IO) によってスレッドを切り替える必要があるのしょうか?

どこでスレッドの切り替えが起きているのか?

まず軽くググってみると、例えばこちらの記事には、Networking libraries such as Retrofit and Volley manage their own threads and do not require explicit main-safety in your code when used with Kotlin coroutines. とあります。よさそう。。。他にも、スレッド管理はRetrofitが独自管理しているという記事はいくつか見受けられました。

しかし、肝心のRetrofit公式ページGitHubではこの辺りの記述は見つけられません。 仕方がないのでコードを追うと、RetrofitがラップしているOkHttpの中でスレッド管理されていることがわかりました。

そこだけ抜き出してもわからないけど、具体的にはこの部分。 https://github.com/square/okhttp/blob/4677beea96f0afb1e061f119e52e0203d4cd3738/okhttp/src/main/kotlin/okhttp3/internal/connection/RealCall.kt#L160-L165)\

  override fun enqueue(responseCallback: Callback) {
    check(executed.compareAndSet(false, true)) { "Already Executed" }

    callStart()
    client.dispatcher.enqueue(AsyncCall(responseCallback))  ## ここでOkHttpが管理しているスレッドに処理が渡される
  }

結論

Retrofitのコルーチン関数を利用する際に、敢えて withContext(Dispatchers.IO) を書く必要は必要ありません。

また、コルーチン関数が完了した後にはメインスレッドへ処理が戻されるため安心してUIに触れます。楽ちんで助かりますね。

参考にした記事

developer.android.com

medium.com

stackoverflow.com