将领域与协程一起使用时从错误线程访问领域

Cui*_*chu 6 android realm kotlin kotlinx.coroutines

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

我观察到的是线程在循环中切换,使领域抛出此异常:来自不正确线程的领域访问。Realm 对象只能在创建它们的线程上访问。

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()
}
Run Code Online (Sandbox Code Playgroud)

正如 dispatchers.IO 文档在这里提到的:https : //kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/-io.html

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

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

小智 6

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

val dispatcher =  Executors.newSingleThreadExecutor().asCoroutineDispatcher()
jobs.launch(dispatcher) {
  // create new Realm instance
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*nik 5

每次协程暂停时,在它恢复时,调度程序都会找到一个线程来运行。它很可能与之前运行的线程不同。

  • 所以我们现在知道为什么会发生这种情况,但是是否已经有关于如何在协程中使用领域的最佳实践? (12认同)