Rxjava2 Observable的错误处理操作详解及实例

简要:

需求了解:

Rxjava 中当数据处理派发中发生了异常 ,观察者会接受到一个 Error 的通知,那如果不想发射这个异常的通知,自己处理掉呢?答案当然是可以的,在 Rxjava 中很多操作符可用于对 Observable 发射的 onError 通知做出响应或者从错误中恢复。

例如:

  1. 吞掉这个错误,切换到一个备用的Observable继续发射数据
  2. 吞掉这个错误然后发射默认值
  3. 吞掉这个错误并立即尝试重启这个Observable
  4. 吞掉这个错误,在一些回退间隔后重启这个Observable

Rxjava中常见的错误处理操作符有如下几类:

  • onErrorReturn():指示Observable在遇到错误时发射一个特定的数据
  • onErrorResumeNext():指示Observable在遇到错误时发射一个数据序列
  • onExceptionResumeNext():指示Observable遇到错误时继续发射数据
  • retry():指示Observable遇到错误时重试
  • retryWhen():指示Observable遇到错误时,将错误传递给另一个Observable来决定是否要重新给订阅这个Observable

1. Catch

从 onError 通知中恢复发射数据。

img-Catch

Catch 操作符拦截原始Observable的 onError 通知,将它替换为其它的数据项或数据序列,让产生的Observable能够正常终止或者根本不终止。

1.1 onErrorReturn

onErrorReturn 方法返回一个镜像原有Observable行为的新Observable,后者会忽略前者的 onError 调用,不会将错误传递给观察者,作为替代,它会发发射一个特殊的项并调用观察者的 onCompleted 方法。

  • onErrorReturnItem(T item): 让Observable遇到错误时发射一个指定的项(item)并且正常终止。
img-onErrorReturnItem
  • onErrorReturn(Function<Throwable, T> valueSupplier):让Observable遇到错误时通过一个函数Function来进行判断返回指定的类型数据,并且正常终止。
img-onErrorReturn

示例代码:

    // 创建一个可以发射异常的Observable
    Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
            emitter.onNext(1);
            emitter.onNext(2);
            emitter.onNext(1 / 0);  // 产生一个异常
            emitter.onNext(3);
            emitter.onNext(4);
        }
    });

    /** 1. onErrorReturnItem(T item)
     * 让Observable遇到错误时发射一个指定的项(item)并且正常终止。
     */
    observable.onErrorReturnItem(888)   // 源Observable发生异常时发射指定的888数据
            .subscribe(new Observer<Integer>() {
                @Override
                public void onSubscribe(Disposable d) {
                    System.out.println("--> onSubscribe(1)");
                }

                @Override
                public void onNext(Integer integer) {
                    System.out.println("--> onNext(1): " + integer);
                }

                @Override
                public void onError(Throwable e) {
                    System.out.println("--> onError(1): " + e);
                }

                @Override
                public void onComplete() {
                    System.out.println("--> onCompleted(1)");
                }
            });

    System.out.println("-----------------------------------------------");
    /**
     * 2. onErrorReturn(Function<Throwable, T> valueSupplier)
     * 让Observable遇到错误时通过一个函数Function来接受Error参数并进行判断返回指定的类型数据,并且正常终止。
     */
    observable.onErrorReturn(new Function<Throwable, Integer>() {
        @Override
        public Integer apply(Throwable throwable) throws Exception {
            System.out.println("--> apply(1): e = " + throwable);
            return 888; // 源Observable发生异常时发射指定的888数据
        }
    }).subscribe(new Observer<Integer>() {
        @Override
        public void onSubscribe(Disposable d) {
            System.out.println("--> onSubscribe(2)");
        }

        @Override
        public void onNext(Integer integer) {
            System.out.println("--> onNext(2): " + integer);
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("--> onError(2): " + e);
        }

        @Override
        public void onComplete() {
            System.out.println("--> onCompleted(2)");
        }
    });

输出:

--> onSubscribe(1)
--> onNext(1): 1
--> onNext(1): 2
--> onNext(1): 888
--> onCompleted(1)
-----------------------------------------------
--> onSubscribe(2)
--> onNext(2): 1
--> onNext(2): 2
--> apply(1): e = java.lang.ArithmeticException: / by zero
--> onNext(2): 888
--> onCompleted(2)

