Home > database >  Kotlin structured concurrency : blocking a call when a java library runs in a separate thread
Kotlin structured concurrency : blocking a call when a java library runs in a separate thread

Time:07-29

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.

  • Related