![](/img/trans.png)
[英]'Cannot access database on the main thread since it may potentially lock the UI for a long period of time' Also, I Accessed room using coroutine
[英]Room Coroutine is executed in main thread
我在玩 Kotlin Flow、Coroutines 和 Room。 我正在尝试将数据从我的存储库插入到我的房间数据库中。
插入单个项目时没有问题,但如果我尝试插入项目列表,执行将中止并且控制台会记录以下消息:
I/Choreographer: Skipped 47 frames! The application may be doing too much work on its main thread.
我不明白为什么插入操作在主线程上执行,因为根据文档,暂停的 DAO 操作应该始终在 Room 内部启动的协程中执行(最终应该在后台线程上运行)。 我还尝试在另一个 Scope 中显式运行插入调用 (withContext(Dispatchers.IO) {... }) 但没有区别。
这是我的代码的样子:
视图模型:
fun setStateEvent(stateEvent: StateEvent) {
viewModelScope.launch {
when (stateEvent) {
is StateEvent.GetItems -> {
repository.getItems().onEach { dateState ->
_dataState.value = dateState
}.launchIn(viewModelScope)
}
}
}
}
存储库:
suspend fun getItems(): Flow<DataState<List<Item>>> = flow {
emit(DataState.Loading)
try {
val items = itemService.getAllItems()
emit(DataState.Success(items))
itemDao.insertItems(items) // The execution stops here
} catch (e: Exception) {
emit(DataState.Error(e))
}
}
道:
@Insert
suspend fun insertItems(items: List<Item>)
我也尝试调试并找到问题的根源,但我没有运气。 如果有人能告诉我出了什么问题,我会很高兴。
据我所见,这里没有问题。 Choreographer 消息可能具有误导性,它可能与主线程无关。 我在调试时经常看到这个,可能是由于调试器的开销。 沉重的布局膨胀也可能导致它。
此外,您不需要launchIn(viewModelScope)
,因为流已收集在该 scope 中。只需使用collect()
即可。 与其他答案可能暗示的不同,您说 Room 在使用suspend
DAO 方法时自动切换线程是正确的。
对不起大家......我原来帖子中的代码没有问题。 我没有评估我在捕获异常时抛出的错误。 所以问题是完全不同的(不是 NULL 约束失败)。
由于主线程的消息,我没有考虑这个。
感谢大家的帮助。
您可以在执行 viewmodelScope 的 CoroutineScope 的启动中添加 Dispatchers.IO
fun setStateEvent(stateEvent: StateEvent) {
viewModelScope.launch(Dispatchers.IO) {
when (stateEvent) {
is StateEvent.GetItems -> {
repository.getItems().collect {
for(item in it) { _dataState.value = item }
}
}
}
}
}
确保你的 gradle 中有 room-ktx 的依赖项,这将允许你在你的 room 界面中使用挂起函数
implementation "androidx.room:room-ktx:2.2.5"
请参阅: https://developer.android.com/jetpack/androidx/releases/room#declaring_dependencies
无论哪种方式,您都无法从房间界面中的暂停中受益。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.