簡體   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