I have an Android service which starts and syncs different types of data with the server when it's online. I'm new to Kotlin coroutines and I'm trying to accomplish the following:
fun syncData{
//Job1 make retrofit call to server
//Job2 make retrofit call to server after job1 is done.
//Job3 make retrofit call to server after job2 is done and so on.
//After all jobs are done I'll stop service.
}
I'm following this post: Kotlin Coroutines the right way in Android
Which brought me to this solution:
fun syncData() = async(CommonPool){
try{
val sync1 = async(CommonPool){
job1.sync()
}
val sync2 = async(CommonPool){
job2.sync()
}
val sync3 = async(CommonPool){
job3.sync()
}
val sync4 = async(CommonPool){
job4.sync()
}
job1.await()
job2.await()
job3.await()
job4.await()
}catch (e: Exception){
}finally {
stopSelf()
}
}
But when I get retrofit's log on logcat, every call is mixed. Calls from job3 comes before job1, and so on. How can I execute them in a pipeline? I'm kinda lost in Kotlin's coroutines so I don't know how exactly to implement this.
You can create your own CoroutineScope with a SupervisorJob that you can cancel in the onDestroy() method. The coroutines created with this scope will live as long as your Service is being used. Once onDestroy() of your service is called, all coroutines started with this scope will be cancelled.
Kotlin Coroutines Example For fetching the data from the database we have to perform the network call, fetch the user from the database, and show it on the screen. Fetching the user can be done by using either by using callbacks or coroutines. Using Callbacks: Kotlin.
A coroutine is a concurrency design pattern that you can use on Android to simplify code that executes asynchronously. Coroutines were added to Kotlin in version 1.3 and are based on established concepts from other languages.
A ViewModelScope is defined for each ViewModel in your app. Any coroutine launched in this scope is automatically canceled if the ViewModel is cleared. Coroutines are useful here for when you have work that needs to be done only if the ViewModel is active.
Agree with @s1m0nw1 and his answer
It's a way too hard to approach. All you need is as easy as this:
val job = SupervisorJob()
fun syncData() = launch(job) {
try {
val result1 = makeRetrofitCall1()
val result2 = makeRetrofitCall2(result1)
...
val resultN = makeRetrofitCallN(resultNMinusOne)
} catch(e: Exception) {
// handle exception
} finally {
stopSelf()
}
}
override fun onDestroy() {
super.onDestroy()
job.cancel()
}
Here makeRetrofitCall
means a direct API call as retrofitClient.getData()
where retrofitClient
is
interface RetrofitClient {
@GET("endpoint")
suspend fun getData(): MyCustomResult
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With