我有一個 DAO,我在其中查詢物件,有些是 liveData,大多數是常規函式。但是今天我陷入了錯誤回圈。如果我在主執行緒中訪問物件,則會出現錯誤,Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
但在 IO 執行緒上使用時會出現另一個錯誤:無法在沒有主執行緒的情況下添加觀察者。第二個錯誤很奇怪,因為它不應該是觀察者,而是來自查詢的簡單串列物件。
DAO 代碼:
@Dao
interface ItemsDAO {
@Insert(onConflict = OnConflictStrategy.REPLACE)
...
@Delete
...
@Query("SELECT * FROM table_items ORDER BY timestamp")
fun getAllItems(): LiveData<List<Item>>
@Query("SELECT * FROM table_items")
fun allItemsList(): List<Item>
}
在存盤庫上:
fun getAllItems() = ItemsDAO.getAllItems()
fun allItemsList() = ItemsDAO.allItemsList()
視圖模型:
val getItems = itemPoolRepository.getAllItems()
val allItemsList = itemPoolRepository.allItemsList()
//also checked same result with the following:
//fun allPoolsItemsList() = itemPoolRepository.allItemsList() // Gives error : Method addObserver must be called on the main thread
分段:
val itemsList = itemsViewModel.allItemsList // the error occurrs here
//val itemsList = itemsViewModel.allItemsList()
如果它在主執行緒中,我得到,java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
如果在 IO 執行緒中,我得到 : java.lang.IllegalStateException: Method addObserver must be called on the main thread
。
這是一個簡單的串列,為什么它被視為觀察者?我還有其他類似的方法可以使用方法引數以類似的方式訪問查詢串列,并且這些方法在 IO 執行緒上運行良好。誰能告訴我任何解決方案只是為了訪問任何執行緒上的串列?
更新。我添加了暫停,但這并沒有解決任何問題,它仍然認為我正在添加觀察者。
@Query("SELECT * FROM table_items")
suspend fun allItemsList(): List<Item>
uj5u.com熱心網友回復:
你在使用協程嗎?DAO & repository 中的方法應該是suspend fun
,然后你可以使用 CoroutineScope 來設定執行緒。
uj5u.com熱心網友回復:
對于無法訪問主執行緒上的資料庫-> 使用掛起的函式和協程,并且我假設片段正在通過 di 訪問 viewModel。并且 viewmodel 在訪問時是惰性創建的,并且 viewmodel 的創建必須在主執行緒上完成。只需在訪問其函式之前嘗試訪問主執行緒上的視圖模型即可解決問題。所以,
// Access viewmodel so that it gets initialized on the main thread
itemsViewModel
val list = itemsViewModel.getList()
uj5u.com熱心網友回復:
即使您只想要串列,資料庫也需要在單獨的作業執行緒上執行操作。您可以使用與您相同的方法
@Query("SELECT * FROM table_items ORDER BY timestamp")
fun getAllItems(): LiveData<List<Item>>
只需更換
@Query("SELECT * FROM table_items")
fun allItemsList(): List<Item>
和
@Query("SELECT * FROM table_items")
fun allItemsList(): LiveData<List<Item>>
每當我們將回傳值包裝到 observable 中時,Room Database 會確保查詢在后臺執行緒上運行。
現在在 Fragment 中,添加 observable 以查找最新更改
// The onChanged() method fires when the observed data changes and the activity is
// in the foreground.
itemsViewModel.allItemsList.observe(owner = viewLifecycleOwner) { items ->
// Do something with the data.
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/456622.html
上一篇:輸入幾行后文本輸入的底部溢位顫動