Javadoc: onErrorReturnItem(T item)
Javadoc: onErrorReturn(Function<Throwable, T> valueSupplier)

1.2 onErrorResumeNext

onErrorResumeNext 方法返回一个镜像原有Observable行为的新Observable,后者会忽略前者的 onError 调用,不会将错误传递给观察者,作为替代,它会开始另一个指定的备用Observable。

img-onErrorResumeNext-Observable
  • onErrorResumeNext(ObservableSource next): 让Observable在遇到错误时开始发射第二个指定的Observable的数据序列。
  • onErrorResumeNext(Function<Throwable, ObservableSource<T>> resumeFunction):让Observable在遇到错误时通过一个函数Function来接受Error参数并进行判断返回指定的第二个Observable的数据序列。

示例代码:

    // 创建一个可以发射异常的Observable
    Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
            emitter.onNext(1);
            emitter.onNext(2);
            emitter.onNext(1 / 0);  // 产生一个异常
            emitter.onNext(3);
            emitter.onNext(4);
        }
    });
    
    /**
     * 3. onErrorResumeNext(ObservableSource next)
     * 让Observable在遇到错误时开始发射第二个指定的Observable的数据序列
     */
    observable.onErrorResumeNext(Observable.just(888))  // 当发生异常的时候继续发射此项Observable
            .subscribe(new Observer<Integer>() {
                @Override
                public void onSubscribe(Disposable d) {
                    System.out.println("--> onSubscribe(3)");
                }

                @Override
                public void onNext(Integer integer) {
                    System.out.println("--> onNext(3): " + integer);
                }

                @Override
                public void onError(Throwable e) {
                    System.out.println("--> onError(3): " + e);
                }

                @Override
                public void onComplete() {
                    System.out.println("--> onCompleted(3)");
                }
            });

    System.out.println("-----------------------------------------------");
    /**
     * 4. onErrorResumeNext(Function<Throwable, ObservableSource<T>> resumeFunction)
     * 让Observable在遇到错误时通过一个函数Function来接受Error参数并进行判断返回指定的第二个Observable的数据序列
     */
    observable.onErrorResumeNext(new Function<Throwable, ObservableSource<? extends Integer>>() {
        @Override
        public ObservableSource<? extends Integer> apply(Throwable throwable) throws Exception {
            System.out.println("--> apply(4): " + throwable);
            return Observable.just(888);    // 当发生异常的时候继续发射此项Observable
        }
    }).subscribe(new Observer<Integer>() {
        @Override
        public void onSubscribe(Disposable d) {
            System.out.println("--> onSubscribe(4)");
        }

        @Override
        public void onNext(Integer integer) {
            System.out.println("--> onNext(4): " + integer);
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("--> onError(4): " + e);
        }

        @Override
        public void onComplete() {
            System.out.println("--> onCompleted(4)");
        }
    });

输出:

--> onSubscribe(3)
--> onNext(3): 1
--> onNext(3): 2
--> onNext(3): 888
--> onCompleted(3)
-----------------------------------------------
--> onSubscribe(4)
--> onNext(4): 1
--> onNext(4): 2
--> apply(4): java.lang.ArithmeticException: / by zero
--> onNext(4): 888
--> onCompleted(4)

Javadoc: onErrorResumeNext(ObservableSource next)
Javadoc: onErrorResumeNext(Function<Throwable, ObservableSource<T>> resumeFunction)

1.3 onExceptionResumeNext

与 onErrorResumeNext 类似, onExceptionResumeNext 方法返回一个镜像原有Observable行为的新Observable,也使用一个备用的Observable,不同的是,如果 onError 收到的 Throwable 不是一个 Exception ,它会将错误传递给观察者的 onError 方法,不会使用备用的Observable。

img-onExceptionResumeNext

解析: onExceptionResumeNext 只会对Exception类型的异常进行处理,如果onError收到的Throwable不是一个Exception,它会将错误传递给观察者的onError方法,不会使用备用的Observable 。

