KotlinのCoroutinesでRetrofitをより便利に!
まえがき
KotlinでAndrid開発は控えめにいって、 最高 です。
AndroidでAPIを叩く時には、OkHttp + Retrofit + RxJavaが定番になっていると思います。
Koltinの力を持ってすれば、RxJavaを使わず、Coroutinesを使うことで、幸せな開発が待っているかもしれません。
注意:Kotlin 1.1.xでは、Coroutinesは、experimental機能です。実験的な機能ですので、リリースされるまでは、プロダクトにいれないほうが無難です
RxJava版とCoroutines版の比較
もっとシンプルな具体例のほうがよかったけど、すいません。MVP構成での具体例になりました。。。
RxJava版
interface GithubApi { @GET("users/{user}") fun user(@Path("user") user: String): Single<User> }
class GithubRepositoryImpl(val api: GithubApi) : GithubRepository { override fun user(user: String) = api.user(user) }
class GithubPresenter(val view: GithubView, val repository: GithubRepository) { fun search(user: String) = repository.user(user) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ if (it == null) { view.notFoundUser() } else { view.showUser("${it.id}:${it.name}") } }, { view.showError(it) }) }
Coroutines版
RetrofitをCoroutinesに変換してくれるライブラリがあります。
gildor/kotlin-coroutines-retrofit: Kotlin Coroutines await() extension for Retrofit Call
とても薄いCallの拡張関数です。
同期的な書き方でとてもみやすい。
interface GithubApi { @GET("users/{user}") fun user(@Path("user") user: String): Call<User> }
class GithubRepositoryImpl(val api: GithubApi) : GithubRepository { override fun user(user: String) = async(CommonPool) { api.user(user).awaitResponse() // api.user(user).await() <- スタータスコードとか必要ないなら、これだけでも良い } }
class GithubPresenter(val view: GithubView, val repository: GithubRepository) { fun search(user: String) = launch(UI) { try { val response = repository.user(user).await() if (response.body() == null) { view.notFoundUser() return@launch } response.body()?.run { view.showUser("$id:$name") } } catch (e: Throwable) { view.showError(e) e.printStackTrace() } } }
まとめ
今回は1つAPIしか叩かなかったので、ぱっと見の違いがないのかもしれないですが、複数組み合わせてAPIを叩くときにはものすごい威力を発揮します。
備えよう! Coroutinesのリリースに!
サンプル:kamedon/KodeinSample