Deadlock with runBlocking(UI)


#1

Hi,

I try to manage my threads for IO Processes. One of is for Realm usage.

like…

init {
        val ai = app.packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA)
        bundle = ai.metaData
        runBlocking(appExecutors.dbContext) {
            Realm.init(app)
        }
    }

It works fine if I set val dbContext as newSingleThreadContext(“databaseIO”)…
But I develop an android-library, so If there is an implementation of Realm on the app module, I need to set usage on the same thread. And generally, everyone use main thread to use Realm. In that case I tried to set UI but it caused ANR. I can understand why it causes ANR, but I can’t find a proper solution for this scenario.

Note: if I use it with launch… it works for here. But on my RealmManager class I need to use runBlocking. So there is no way to use only launch…:slight_smile:
like…

fun getProfile(id: String): Profile? {
        try {
            return runBlocking(dbCoroutine) {
                val query = realm!!.where(Profile::class.java).equalTo("numbers.id", id)
                query.findFirst()
            }
        } catch (ex: Exception) {
            logger.e(TAG, ex)
            return null
        }
    } 

or

internal val allProfiles: List<Profile>
        get() = runBlocking(dbCoroutine) { realm!!.where(Profile::class.java).findAll() }

Is there anything I do wrong way, or any advice for better implementation?

Thanks & Regards


#2

The UI context will post a task to the handler of the UI thread. Handlers process messages in sequence. If you call getProfile from the UI thread this means that your function never returns because you are waiting for the task to complete but it never will because for it to be processed the function needs to return (and give control to the handler so it can process messages).