示例代码:

    // 创建一个可以发射异常的Observable
    Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
            emitter.onNext(1);
            emitter.onNext(2);
        //  emitter.onError(new Throwable("This is Throwable!"));  // Throwable类型异常,直接通知观察者
        //  emitter.onError(new Error("This is Error!"));          // Error类型异常,直接通知观察者
            emitter.onError(new Exception("This is Exception!"));  // Exception类型异常,进行处理,发送备用的Observable数据
        //    emitter.onNext(1 / 0);  // 会产生一个ArithmeticException异常,异常会被处理,发送备用的Observable数据
            emitter.onNext(3);
            emitter.onNext(4);
        }
    });
    /**
     * 5. onExceptionResumeNext(ObservableSource next)
     *  如果onError收到的Throwable不是一个Exception,它会将错误传递给观察者的onError方法,不会使用备用的Observable
     *  只对Exception类型的异常通知进行备用Observable处理
     */
    observable1.onExceptionResumeNext(Observable.just(888))
            .subscribe(new Observer<Integer>() {
                @Override
                public void onSubscribe(Disposable d) {
                    System.out.println("--> onSubscribe(5)");
                }

                @Override
                public void onNext(Integer integer) {
                    System.out.println("--> onNext(5): " + integer);
                }

                @Override
                public void onError(Throwable e) {
                    System.out.println("--> onError(5): " + e);
                }

                @Override
                public void onComplete() {
                    System.out.println("--> onCompleted(5)");
                }
            });

输出:

--> onSubscribe(5)
--> onNext(5): 1
--> onNext(5): 2
--> onNext(5): 888
--> onCompleted(5)

Javadoc: onExceptionResumeNext(ObservableSource next)

2. Retry

如果原始Observable遇到错误,重新订阅它期望它能正常终止。

Retry 操作符不会将原始 Observable 的 onError 通知传递给观察者,它会订阅这个Observable,再给它机会无错误地完成它的数据序列。 Retry 总是传递 onNext 通知给观察者,由于重新订阅,可能会造成数据项重复情况。

2.1 retry()

retry():无论收到多少次 onError 通知,无参数版本的 retry 都会继续订阅并发射原始Observable。

img-retry

注意: 因为如果遇到异常,将会无条件的重新订阅原始的Observable,知道没有异常的发射全部的数据序列为止。所以如果你的异常发生后重新订阅也不会恢复正常的话,会一直订阅下去,有内存泄露的风险。

2.2 retry(long times)

retry(long times):接受单个 count 参数的 retry 会最多重新订阅指定的次数,如果次数超了,它不会尝试再次订阅,它会把最新的一个 onError 通知传递给它的观察者。

img-retry-times

2.3 retry(long times, Predicate predicate)

retry(long times, Predicate<Throwable> predicate):遇到异常后最多重新订阅 times 次,每次重新订阅经过函数predicate 最终判断是否继续重新订阅,如果 times 到达上限或者 predicate 返回 false 中任意一个最先满足条件,都会终止重新订阅,retry 会将最新的一个 onError 通知传递给它的观察者。

img-retry-times-predicate

2.4 retry(Predicate predicate)

retry(Predicate<Throwable> predicate):接受一个谓词函数作为参数,这个函数的两个参数是:重试次数和导致发射 onError 通知的 Throwable 。这个函数返回一个布尔值,如果返回 true , retry 应该再次订阅和镜像原始的Observable,如果返回 false , retry 会将最新的一个 onError 通知传递给它的观察者

img-retry-predicate

2.5 retry(BiPredicate predicate)

retry(BiPredicate<Integer, Throwable> predicate):遇到异常时,通过函数 predicate 判断是否重新订阅源Observable,并且通过参数 Integer 传递给 predicate 重新订阅的次数,retry 会将最新的一个 onError 通知传递给它的观察者。

img-retry-BiPrediccate

2.6 retryUntil(BooleanSupplier stop)

retryUntil(BooleanSupplier stop):重试重新订阅,直到给定的停止函数 stop 返回 true,retry 会将最新的一个 onError 通知传递给它的观察者。

img-retryUntil

