If you are already in a worker/backgroud thread (e.g. WorkManager), use runBlocking
to execute coroutine/suspend function.
class ProcessImageWorker constructor(context : Context, params : WorkerParameters) : Worker(context, params) { @WorkerThread override fun doWork(): Result { return runBlocking { // execute suspend function, network call perhaps val data = service.await() // convert callback to coroutine val result = suspendCoroutine<Int> { continuation -> liveData.observeForever(object : Observer<String> { override fun onChanged(message: String?) { message?.let { liveData.removeObserver(this) continuation.resume(if (message == "ok") 1 else 0) } } }) } return if (result == 1) Result.success() else Result.failure() } }}
runBlocking Runs new coroutine and blocks current thread interruptibly until its completion. This function should not be used from coroutine. It is designed to bridge regular blocking code to libraries that are written in suspending style, to be used in main functions and in tests.