首页 > 解决方案 > 使用 Kotlin Coroutines 和 Realm 执行数据库写入会导致 UI 冻结

问题描述

我正在尝试使用 Kotlin Coroutines 将数据异步写入 Realm 数据库,代码如下:

suspend fun write(realmObject): Unit = with(realmDatabase) {
    beginTransaction()
    insertOrUpdate(realmObject)
    commitTransaction()
}

我在我的存储库中调用 write 方法:

suspend fun insertALotOfObjects() {
    for (i in 0..1000) {
        val realmObjectToInsert = SampleRealmObject(id = i)
        realmRepository.write(realmObjectToInsert)
    }
}

我以这种方式在 ViewModel 中使用我的存储库:

viewModelScope.launch(Dispatchers.IO) {
    repository.insertALotOfObjects()
}

每次我运行 ViewModel 并单击启动数据库协程的按钮时,UI 都会完全冻结,甚至按钮状态都没有更新,并且卡在显示单击后的波纹效果,直到数据库操作完成。协程完成后,UI 恢复正常状态并再次响应。

我已经Thread.currentThread()在所有这些调用中记录了输出,并且当前线程值总是Thread[DefaultDispatcher-worker-1,5,main],所以协程实际上是在工作线程中运行的。

为什么会这样?UI不应该只在调用协程时UiThreadMainThread用于调用协程时才被阻塞吗?在协程运行时,如何解决这个问题并使 UI 响应?

标签: androidkotlinrealmcoroutinekotlin-coroutines

解决方案


您每次都在循环中创建一个新事务。相反,创建一个事务,并write在其中多次执行您的操作。


推荐阅读