2.7 retryWhen(Function handler)

retryWhen(Function<Observable<Throwable>, ObservableSource> handler):retryWhen 和 retry 类似,区别是, retryWhen 将 onError 中的 Throwable 传递给一个函数,这个函数产生另一个 Observable, retryWhen 观察它的结果再决定是不是要重新订阅原始的Observable。如果这个Observable发射了一项数据,它就重新订阅,如果这个Observable发射的是 onError 通知,它就将这个通知传递给观察者然后终止。

img-retryWhen

实例代码:

    // flag for emitted onError times
    public static int temp = 0;

    // 创建可以发送Error通知的Observable
    Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
            emitter.onNext(1);
            emitter.onNext(2);
            if (temp <= 2) {
                emitter.onError(new Exception("Test Error!"));
                temp++;
            }
            emitter.onNext(3);
            emitter.onNext(4);
        }
    });

    /**
     * 1. retry()
     *  无论收到多少次onError通知, 都会去继续订阅并发射原始Observable。
     */
    observable.doOnSubscribe(new Consumer<Disposable>() {
        @Override
        public void accept(Disposable disposable) throws Exception {
            System.out.println("----> doOnSubscribe(1)");
        }
    }).retry().subscribe(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            System.out.println("--> accept(1): " + integer);
        }
    });

    System.out.println("---------------------------------------------");
    temp = 0;
    /**
     * 2. retry(long times)
     *  遇到异常后,最多重新订阅源Observable times次
     */
    observable.doOnSubscribe(new Consumer<Disposable>() {
        @Override
        public void accept(Disposable disposable) throws Exception {
            System.out.println("----> doOnSubscribe(2)");
        }
    }).retry(1) // 遇到异常后,重复订阅的1次
      .subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
                System.out.println("--> onSubscribe(2)");
            }

            @Override
            public void onNext(Integer integer) {
                System.out.println("--> onNext(2): " + integer);
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("--> onError(2): " + e);
            }

            @Override
            public void onComplete() {
                System.out.println("--> onCompleted(2)");
            }
      });

    System.out.println("---------------------------------------------");
    temp = 0;
    /**
     * 3. retry(long times, Predicate<Throwable> predicate)
     *  遇到异常后最多重新订阅times次,每次重新订阅经过函数predicate最终判断是否继续重新订阅
     *  如果times到达上限或者predicate返回false中任意一个最先满足条件,都会终止重新订阅
     */
    observable.doOnSubscribe(new Consumer<Disposable>() {
        @Override
        public void accept(Disposable disposable) throws Exception {
            System.out.println("----> doOnSubscribe(3)");
        }
    }).retry(2, new Predicate<Throwable>() {
        @Override
        public boolean test(Throwable throwable) throws Exception {
            System.out.println("--> test(3)");
            if(throwable instanceof Exception) {
                return true;    // 遇到异常通知后是否继续继续订阅
            }
            return false;
        }
    }).subscribe(new Observer<Integer>() {
        @Override
        public void onSubscribe(Disposable d) {
            System.out.println("--> onSubscribe(3)");
        }

        @Override
        public void onNext(Integer integer) {
            System.out.println("--> onNext(3): " + integer);
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("--> onError(3): " + e);
        }

        @Override
        public void onComplete() {
            System.out.println("--> onCompleted(3)");
        }
    });

    System.out.println("---------------------------------------------");
    temp = 0;
    /**
     * 4. retry(Predicate<Throwable> predicate)
     *  遇到异常时,通过函数predicate判断是否重新订阅源Observable
     */
    observable.doOnSubscribe(new Consumer<Disposable>() {
        @Override
        public void accept(Disposable disposable) throws Exception {
            System.out.println("----> doOnSubscribe(4)");
        }
    }).retry(new Predicate<Throwable>() {
        @Override
        public boolean test(Throwable throwable) throws Exception {
            if (throwable instanceof Exception) {
                return true;    // 遇到异常通知后是否继续继续订阅
            }
            return false;
        }
    }).subscribe(new Observer<Integer>() {
        @Override
        public void onSubscribe(Disposable d) {
            System.out.println("--> onSubscribe(4)");
        }

        @Override
        public void onNext(Integer integer) {
            System.out.println("--> onNext(4): " + integer);
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("--> onError(4): " + e);
        }

        @Override
        public void onComplete() {
            System.out.println("--> onCompleted(4)");
        }
    });

    System.out.println("---------------------------------------------");
    temp = 0;
    /**
     * 5. retry(BiPredicate<Integer, Throwable> predicate)
     *   遇到异常时,通过函数predicate判断是否重新订阅源Observable,并且通过参数integer传递给predicate重新订阅的次数
     */
    observable.doOnSubscribe(new Consumer<Disposable>() {
        @Override
        public void accept(Disposable disposable) throws Exception {
            System.out.println("----> doOnSubscribe(5)");
        }
    }).retry(new BiPredicate<Integer, Throwable>() {
        @Override
        public boolean test(Integer integer, Throwable throwable) throws Exception {
            System.out.println("--> test(5): " + integer);
            if (throwable instanceof Exception) {
                return true;    // 遇到异常通知后是否继续继续订阅
            }
            return false;
        }
    }).subscribe(new Observer<Integer>() {
        @Override
        public void onSubscribe(Disposable d) {
            System.out.println("--> onSubscribe(5)");
        }

        @Override
        public void onNext(Integer integer) {
            System.out.println("--> onNext(5): " + integer);
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("--> onError(5): " + e);
        }

        @Override
        public void onComplete() {
            System.out.println("--> onCompleted(5)");
        }
    });

    System.out.println("---------------------------------------------");
    temp = 0;
    /**
     * 6. retryUntil(BooleanSupplier stop)
     * 重试重新订阅,直到给定的停止函数stop返回true
     */
    observable.doOnSubscribe(new Consumer<Disposable>() {
        @Override
        public void accept(Disposable disposable) throws Exception {
            System.out.println("----> doOnSubscribe(6)");
        }
    }).retryUntil(new BooleanSupplier() {
        @Override
        public boolean getAsBoolean() throws Exception {
            System.out.println("--> getAsBoolean(6)");
            if(temp == 1){  // 满足条件,停止重新订阅
                return true;
            }
            return false;
        }
    }).subscribe(new Observer<Integer>() {
        @Override
        public void onSubscribe(Disposable d) {
            System.out.println("--> onSubscribe(6)");
        }

        @Override
        public void onNext(Integer integer) {
            System.out.println("--> onNext(6): " + integer);
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("--> onError(6): " + e);
        }

        @Override
        public void onComplete() {
            System.out.println("--> onCompleted(6)");
        }
    });


    System.out.println("---------------------------------------------");
    temp = 0;
    /**
     * 7. retryWhen(Function<Observable<Throwable>, ObservableSource> handler)
     *  将onError中的Throwable传递给一个函数handler,这个函数产生另一个Observable,
     *  retryWhen观察它的结果再决定是不是要重新订阅原始的Observable。
     *  如果这个Observable发射了一项数据,它就重新订阅,
     *  如果这个Observable发射的是onError通知,它就将这个通知传递给观察者然后终止。
     */
    observable.doOnSubscribe(new Consumer<Disposable>() {
        @Override
        public void accept(Disposable disposable) throws Exception {
            System.out.println("----> doOnSubscribe(7)");
        }
    }).retryWhen(new Function<Observable<Throwable>, ObservableSource<?>>() {
        @Override
        public ObservableSource<?> apply(Observable<Throwable> throwableObservable) throws Exception {
            System.out.println("--> apply(7)");
            // 根据产生的Error的Observable是否正常发射数据来进行重新订阅,如果发射Error通知,则直接传递给观察者后终止
            return throwableObservable.flatMap(new Function<Throwable, ObservableSource<?>>() {
                @Override
                public ObservableSource<?> apply(Throwable throwable) throws Exception {
                    if (temp == 1) {
                        return Observable.error(throwable); // 满足条件后,传递这个Error,终止重新订阅
                    }
                    return Observable.timer(1, TimeUnit.MILLISECONDS);  // 正常发射数据,可以重新订阅
                }
            });
        }
    }).subscribe(new Observer<Integer>() {
        @Override
        public void onSubscribe(Disposable d) {
            System.out.println("--> onSubscribe(7)");
        }

        @Override
        public void onNext(Integer integer) {
            System.out.println("--> onNext(7): " + integer);
        }

        @Override
        public void onError(Throwable e) {
            System.out.println("--> onError(7): " + e);
        }

        @Override
        public void onComplete() {
            System.out.println("--> onCompleted(7)");
        }
    });

    System.in.read();

