如何使用RxJava2在后台线程上查询Realm

时间:2017-08-02 17:26:22

标签: android multithreading realm kotlin rx-java

我想使用RxJava2在后台线程上读取/查询和转换Realm数据。这是一个Observable:

fun getAllPlayers(): Observable<List<Player>> {
    return Observable.create { emitter ->
        val realm = Realm.getDefaultInstance()
        val players = realm.where(Player::class.java).findAll()

        val listener = RealmChangeListener<RealmResults<Player>> { players ->
            if (!emitter.isDisposed) {
                emitter.onNext(realm.copyFromRealm(players))
            }
        }

        emitter.setDisposable(Disposables.fromRunnable(Runnable {
            players.removeChangeListener(listener)
            realm.close()
        }))

        players.addChangeListener(listener)
        emitter.onNext(realm.copyFromRealm(players))
    }
}

如果我尝试将以下内容应用于observable:

getAllPlayers()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())

我得到了这个可怕的错误:

  

java.lang.IllegalStateException:不能在当前线程上使用监听器。在没有looper的情况下,不能在线程上自动更新域。

好的,让我们用Looper创建一个Scheduler:

fun createSubscribeOnScheduler(): Scheduler {
    val t = HandlerThread("worker")
    if (!t.isAlive())
        t.start()
    return AndroidSchedulers.from(t.looper)
}

我们可以这样使用它:

val subscribeOnScheduler = createSubscribeOnScheduler()
getAllPlayers()
    .subscribeOn(subscribeOnScheduler)
    .unsubscribeOn(subscribeOnScheduler)
    .observeOn(AndroidSchedulers.mainThread())

现在一切正常。但是,谁会杀死HandlerThread?如果从多个地方同时调用getAllPlayer()怎么办?是否存在使用RxJava2在后台线程上查询Realm的其他(和更好)解决方案?

0 个答案:

没有答案