【问题标题】:How to observeOn the calling thread in java rx?java - 如何观察java rx中的调用线程?
【发布时间】:2015-11-20 08:17:33
【问题描述】:

有没有办法告诉 java rx 在 observeOn 函数中使用当前线程?我正在为 android 同步适配器编写代码,我希望在同步适配器线程中而不是在主线程中观察结果。

使用 Retrofit + RX Java 的示例网络调用如下所示:

MyRetrofitApi.getInstance().getObjects()
.subscribeOn(Schedulers.io())
.observeOn(<current_thread>)
.subscribe(new Subscriber<Object>() {
    //do stuff on the sync adapter thread

}

我尝试使用

...
.observeOn(AndroidSchedulers.handlerThread(new Handler(Looper.myLooper())))
...

这与 android rx 为主线程创建调度程序的方式相同,但一旦我将 Looper.myLooper() 替换为 Looper.getMainLooper(),它就不再工作了。

我可以使用 Schedulers.newThread(),但由于它与大量服务器调用的复杂同步代码,我会不断创建一个新线程来触发新的网络调用,该调用再次创建新线程以启动更多网络调用。有没有办法做到这一点?还是我的方法本身完全错误?

【问题讨论】:

  • 这有点投机,所以我不会将其发布为答案:从版本 2.0-beta2 开始,Retrofit 不再将网络请求放在不同的线程上 - 请参见此处:github.com/square/retrofit/commit/…因此,如果您使用的是当前版本的 Retrofit,您应该可以完全跳过 subscribeOnobserveOn,而一直保持在同步适配器线程上。还是我误解了您的问题,您确实想创建新线程,但它们应该都返回到您开始的线程?
  • 你解决了吗?

标签: rx-java android-syncadapter rx-android


【解决方案1】:

尝试使用Schedulers.immediate()

MyRetrofitApi.getInstance().getObjects()
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.immediate())
.subscribe(new Subscriber<Object>() {
    //do stuff on the sync adapter thread

}

它的描述是:Creates and returns a Scheduler that executes work immediately on the current thread.

注意:
我认为将所有工作保留在 SyncAdapter 的线程上是可以的,因为它已经在使用不同的线程

【讨论】:

  • Schedulers.immediate() 不适合我。我需要在 GlThread 上观察,但它在 subscribeOn 的线程上观察。可能是什么原因?
  • @DmitriyPuchkov 你的subscribeOnobserveOn 函数的顺序是什么?
  • 顺序和你写的一样。我通过创建将可运行文件发布到 GLThread 的自定义执行程序来解决我的问题。
  • @DmitriyPuchkov 是你的GLThread 吗?我写的解决方案对我有用。
  • RxJava2 上没有 Schedulers.immediate(),有什么新的吗?
【解决方案2】:

哦,我刚刚在 wiki 上找到了这个:https://github.com/ReactiveX/RxAndroid#observing-on-arbitrary-threads

new Thread(new Runnable() {
    @Override
    public void run() {
        final Handler handler = new Handler(); // bound to this thread
        Observable.just("one", "two", "three", "four", "five")
                .subscribeOn(Schedulers.newThread())
                .observeOn(HandlerScheduler.from(handler))
                .subscribe(/* an Observer */)

        // perform work, ...
    }
}, "custom-thread-1").start();

我认为这也适用于您的情况 - 当然,除了创建一个新线程......所以只是:

final Handler handler = new Handler(); // bound to this thread
MyRetrofitApi.getInstance().getObjects()
    .subscribeOn(Schedulers.io())
    .observeOn(HandlerScheduler.from(handler))
    .subscribe(new Subscriber<Object>() {
        //do stuff on the sync adapter thread

    }

【讨论】:

  • 感谢您的快速回复。我升级了 rx android(我使用的是旧版本)并尝试了这个例子。不幸的是它没有工作,但我创建了一些测试并发现 onNext() 被调用但订阅者没有收到它。只有在最后添加 Looper.loop() 之后它似乎才能工作(这是一个处理消息的无限循环)。即使是完全相同的示例也告诉我需要在创建处理程序之前使用 Looper.prepare()。也许我在做一些根本错误的事情,或者可能是 android rx 本身的问题?
  • 恐怕我不能告诉你这里出了什么问题……让我们看看其他人怎么说……
  • @tiqz found out the that onNext() is called but the Subscriber doesn't receive it onNext 是订阅者的方法,所以你写的对我来说有点奇怪。理论上大卫的答案应该没问题。我建议您发布更详细的您正在尝试的内容,以便我们为您提供帮助。
猜你喜欢
  • 1970-01-01
  • 2013-03-05
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 2012-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多