LoginSignup
10
8

More than 3 years have passed since last update.

Retrofit 2.6で通信を非同期処理

Posted at

Retrofit2.6でsuspend関数がサポート

Retrofit2.6でsuspendがサポートされ、HTTPリクエストをcoroutineを使って書くことができるようになりました!

New: Support suspend modifier on functions for Kotlin! This allows you to express the asynchrony of HTTP requests in an idiomatic fashion for the language.
retrofit - Change Log

Retrofit 2.6以前と比較してみたいと思います。
こちらにサンプルコードがあるので、参考にしていただければー!

Retrofit 2.6以前で通信を非同期処理

Retrofitの2.6以前で非同期処理を行う場合は、enqueueを使用します。
具体的にはCallを戻り値に設定して

interface EmployeeApi  {
    @GET("employees")
    fun getEmployeeWithCall(): Call<List<Employee>>
}

この戻り値を利用してenqueueを呼び出します。
enqueueにコールバック(コード例ではCustomCallBack)を渡して、成功時にはonResponse、失敗時にはonFailureが実行されます。

class EmployeeService {
    fun getAsyncEmployeeWithCall() {
        service.getEmployeeWithCall().enqueue(CustomCallBack())
        service.getEmployeeWithCall().enqueue(CustomCallBack())
    }

    private class CustomCallBack: Callback<List<Employee>>{
        override fun onResponse(call: Call<List<Employee>>, response: Response<List<Employee>>) {
             // TODO やりたい処理
            }
        }

        override fun onFailure(call: Call<List<Employee>>, t: Throwable) {
            // TODO エラーハンドリング
        }
    }
}

Retrofit2.6で通信を非同期処理

Retrofit2.6ではHTTPリクエストを送るメソッドをsuspendにすることができるようになります。
この際、戻り値はCallではなくResponseを指定します。

interface EmployeeApi  {
    @GET("employees")
    suspend fun getEmployeesWithResponse(): Response<List<Employee>>
}

呼び出し側は、coroutineの要領で記述できます。

class EmployeeService {
    fun getAsyncEmployeeWithSuspendFunc() {
        runBlocking {
            val job1 = async { service.getEmployeesWithResponse() }
            val job2 = async { service.getEmployeesWithResponse() }

            val res1: Response<List<Employee>>  = job1.await()
            val res2: Response<List<Employee>>  = job2.await()

            println(res1.body()?.forEach { println(it) })
            println(res2.body()?.forEach { println(it) })
        }
    }
}

直感的に非同期処理をかけるのでいいですね。
また、Responseで返されるので色々とレスポンスのメタデータがいじれて便利です。

// リクエストを取得したり・・・
res1.raw().request()
// レスポンスのヘッダーを確認したり・・・
res1.headers().toMultimap().forEach {
  println("${it.key}: ${it.value}")
}

まとめ

coroutine対応のおかげで、ぱっと見で何をしているかわかりやすくなった気がします。
ただ、coroutineび知識はまだまだなので、何かご指摘があればいただけると嬉しいです。

10
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
8