So, this is the problem :
My application calls a functionA
in a third party library which creates its own thread and calls back the caller in that thread. What I want to do is call that functionA
from a function in my app and wait until the callback has been called and then exit my function. I tried to use runBlocking
, withContext
etc., to no avail.
Below is a code snippet.
fun appFunction(context: Context) {
// call library function `functionA` which calls back the success and failure callbacks in a separate java thread.
runBlocking {
launch { functionA({ Timber.i("Call Success") }, { Timber.e(it) }) }
joinAll()
}
}
I want the app function to return only after the callback method finishes executing. I was thinking using a launch would make all threads created inside the java library would be part of the same coroutine scope and joinAll() would wait on that. Obviously, I was wrong.
Is this something that could be achieved? If so, how?
Any help is appreciated.
CodePudding user response:
Try this https://stackoverflow.com/a/67599110/19645104
Save result of launch
to job
variable and wait it
CodePudding user response:
Standard way of doing this with coroutines is by using either suspendCoroutine() or suspendCancellableCoroutine(). They both suspend execution waiting to be resumed (for example from a callback) and the difference is that the latter additionally supports cancelling while waiting. I suggest reading docs for the cancellable variant, as docs are much better there.
Example with suspendCoroutine()
:
suspendCoroutine<Unit> { continuation ->
functionA(
{ continuation.resume(Unit) },
{ continuation.resumeWithException(it) }
)
}
Note that to use above, your function has to be a suspend function. In your question appFunction()
is a regular function, so it can't suspend or wait for anything. Technically, you can use runBlocking()
, but if you plan to block threads then I think it doesn't make too much sense to use coroutines - you can just use callbacks.