繁体   English   中英

Room 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM