单个观察者未调用onError()

时间:2019-01-29 14:28:56

标签: java android observable rx-java2

我已经在Android应用程序的MainActivity中编写了以下代码。当我运行以下代码时,它不会引发任何异常,并且onError()也不会被调用。但是我看到onSuccess: testing starts 两次,但看不到onSuccess: testing ends。为什么不调用onError()和/或应用程序不崩溃?

Single.timer(1000, TimeUnit.MILLISECONDS)
                .subscribeOn(Schedulers.computation())
                .subscribeWith(new DisposableSingleObserver<Long>() {
                    @Override
                    public void onSuccess(Long initiationTimeStamp) {
                        String s = null;
                        Log.d(TAG, "onSuccess: testing starts");
                        Log.d(TAG, "onSuccess:test  "+ s.isEmpty());
                        Log.d(TAG, "onSuccess: testing ends");
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                    }
                });

2 个答案:

答案 0 :(得分:1)

您正在s.isEmpty()字符串上调用NULL,这就是为什么它在第一次打印时结束的原因。就是说onSuccess()不会抛出任何东西,因此它仅在抛出NullPointerException时停止执行(为您在RxJava中对其进行静默处理)。订阅可观察项后,您会在onSuccess()中获得初始值,然后如果它发生更改或重新订阅,您在onSuccess()中将获得另一个值,这就是为什么它被称为两次的原因。而且因为onError()是针对操作链中发生的错误,所以抛出异常时,您不会在onSuccess()中得到错误。


此行为是故意的。根据Rx Contract,观察者不应同时收到onSuccess()onError()。您需要自己处理onSuccess()中的异常。

例如:

Single.timer(1000, TimeUnit.MILLISECONDS)
            .subscribeOn(Schedulers.computation())
            .subscribeWith(new DisposableSingleObserver<Long>() {
                @Override
                public void onSuccess(Long initiationTimeStamp) {
                    try {
                        String s = null;
                        Log.d(TAG, "onSuccess: testing starts");
                        Log.d(TAG, "onSuccess:test  "+ s.isEmpty());
                        Log.d(TAG, "onSuccess: testing ends");
                    }
                    catch (Throwable ex) {
                        // tell the upstream we can't accept any more data (OPTIONAL)
                        dispose();
                        // pass error to error handler
                        onError(ex);
                    }
                }

                @Override
                public void onError(Throwable e) {
                    e.printStackTrace();
                }
            });

祝你好运:)

答案 1 :(得分:0)

onError用于操作员链中发生的错误。您在onSuccess中所做的事情已经结束了,不会在onError中进行报告。