【发布时间】:2021-02-21 15:00:25
【问题描述】:
在我的 Android 应用程序中,我使用 Room 作为本地数据库来存储用户的帐户信息。当我发出一个简单的Room 请求以检索存储在数据库中的Account 对象时,我收到以下错误消息:
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
这里是我发出本地数据库请求的Fragment 代码:
// AccountInformationFragment.kt
accountDataFragmentViewModel.retrieveAccountData(accountId).observe(viewLifecycleOwner, Observer {
// do some stuff
})
在ViewModel 类中,我实现了retrieveAccountData(),如下所示:
// 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
}
在Repository 类中,我已经像这样实现了retrieveAccountData():
// AccountRepository.kt
suspend fun retrieveAccountData(accId:Long): Account =
accountDao.retrieveAccountData(accId)
我知道我必须使用某种异步操作,因为本地数据库操作在主线程上执行时可能需要很长时间。
但是在ViewModel 类中,我在viewModelScope 中启动了协程。这还不够吗?根据异常,似乎没有。那么,有没有人可以告诉我如何正确地做到这一点。
编辑:
这是道类:
@Query("SELECT * FROM account_table WHERE id = :id")
fun retrieveAccountData(id: Long) : Account
提前致谢
【问题讨论】:
-
你的
retrieveAccountData是挂起的方法吗?如果不是,为什么不呢?这就是自动将数据库访问跳转到后台线程的原因。 -
我已经从 AccountDao 类中添加了 retrieveAccountData()。你的意思是我只需要添加suspend关键字?
-
@abdullahcelik 是的,尝试将
suspend添加到您正在使用的repository和dao中的方法中。
标签: android android-room kotlin-coroutines illegalstateexception