“Cannot access database on the main thread since it may potentially lock the UI for a long period of time.” error on my Coroutine

♀尐吖头ヾ 提交于 2020-01-15 14:25:34

问题


My Coroutine is running on the main thread, which i've specified in my Coroutine context:

class ClickPreference(context: Context, attrs: AttributeSet) : Preference(context, attrs), CoroutineScope, View.OnClickListener {

    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main

override fun onClick(v: View?) {
    when (key){
        "logout" -> {
            CoroutineScope(coroutineContext).launch {
                CustomApplication.database?.clearAllTables()
                Log.d("MapFragment", "Cleared Tables")
            }
            if (Profile.getCurrentProfile() != null) LoginManager.getInstance().logOut()
            FirebaseAuth.getInstance().signOut()
            val intent = Intent(context, MainActivity::class.java)
            context.startActivity(intent)
        }
    }
}

But I'm still getting this error:

java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.

on my above Coroutine call CustomApplication.database?.clearAllTables() to my Room database.

Here is my CustomApplication:

class CustomApplication : Application() {

    companion object {
        var database: AppDatabase? = null
    }

    override fun onCreate() {
        super.onCreate()
        CustomApplication.database = Room.databaseBuilder(this, AppDatabase::class.java, "AppDatabase").build()
    }

Why am I still getting the error if my coroutine context runs on the main thread?


回答1:


The error says that it should NOT run on the main thread. Database operations (and every other form of IO) can take a long time and should be run in the background.

You should use Dispatchers.IO which is designed for running IO operations.




回答2:


You can't use Dispatchers.Main for the long-running task. You have to use Dispatchers.IO for database operations, look likes:

class ClickPreference(context: Context, attrs: AttributeSet) : Preference(context, attrs), CoroutineScope, View.OnClickListener {



override val coroutineContext: CoroutineContext
        get() = Dispatchers.IO

override fun onClick(v: View?) {
    when (key){
        "logout" -> {
            CoroutineScope(coroutineContext).launch {
                CustomApplication.database?.clearAllTables()
                Log.d("MapFragment", "Cleared Tables")
                if (Profile.getCurrentProfile() != null) LoginManager.getInstance().logOut()
                FirebaseAuth.getInstance().signOut()
            }

            val intent = Intent(context, MainActivity::class.java)
            context.startActivity(intent)
        }
    }
}


来源:https://stackoverflow.com/questions/57657741/cannot-access-database-on-the-main-thread-since-it-may-potentially-lock-the-ui

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!