Observable.take()导致NPE

时间:2017-05-01 20:05:32

标签: java rx-java rx-java2

我有一个像这样的简单程序:

public class MainApp {
    public static void main(String[] args) {
        getAcronyms()
                .flatMap(Observable::fromIterable)
                .flatMap(MainApp::getTitle)
                .filter(Objects::nonNull)
                .subscribe(System.out::println);

    }

    private static Observable<List<String>> getAcronyms(){
        List<String> strings = new ArrayList<>();
        strings.add("YOLO");
        strings.add("LMAO");
        strings.add("ROFL");
        strings.add("AYY LMAO");
        return new Observable<List<String>>() {
            @Override
            protected void subscribeActual(Observer<? super List<String>> observer) {
                observer.onNext(strings);
                observer.onComplete();
            }
        };
    }

    private static Observable<String> getTitle(String url) {
        return new Observable<String>() {
            @Override
            protected void subscribeActual(Observer<? super String> observer) {
                observer.onNext(url + " title!");
                observer.onComplete();
            }
        };
    }
}

这很好用,但当我链接take

getAcronyms()
        .flatMap(Observable::fromIterable)
        .flatMap(MainApp::getTitle)
        .filter(Objects::nonNull)
        .take(2)
        .subscribe(System.out::println);

它打印出2个值但给我一个NPE:

  

YOLO冠军!

     

LMAO冠军!

     

线程中的异常&#34; main&#34; java.lang.NullPointerException at   io.reactivex.internal.operators.observable.ObservableTake $ TakeObserver.onComplete(ObservableTake.java:83)     在   io.reactivex.internal.operators.observable.ObservableTake $ TakeObserver.onNext(ObservableTake.java:64)     在   io.reactivex.internal.operators.observable.ObservableFilter $ FilterObserver.onNext(ObservableFilter.java:52)     在   io.reactivex.internal.operators.observable.ObservableFlatMap $ MergeObserver.tryEmit(ObservableFlatMap.java:262)     在   io.reactivex.internal.operators.observable.ObservableFlatMap $ InnerObserver.onNext(ObservableFlatMap.java:559)     在MainApp $ 2.subscribeActual(MainApp.java:41)at   io.reactivex.Observable.subscribe(Observable.java:10842)at   io.reactivex.internal.operators.observable.ObservableFlatMap $ MergeObserver.subscribeInner(ObservableFlatMap.java:162)     在   io.reactivex.internal.operators.observable.ObservableFlatMap $ MergeObserver.onNext(ObservableFlatMap.java:139)     在   io.reactivex.internal.operators.observable.ObservableFlatMap $ MergeObserver.drainLoop(ObservableFlatMap.java:436)     在   io.reactivex.internal.operators.observable.ObservableFlatMap $ MergeObserver.drain(ObservableFlatMap.java:323)     在   io.reactivex.internal.operators.observable.ObservableFlatMap $ InnerObserver.onSubscribe(ObservableFlatMap.java:546)     在   io.reactivex.internal.operators.observable.ObservableFromIterable.subscribeActual(ObservableFromIterable.java:55)     在io.reactivex.Observable.subscribe(Observable.java:10842)at   io.reactivex.internal.operators.observable.ObservableFlatMap $ MergeObserver.subscribeInner(ObservableFlatMap.java:162)     在   io.reactivex.internal.operators.observable.ObservableFlatMap $ MergeObserver.onNext(ObservableFlatMap.java:139)     在MainApp $ 1.subscribeActual(MainApp.java:31)at   io.reactivex.Observable.subscribe(Observable.java:10842)at   io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55)     在io.reactivex.Observable.subscribe(Observable.java:10842)at   io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55)     在io.reactivex.Observable.subscribe(Observable.java:10842)at   io.reactivex.internal.operators.observable.ObservableFilter.subscribeActual(ObservableFilter.java:30)     在io.reactivex.Observable.subscribe(Observable.java:10842)at   io.reactivex.internal.operators.observable.ObservableTake.subscribeActual(ObservableTake.java:30)     在io.reactivex.Observable.subscribe(Observable.java:10842)at   io.reactivex.Observable.subscribe(Observable.java:10828)at   io.reactivex.Observable.subscribe(Observable.java:10731)at   MainApp.main(MainApp.java:18)

有人可以帮助我弄清楚为什么会发生这种情况以及我做错了什么?

1 个答案:

答案 0 :(得分:2)

由于take在发出定义数量的项目后发生此异常,因此在内部尝试处置未设置的Disposable对象。

因此,您必须通过在Observable方法实现中调用observer.onSubscribe(disposable)来创建初始subscribeActual时提供它。但是,不要重新发明轮子,而且通过调用其公共构造函数创建Observable是为了自定义运算符。只需使用静态工厂方法。在您的情况下,最好的选择是Observable.fromCallable

private static Observable<List<String>> getAcronyms(){
    return Observable.fromCallable(new Callable<List<String>>() {
        @Override
        public List<String> call() throws Exception {
            List<String> strings = new ArrayList<>();
            strings.add("YOLO");
            strings.add("LMAO");
            strings.add("ROFL");
            strings.add("AYY LMAO");
            return strings;
        }
    });
}

另请查看此文章:RxJava 2 Disposable -  Under the hood