Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何使用RxJava2在后台线程上查询领域_Android_Multithreading_Realm_Kotlin_Rx Java - Fatal编程技术网

Android 如何使用RxJava2在后台线程上查询领域

Android 如何使用RxJava2在后台线程上查询领域,android,multithreading,realm,kotlin,rx-java,Android,Multithreading,Realm,Kotlin,Rx Java,我想使用RxJava2在后台线程上读取/查询和转换领域数据。这是一个可以观察到的现象: fun getAllPlayers(): Observable<List<Player>> { return Observable.create { emitter -> val realm = Realm.getDefaultInstance() val players = realm.where(Player::class.java).

我想使用RxJava2在后台线程上读取/查询和转换领域数据。这是一个可以观察到的现象:

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))
    }
}
getAllPlayers()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
我犯了一个可怕的错误:

java.lang.IllegalStateException:无法在当前线程上使用侦听器。在没有循环器的线程上无法自动更新领域

好的,让我们创建一个带有活套的调度器:

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())

现在一切正常。但是,谁会杀了那根手线?如果从多个位置同时调用了
getAllPlayer()
,该怎么办?使用RxJava2在后台线程上查询领域是否存在其他(以及更好的)解决方案?

在我看来,您走的是正确的道路。只需创建HandlerThread和AndroidScheduler一次(也称为singleton),并对领域中的每个可见对象继续重复使用它们。不用关线。谢谢,@Budius!是否知道建议的方法是否允许我同时执行多个查询(即并行执行)?请确保对后台循环线程使用异步查询api(
findalsync()
和co)。出于某种原因,您可以使用同步api获得奇怪的竞争条件。为什么从
HandlerThread
创建的
AndroidScheduler
应该作为单例?我认为无论何时你使用你的时间表,它总是会使用第一次使用时使用的相同线程。如果您有在不同线程中执行的请求链,该怎么办。这是否意味着领域请求(保存、加载数据等)与在哪个线程上执行无关?