In my Android App, I use Room
as local database to store the Account information of a user. When I make a simple Room
request to retrieve the Account
object stored in the database, I get the following error message :
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
Here, is the Fragment
code from which I make the local database request:
// AccountInformationFragment.kt
accountDataFragmentViewModel.retrieveAccountData(accountId).observe(viewLifecycleOwner, Observer {
// do some stuff
})
In the ViewModel
class I have implemented retrieveAccountData()
like this:
// AccountInformationFragmentViewModel.kt
// used to get the account from the local datasource
fun retrieveAccountData(id:Long): LiveData<Account>{
val result = MutableLiveData<Account>()
viewModelScope.launch {
val account = authRepository.retrieveAccountData(id)
result.postValue(account)
}
return result
}
In the Repository
class, I have implemented retrieveAccountData()
like this:
// AccountRepository.kt
suspend fun retrieveAccountData(accId:Long): Account =
accountDao.retrieveAccountData(accId)
I understand that I have to use some sort of asnyc operation because the local database operation may take a long time when its performed on the main thread.
But in the ViewModel
class I launched the coroutine inside the viewModelScope
. Is that not enough? Based on the exception, it seems not. So, is there someone who could tell me how to do this correctly.
EDIT:
Here is the Dao class :
@Query("SELECT * FROM account_table WHERE id = :id")
fun retrieveAccountData(id: Long) : Account
Thanks in advance
As per the Room documentation, if you want Room to automatically move to a background thread to run your @Query
, you can make your method a suspend
method:
@Query("SELECT * FROM account_table WHERE id = :id")
suspend fun retrieveAccountData(id: Long) : Account