Porting Retrofit2 sample to kotlin coroutines sample
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.