【问题标题】:"Cannot access database on the main thread since it may potentially lock the UI for a long period of time" error on lauching coroutine“无法访问主线程上的数据库,因为它可能会长时间锁定 UI”启动协程时出现错误
【发布时间】:2021-04-07 09:20:12
【问题描述】:

我收到此错误:无法访问主线程上的数据库,因为它可能会长时间锁定 UI。 当我在 ViewModel 中启动 fun turnAllWordsOn() 时会发生这种情况(代码如下)。这个函数启动协程,我认为协程总是在后台线程上工作。那么为什么我会收到这个错误? 感谢任何帮助

在片段中:

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.action_turn_all_words_on -> {
            viewModel.turnAllWordsOn()
            true
        }
    // othes items
    }

在 ViewModel 中:

fun turnAllWordsOn() = viewModelScope.launch {
    wordDao.turnAllWordsOn()
}

在道:

@Query("UPDATE word_table SET shown = 1")
fun turnAllWordsOn()

【问题讨论】:

    标签: android kotlin android-room kotlin-coroutines android-mvvm


    【解决方案1】:

    如果你想让 Room 在后台线程上运行它,你必须将你的 Dao 函数标记为挂起函数。否则,您所做的只是从协程范围内调用同步函数。

    @Query("UPDATE word_table SET shown = 1")
    suspend fun turnAllWordsOn()
    

    附带说明,挂起函数不会自动在后台线程上运行,但是当您将查询标记为挂起时,Room 会在后台执行必要的工作。

    【讨论】:

      【解决方案2】:

      即使你有答案,我还是想给出一些解决方案和问题的原因, 进行联网,或者访问数据库会阻塞Ui Thread,所以可以使用

      1. 使用 RxJava:

        Completable.fromAction { wordDao.turnAllWordsOn() }

      2. 使用协程:

        @Query("更新 word_table SET 显示 = 1") 暂停乐趣 turnAllWordsOn()

      【讨论】:

        猜你喜欢
        • 2019-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-01
        相关资源
        最近更新 更多