Lilly
05/29/2020, 2:55 PMhenrikhorbovyi
05/29/2020, 2:58 PMonFinish(result)
lambda inside some callback.henrikhorbovyi
05/29/2020, 2:59 PMonFinish()
when your task is success you must call it inside addOnSuccessListener
but if you want to call it when complete you can call it inside addOnCompleteListener
henrikhorbovyi
05/29/2020, 3:05 PMsuspendCoroutine()
to make the bridge between callbacks and coroutines.
Your code will look betterhenrikhorbovyi
05/29/2020, 3:06 PMCasey Brooks
05/29/2020, 3:13 PMsuspend
function, run each image job in an async
block and await()
the completion of all tasks.
To tie the callback-based image-processing API into the suspending coroutines world, use suspendCancellableCoroutine { }
Something like the following should get you started:
suspend fun startProcessing(taskList: List<String>, onFinish: (List<String>) -> Unit) {
val results: List<String> = taskList
.map { image ->
coroutineScope {
async {
suspendCancellableCoroutine<String> { continuation ->
processImage(image) // runs asynchronous
.addOnSuccessListener { text -> continuation.resume(text) }
.addOnFailureListener { e -> continuation.resumeWithException(e) }
}
}
}
}
.map {
it.await()
}
onFinish(results)
}
Lilly
05/29/2020, 3:46 PMjava.lang.ClassCastException: kotlinx.coroutines.CompletedWithCancellation cannot be cast to java.lang.String
thats points to it.await(). it
is Deferred<String>
Sorry, never used these classesLilly
05/29/2020, 3:49 PMhenrikhorbovyi
05/29/2020, 3:50 PMLilly
05/29/2020, 3:56 PMCasey Brooks
05/29/2020, 3:57 PMsuspendCancellableCoroutine<>
should be the type that is emitted on success. That same value is then unwrapped with it.await()
, so you’ll get a list of the type parameter of suspendCancellableCoroutine<>
Casey Brooks
05/29/2020, 3:58 PM.await()
in the first map { }
. You want to make sure to start all the jobs running in parallel, and then await them all after they’ve all started