android - 使用 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不应该只在调用协程时UiThread
或MainThread
用于调用协程时才被阻塞吗?在协程运行时,如何解决这个问题并使 UI 响应?
解决方案
您每次都在循环中创建一个新事务。相反,创建一个事务,并write
在其中多次执行您的操作。
推荐阅读
- sql - SSMS SQL - 创建具有相关列的表
- thymeleaf - Thymeleaf lists.sort 导致 LazyInitializationException 尽管在视图中打开会话
- c# - 为什么我会收到“未分配的局部变量”错误?
- r - R中系统发育重建中的混合数据分区
- perl - 在 perl 中将空格或逗号分隔的字符串拆分为列表
- javascript - 如何在 s3 aws 存储桶中正确配置 CORS
- r - 使用 dplyr 创建新数据框并添加列
- javascript - 错误 [ERR_HTTP_HEADERS_SENT]:在将标头发送到客户端后无法设置标头 - Node Express Mongodb
- elasticsearch - Logstash 显示遇到可重试错误
- c - 即使代码正在运行,编译器也会显示警告