具有协程不正确线程的领域

问题描述 投票:0回答:1

我在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
        }
    }
}

所以我得到了这个例外。 来自错误线程的领域访问。只能在创建对象的线程上访问领域对象。

解决此问题的最佳方法是什么?

android kotlin realm kotlin-coroutines realm-mobile-platform
1个回答
0
投票

我不使用Realm,所以在这里我可能会犯错,但是在浏览其介绍指南时,它说要在onCreateRealm.init(this))中初始化Realm。这意味着它希望在主UI线程上进行交互。这意味着您仅应使用Dispatchers.Main,并且只要从lifecycleScopeviewModelScope之类的主作用域启动协程,就根本不需要指定调度程序或完全使用withContext。具有回调参数的Realm方法是它将在后台线程上执行操作的位置,但是您永远不要自己在后台线程上与之交互。

在上面的示例中,您似乎只是在invoke函数中注册观察者。注册观察者不是阻塞调用,因此您不应为此使用暂停功能,也不应尝试在后台使用withContext()进行此操作。

协程有意义的区域是在后台执行某些阻止操作时。从该指南看来,Realm确实提供了异步事务。看起来Realm还不支持协程,但是您可以将异步方法转换为如下的暂停函数:

© www.soinside.com 2019 - 2024. All rights reserved.