Home > Back-end >  android room query method returning list but is wrongfully treated as LiveData
android room query method returning list but is wrongfully treated as LiveData

Time:04-06

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.

  • Related