输出:

----> doOnSubscribe(1)
--> accept(1): 1
--> accept(1): 2
----> doOnSubscribe(1)
--> accept(1): 1
--> accept(1): 2
----> doOnSubscribe(1)
--> accept(1): 1
--> accept(1): 2
----> doOnSubscribe(1)
--> accept(1): 1
--> accept(1): 2
--> accept(1): 3
--> accept(1): 4
---------------------------------------------
--> onSubscribe(2)
----> doOnSubscribe(2)
--> onNext(2): 1
--> onNext(2): 2
----> doOnSubscribe(2)
--> onNext(2): 1
--> onNext(2): 2
--> onError(2): java.lang.Exception: Test Error!
---------------------------------------------
--> onSubscribe(3)
----> doOnSubscribe(3)
--> onNext(3): 1
--> onNext(3): 2
--> test(3)
----> doOnSubscribe(3)
--> onNext(3): 1
--> onNext(3): 2
--> test(3)
----> doOnSubscribe(3)
--> onNext(3): 1
--> onNext(3): 2
--> onError(3): java.lang.Exception: Test Error!
---------------------------------------------
--> onSubscribe(4)
----> doOnSubscribe(4)
--> onNext(4): 1
--> onNext(4): 2
----> doOnSubscribe(4)
--> onNext(4): 1
--> onNext(4): 2
----> doOnSubscribe(4)
--> onNext(4): 1
--> onNext(4): 2
----> doOnSubscribe(4)
--> onNext(4): 1
--> onNext(4): 2
--> onNext(4): 3
--> onNext(4): 4
---------------------------------------------
--> onSubscribe(5)
----> doOnSubscribe(5)
--> onNext(5): 1
--> onNext(5): 2
--> test(5): 1
----> doOnSubscribe(5)
--> onNext(5): 1
--> onNext(5): 2
--> test(5): 2
----> doOnSubscribe(5)
--> onNext(5): 1
--> onNext(5): 2
--> test(5): 3
----> doOnSubscribe(5)
--> onNext(5): 1
--> onNext(5): 2
--> onNext(5): 3
--> onNext(5): 4
---------------------------------------------
--> onSubscribe(6)
----> doOnSubscribe(6)
--> onNext(6): 1
--> onNext(6): 2
--> getAsBoolean(6)
----> doOnSubscribe(6)
--> onNext(6): 1
--> onNext(6): 2
--> getAsBoolean(6)
--> onError(6): java.lang.Exception: Test Error!
---------------------------------------------
--> apply(7)
--> onSubscribe(7)
----> doOnSubscribe(7)
--> onNext(7): 1
--> onNext(7): 2
----> doOnSubscribe(7)
--> onNext(7): 1
--> onNext(7): 2
--> onError(7): java.lang.Exception: Test Error!

Javadoc: retry()
Javadoc: retry(long times)
Javadoc: retry(long times, Predicate<Throwable> predicate)
Javadoc: retry(Predicate<Throwable> predicate)
Javadoc: retry(BiPredicate<Integer, Throwable> predicate)
Javadoc: retryUntil(BooleanSupplier stop)
Javadoc: retryWhen(Function<Observable<Throwable>, ObservableSource> handler)

小结

本节主要介绍了 Rxjava 中关于 Error 通知的处理,主要是在遇到异常通知时,无条件或者指定条件的去重新订阅原始 Observable 直到没有异常(正常发射所有数据序列)或者满足指定的条件后终止重新订阅,发射异常通知给观察者。

提示:以上使用的Rxjava2版本: 2.2.12

Rx介绍与讲解及完整目录参考:Rxjava2 介绍与详解实例

实例代码:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容