我在Realm Database中使用MVVM模式(ViewModel,LiveData,协程)。我的Dao类中有一个方法,如下所示。在这里,领域由Dagger注入。
fun observeChannels(): LiveRealmData<Channel> {
val channelResults = realm.where(Channel::class.java).findAll()
return channelResults.asLiveData()
}
这是从存储库/中调用的,如下所示。因此,此协程在与创建Realm的线程不同的线程中运行。
suspend operator fun invoke(currentFiltering: ChannelFilterType = ChannelFilterType.ALL_CHANNELS)
: LiveData<Result<List<ChatChannel>>> = withContext(dispatcher) {
chatRepository.observeChannels().map {
if (it is Result.Success && currentFiltering != ChannelFilterType.ALL_CHANNELS) {
val channelToDisplay = mutableListOf<ChatChannel>()
for (channel in it.data) {
when (currentFiltering) {
ChannelFilterType.ALL_CHANNELS -> if (!channel.favMembers.contains("")) {
channelToDisplay.add(channel)
}
ChannelFilterType.FAVORITE_CHANNELS -> if (channel.favMembers.contains("")) {
channelToDisplay.add(channel)
}
}
}
Result.Success(channelToDisplay)
} else if (it is Result.Error) {
it
} else {
it
}
}
}
所以我得到了这个例外。 来自错误线程的领域访问。只能在创建对象的线程上访问领域对象。
解决此问题的最佳方法是什么?
我不使用Realm,所以在这里我可能会犯错,但是在浏览其介绍指南时,它说要在onCreate
(Realm.init(this)
)中初始化Realm。这意味着它希望在主UI线程上进行交互。这意味着您仅应使用Dispatchers.Main
,并且只要从lifecycleScope
或viewModelScope
之类的主作用域启动协程,就根本不需要指定调度程序或完全使用withContext
。具有回调参数的Realm方法是它将在后台线程上执行操作的位置,但是您永远不要自己在后台线程上与之交互。
在上面的示例中,您似乎只是在invoke
函数中注册观察者。注册观察者不是阻塞调用,因此您不应为此使用暂停功能,也不应尝试在后台使用withContext()
进行此操作。
协程有意义的区域是在后台执行某些阻止操作时。从该指南看来,Realm确实提供了异步事务。看起来Realm还不支持协程,但是您可以将异步方法转换为如下的暂停函数: