如何处理主线程中的RxAndroid错误

时间:2016-10-03 16:13:52

标签: error-handling rx-java rx-android

我是rxJava / Android的新手并且惊讶于我的onError lambda有时在主线程上被调用,有时候没有,尽管我使用.observeOn(AndroidSchedulers.mainThread())

示例1 :主线程上的onError
这按预期工作:在主线程上调用onError

Observable.error(new RuntimeException("RTE"))
    .subscribeOn(Schedulers.newThread())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(s -> {
                Log.e(TAG, "onNext("+s+")-thread: " + Thread.currentThread().getName());
            },
            throwable -> {
                Log.e(TAG, "onError()-thread: " + Thread.currentThread().getName());
            });

对数输出:

onError()-thread: main

示例2 :主线程上的onError NOT

Observable.create(new Observable.OnSubscribe<String>() {
    @Override
    public void call(Subscriber<? super String> subscriber) {
        subscriber.onNext("one and only");
    }
})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.timeout(1, TimeUnit.SECONDS)
.subscribe(s -> {
        Log.e(TAG, "onNext("+s+")-thread: " + Thread.currentThread().getName());
    },
    throwable -> {
        Log.e(TAG, "onError()-thread: " + Thread.currentThread().getName());
    });

输出是这样的:

onNext(one and only)-thread: main
onError()-thread: RxComputationScheduler-4       

我认为在调用observeOn(AndroidSchedulers.mainThread())之后,所有排放应该在主线程上完成。

所以我有这些问题:

  1. 我找不到任何文档来指定在什么情况下onError在哪个线程中调用。有谁知道链接?
  2. 我当然希望在GUI中显示一些错误指示:那么如何强制onError在主线程中始终被调用?

2 个答案:

答案 0 :(得分:10)

我刚刚发现我只需要更改通话顺序。当我在observeOn之后调用timeout时,它按预期工作:

.timeout(1, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())

日志输出

onNext(one and only)-thread: main
onError()-thread: main

原因是,observeOn只会影响调用以下的所有内容,并且只有在其他操作符再次更改线程之后才会影响。在上面的示例中,timeout()将更改为计算线程。

请注意,subscribeOn的工作方式不同。你称之为链条的位置并不重要 你应该只调用一次(当你第一次调用win多次调用它时:在这个Blog中看“Multiple subscribeOn”

这是一篇很好的博文,其中包含更多详细信息:RxJava- Understanding observeOn() and subscribeOn()

答案 1 :(得分:3)

因为.timeout(1, TimeUnit.SECONDS)默认情况下会在Schedulers.computation()上运行。