TheGraduateGuy
TheGraduateGuy

Reputation: 1520

Coroutine suspend function and blocking calls

Below is my use case. I have a function fun requestFocus this function in turn call function fun configure which depends on a callback from system hence this function configure uses coundownlatch with count 1 and await until it is reset to zero when callback is received. For this I have marked requestFocus suspend and use Dispatchers.IO to do all its operation. Now there are multiple caller of requestFocus for ex function fun accept. The function accept does many things and all of them happens on same thread. function accept can also be called from main thread or intent service as well. My problem is since function configure is blocking I do not want to block main thread. Currently accept function looks like this

fun accept() {
    //do something
    requestFocus()
    // do something
}

I am not sure how I can call requestFocus from accept and have all the operation that happens post requestFocus execution to happen in same way. What I have done currently in accept function is below

fun accept() {
    //do something
    runBlocking{
    requestFocus()
    // do something
}

But this creates problem as main thread gets blocked. Any suggestion what can I try? I have looked into documentation of Global scope and main scope.

Upvotes: 1

Views: 2579

Answers (1)

Glenn Sandoval
Glenn Sandoval

Reputation: 3745

You're looking for withContext block. withContext behaves similar to runBlocking but it suspends the thread instead of blocking it.

suspend fun accept() {
    //do something on calling thread
    withContext(Dispatchers.IO){ // Changes to Dispatchers.IO and suspends the calling thread
        requestFocus() // Calls requestFocus() on Dispatchers.IO
        // do something on Dispatchers.IO
    }
    // Resumes calling thread
}

You need to call accept from a coroutine scope or from another suspending function. Or you can create a coroutine with launch to start a coroutine:

fun accept() = launch(Dispatchers.Main) { // Starts a coroutine on the main thread
    //do something on main thread
    withContext(Dispatchers.IO){ // Changes to Dispatchers.IO and suspends the main thread
        requestFocus() // Calls requestFocus() on Dispatchers.IO
        // do something on Dispatchers.IO
    }
    // Resumes main thread
}

Upvotes: 2

Related Questions