plastiv
11/07/2018, 3:32 PMopen class RetrofitCallManager( // Open because its mocked at some unit tests.
val uiDispatcher: CoroutineDispatcher = Dispatchers.Main, // To be able to switch to Unconfined at jvm tests.
val ioDispatcher: CoroutineDispatcher = <http://Dispatchers.IO|Dispatchers.IO>
) : CoroutineScope {
private lateinit var parentJob: Job
override val coroutineContext: CoroutineContext
get() = parentJob + uiDispatcher
fun onCreate() {
parentJob = SupervisorJob() // Job is supervised so one failed child coroutine wouldn't cancel other running coroutines.
}
open fun <T> execute(request: NetworkRequest<Result<T>>, listener: ResultListener<T>) = launch { // Launch returns Job which could be joined inside test runBlocking.
try {
val result = withContext(ioDispatcher) {
request.loadDataFromNetwork() // Blocking retrofit network call.
}
if (result.isSuccess) {
listener.onResult(result.data()!!) // Update ui.
} else {
listener.onError(result.error()!!) // Update ui.
}
} catch (e: CancellationException) {
throw e // No need to propagate to UI since execution was cancelled by UI.
} catch (e: Exception) {
listener.onError(LocalError.create(ERR_CODE, e)) // Update ui.
}
}
fun onDestroy() {
parentJob.cancel()
}
}
Is this something you would expect to see in android app?gildor
11/08/2018, 1:34 AMawait()
extension fro your NetworkRequest> request.loadDataFromNetwork() // Blocking retrofit network call.This is really bad idea
launch {
try {
val result = request.await()
} catch (…) {
// handle error
}
}
plastiv
11/08/2018, 9:31 AMcall.enqueue(Callback
through coroutines-retrofit adapter from Jake?gildor
11/08/2018, 9:36 AMplastiv
11/08/2018, 10:01 AMEven not sure that you need this class in general
I don’t know details of your architecture of course, but I think it doesn’t help with migration and instead make sense to implement coroutine scope on your UI component where you already have onCreate/onDestroy or LifecycleProvider, so no need to write all this boilerplateActually I was wondering about this. I'm just starting with coroutines but if I learned anything in 8 years of doing android development its is that putting everything into activities is really bad idea. Leave ui for the ui and extract everything else. Why UI component should control/know what execution mechanism app is using? Is it really considered to be a best practice?
gildor
11/08/2018, 10:02 AMplastiv
11/08/2018, 10:09 AMgildor
11/08/2018, 10:18 AM(yes it’s not fully performant of course, like cancellation is not propagated to okhttpBut you can easily fix this