![](/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.