Porting Retrofit2 sample to kotlin coroutines sample

Raghunandan Kavi
2 min readApr 26, 2018

I recently started to learn koltin coroutines. I followed this excellent blog post on koltin coroutines by Dmytro Danlyk https://proandroiddev.com/android-coroutine-recipes-33467a4302e9 while starting with kotlin coroutines. The official wiki page is available on github https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md

I had a sample where i used RxJava instead of kotlin cotoutines and i recently came to know that retrofit supports coroutines and i tried to port the rxjava to the one that uses coroutines. All you need to add is

implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-experimental-adapter:1.0.0'

If you have already read the blog post in the above linked it would be easier for you to see the difference. The sample is written using MVP architecture pattern. The code snippets should be self explanatory.

With RxJava — API interface

@get:Headers("Content-Type: application/json")
@get:GET("bins/v6cg1")
val data: Single<Example>

With Coroutines — API interface

@get:Headers("Content-Type: application/json")
@get:GET("bins/ciahj")
val data: Deferred<Example>

Note the return type is Deferred

RxJava — Presenter Code

single = mainModel.loadData()
disposable.add(single!!.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeBy(// named arguments for lambda Subscribers
onSuccess = { example:Example ->mainView !!. showData (example.user) },
onError = { e: Throwable -> e.printStackTrace()}))

RxJava — The Model part

fun loadData(): Single<Example> {
val response = retrofit.create(Api::class.java).data.cache()
return response
}

With Coroutines — Presenter Code

launch(uiContext) {

val result = mainModel.getData()
if(result is Result.Success){
var example = result.data
mainView?.showData(example.user)
}else if( result is Result.Error) {
result.exception.printStackTrace()
}
}

launch the coroutines in uicontext. You wait for the result ( mainModel.getData() is a suspending function and you call await).

The coroutines contexts

 private val uiContext: CoroutineContext = UI // for ui
private val bgContext: CoroutineContext = CommonPool // for background from the common pool

With Coroutines — The model part

suspend fun loadData():Result<Example>{

try {
val response = retrofit.create(Api::class.java).data_corountine
val result = response.await()
return Result.Success(result)
} catch (e: HttpException) {
// Catch http errors
return Result.Error(e)
} catch (e: Throwable) {
return Result.Error(e)
}
}

Notice the await function and also the traditional try catch blocks.

The Result class

sealed class Result<out T : Any> {

class Success<out T : Any>(val data: T) : Result<T>()

class Error(val exception: Throwable) : Result<Nothing>()
}

Coroutines is in experimental although it is quite stable to use it production. With coroutines the code is easily readable and understandable while rxjava has quite as steep learning curve. Coroutines can also with RxJava2 sample of which is availabe https://github.com/Kotlin/kotlinx.coroutines/tree/master/reactive/kotlinx-coroutines-rx-example

There is lot to learn and there are excellent blog written by some very good developers. I just started with kotlin coroutines.

--

--