在将协程与领域结合使用时,来自错误线程的领域访问

时间:2018-12-28 15:01:54

标签: android kotlin realm kotlinx.coroutines

我正在尝试将域与kotlin协程一起使用,并使用withContext()在新线程内进行查询

我观察到的是,线程在循环中切换,使领域抛出以下异常:来自错误线程的领域访问。只能在创建对象的线程上访问领域对象。

withContext(Dispatchers.IO) {
            val realm = Realm.getDefaultInstance()
            val images = mutableListOf<String>("id1", "id2", ...)
            for (imageId in images) {
                 println("THREAD : ${Thread.currentThread().name}")
                 val image = realm.where<Image>().equalTo("imageId", imageId).findFirst()
                 delay(1000) // Can lead to an actual switching to another thread
            }
            realm.close()
}

如dispatchers.IO文档所述:https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/-i-o.html

”此调度程序与[Default] [Dispatchers.Default]调度程序共享线程,因此使用      * withContext(Dispatchers.IO) { ... }不会导致实际切换到另一个线程;      *通常在同一线程中继续执行。“

我不明白为什么线程会在循环中切换。 如何使用协程正确管理领域实例?

2 个答案:

答案 0 :(得分:2)

您可以在协程的另一个新单线程中运行Realm。例如

val dispatcher =  Executors.newSingleThreadExecutor().asCoroutineDispatcher()
jobs.launch(dispatcher) {
  // create new Realm instance
}

答案 1 :(得分:1)

每次协程被挂起时,在它重新开始时,调度程序将找到一个线程来运行它。很有可能它将是一个与以前运行的线程不同的线程。