Android 如何使用RxJava2在后台线程上查询领域
我想使用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).
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
应该作为单例?我认为无论何时你使用你的时间表,它总是会使用第一次使用时使用的相同线程。如果您有在不同线程中执行的请求链,该怎么办。这是否意味着领域请求(保存、加载数据等)与在哪个线程上执行无关?