I have a DAO where I'm querying objects, some as liveData and most as regular functions. But today I am stuck in a loop of errors. If I access the object in main thread, it gives error of Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
But when used on a IO thread it gives another error of: can not add observer without main thread. The second error is weird because it should not be an observer but a simple list object from query.
DAO code:
@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>
}
on repository:
fun getAllItems() = ItemsDAO.getAllItems()
fun allItemsList() = ItemsDAO.allItemsList()
ViewModel:
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
Fragment:
val itemsList = itemsViewModel.allItemsList // the error occurrs here
//val itemsList = itemsViewModel.allItemsList()
If it is in main thread I get, java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
If in IO thread, I get : java.lang.IllegalStateException: Method addObserver must be called on the main thread
.
It is a simle list, why it is treated as observer? I have other similar methods to access the queried list similar way with method parameters and those works fine on a IO thread. Can anyone tell me any solution just to access the list on any thread?
Update. I have added suspend but that did not solve anything and it still thinks I am adding observer.
@Query("SELECT * FROM table_items")
suspend fun allItemsList(): List<Item>
CodePudding user response:
For Cannot access database on the main thread -> use suspended functions and coroutines and use
val itemsList = itemsViewModel.allItemsList.value
CodePudding user response:
Are you using Coroutine? the methods inside DAO & repository should be suspend fun
, then you can set the thread by using CoroutineScope.