用于处理IllegalStateException的Android-Kotlin Coroutines:无法访问主线程上



在我的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)

我知道我必须使用某种asnyc操作,因为在主线程上执行本地数据库操作可能需要很长时间。但在ViewModel类中,我在viewModelScope中启动了协同程序。这还不够吗?基于例外情况,似乎并非如此。那么,有没有人能告诉我如何正确地做到这一点。

编辑:

这是刀类:

@Query("SELECT * FROM account_table WHERE id = :id")
fun retrieveAccountData(id: Long) : Account

提前感谢

根据Room文档,如果您希望Room自动移动到后台线程来运行@Query,您可以将您的方法设置为suspend方法:

@Query("SELECT * FROM account_table WHERE id = :id")
suspend fun retrieveAccountData(id: Long) : Account

RoomDB支持LiveData。您可以将查询结果作为livedata返回,默认情况下,livedata在后台线程中执行操作,并在UI层中观察它。我已经修改了您下面的查询,它将返回LiveData而不是Account。

@Query("SELECT * FROM account_table WHERE id = :id")
fun retrieveAccountData(id: Long) : LiveData<Account>

最新更新