RxJava2.x是一个非常棒的流式编程,采用的观察者模式思想,事件的产生者产生事间之后发送给绑定的接受者,接受顺序与发送顺序一致.但是 是独立于RxJava1.x存在,本文讲解RxJava2.x的简单使用


RxJava2 封装主要变化

  • Transformer的变化:RxJava1.X为rx.Observable.Transformer接口, 继承自Func1<Observable<T>, Observable<R>>, RxJava2.X为io.reactivex.ObservableTransformer<Upstream, Downstream>,是一个独立的接口。
  • Flowable则是FlowableTransformer,如果你使用Flowable,以下ObservableTransformer替换FlowableTransformer即可。


compile 'io.reactivex.rxjava2:rxjava:2.1.0'
  compile 'io.reactivex.rxjava2:rxandroid:2.0.1'


简单使用:

//观察者模式,这里产生事件,事件产生后发送给接受者,但是一定要记得将事件的产生者和接收者捆绑在一起,否则会出现错误
Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> e) throws Exception {
        //这里调用的方法会在产生事件之后会发送给接收者,接收者对应方法会收到
        e.onNext("hahaha");
        e.onError(new Exception("wulala"));
        e.onComplete();
    }}).subscribe(new Observer<String>() {
    //接受者,根据事件产生者产生的事件调用不同方法
    @Override
    public void onSubscribe(Disposable d) {
        Log.e(TAG, "onSubscribe: ");
    }

    @Override
    public void onNext(String value) {
        Log.e(TAG, "onNext: " + value);
    }

    @Override
    public void onError(Throwable e) {
        Log.e(TAG, "onError: ", e);
    }

    @Override
    public void onComplete() {
        Log.e(TAG, "onComplete: ");
    }
});
//观察者模式,这里产生事件,事件产生后发送给接受者,但是一定要记得将事件的产生者和接收者捆绑在一起,否则会出现错误
Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> e) throws Exception {
        //这里调用的方法会在产生事件之后会发送给接收者,接收者对应方法会收到
        e.onNext("hahaha");
        e.onError(new Exception("wulala"));
        e.onComplete();
    }}).subscribe(new Observer<String>() {
    //接受者,根据事件产生者产生的事件调用不同方法
    @Override
    public void onSubscribe(Disposable d) {
        Log.e(TAG, "onSubscribe: ");
    }

    @Override
    public void onNext(String value) {
        Log.e(TAG, "onNext: " + value);
    }

    @Override
    public void onError(Throwable e) {
        Log.e(TAG, "onError: ", e);
    }

    @Override
    public void onComplete() {
        Log.e(TAG, "onComplete: ");
    }
});

我们来用图解一下这其中发生了什么事:




rxjava throttleFirst 使用_ide

Paste_Image.png


上游朝下游发送数据,经过subscribe使上下游产生关系,即达成订阅.

解析1:
ObservableEmitter,这是个啥东西?Emitter:顾名思义,即Rxjava的发射器,通过这个发射器,即可发送事件-----通过调用onNext,onError,onComplete方法发送不同事件.

注意:
虽然RxJava可以进行事件发送,但这并不意味着你可以随便发送,这其中需要遵循一些规则.


onNext:你可以发送无数个onNext,发送的每个onNext接受者都会接收到.


onError:当发送了onError事件之后,发送者onError之后的事件依旧会继续发送,但是接收者当接收到onError之后就会停止接收事件了.


onComplete:当发送了onComplete事件之后,发送者的onComplete之后的事件依旧会继续发送,但是接收者接收到onComplete之后就停止接收事件了.


onError事件和onComplete事件是互斥的,但是这并不代表你配置了多个onError和onComplete一定会崩溃,多个onComplete是可以正常运行的,但是只会接收到第一个,之后的就不会再接收到了,多个onError时,只会接收到第一个,第二个会直接造成程序崩溃.



解析2:
Disposable又是个啥东西,翻译之后百度告诉我这东西叫做一次性的,是用来控制发送者和接受者之间的纽带的,默认为false,表示发送者和接受者直接的通信阀门关闭,可以正常通信,在调用dispose()方法之后,阀门开启,会阻断发送者和接收者之间的通信,从而断开连接.

重载方法:

subscribe();          //表示发送者随意发送数据,接受者什么都不管,什么都不接收.
          subscribe(Consumer<? super T> onNext) {}     //只响应onNext()事件,其他的事件忽略.
          subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError) {}         //含义同上
          subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete) {}         //含义同上
          subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError, Action onComplete, Consumer<? super Disposable> onSubscribe) {}     //含义同上



解析3:
默认情况下,发送者和接收者都运行在主线程,但是这显然是不符合实际需求的,我们在日常使用中,通常用的最多的就是在子线程进行各种耗时操作,然后发送到主线程进行,难道我们就没有办法继续用这个优秀的库了?想多了你,一个优秀的库如果连这都想不到,怎么能被称为优秀呢,RxJava中有线程调度器,通过线程调度器,我们可以很简单的实现这种效果,下面放代码.

Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> e) throws Exception {
        e.onNext("hahaha");
        e.onNext("hahaha");
        e.onNext("hahaha");
        Log.e(TAG,"运行在什么线程" + Thread.currentThread().getName());
        e.onComplete();
    }
}).subscribeOn(Schedulers.newThread())               //线程调度器,将发送者运行在子线程
  .observeOn(AndroidSchedulers.mainThread())          //接受者运行在主线程
  .subscribe(new Observer<String>() {
    @Override
    public void onSubscribe(Disposable d) {
        Log.e(TAG, "onSubscribe: ");
        Log.e(TAG,"接收在什么线程" + Thread.currentThread().getName());
    }

    @Override
    public void onNext(String value) {
        Log.e(TAG, "onNext: " + value);
    }

    @Override
    public void onError(Throwable e) {
        Log.e(TAG, "onError: ", e);
    }

    @Override
    public void onComplete() {
        Log.e(TAG, "onComplete: ");
    }
});
Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> e) throws Exception {
        e.onNext("hahaha");
        e.onNext("hahaha");
        e.onNext("hahaha");
        Log.e(TAG,"运行在什么线程" + Thread.currentThread().getName());
        e.onComplete();
    }
}).subscribeOn(Schedulers.newThread())               //线程调度器,将发送者运行在子线程
  .observeOn(AndroidSchedulers.mainThread())          //接受者运行在主线程
  .subscribe(new Observer<String>() {
    @Override
    public void onSubscribe(Disposable d) {
        Log.e(TAG, "onSubscribe: ");
        Log.e(TAG,"接收在什么线程" + Thread.currentThread().getName());
    }

    @Override
    public void onNext(String value) {
        Log.e(TAG, "onNext: " + value);
    }

    @Override
    public void onError(Throwable e) {
        Log.e(TAG, "onError: ", e);
    }

    @Override
    public void onComplete() {
        Log.e(TAG, "onComplete: ");
    }
});

注意事项: 变换线程方法与1.x一致
subscribeOn(),只有在第一次调用的时候生效,之后不管调用多少次,只会以第一次为准.
observeOn(),可以被调用多次,每次调用都会更改线程.

RxJava线程池中的几个线程选项

- Schedulers.io()      io操作的线程, 通常io操作,如文件读写.
      - Schedulers.computation()      计算线程,适合高计算,数据量高的操作.
      - Schedulers.newThread()      创建一个新线程,适合子线程操作.
      - AndroidSchedulers.mainThread()      Android的主线程,主线程

操作符之变换

Map:



首先是变换操作符- > Map,(此处引入以前看过的一篇文章的一句话:不知道Map已经统治世界了么?)那么在RxJava2中,Map究竟是个什么鬼.
map是RxJava中最简单的一个变换操作符,它的作用是将上游发送过来的事件都去应用一个函数,让每一个事件都按照该函数去变化,下游接收到事件时,就变成了变化过后的事件,多说无益,上代码.

Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> e) throws Exception {
            e.onNext(1);
            e.onNext(2);
            e.onNext(3);
        }
    }).map(new Function<Integer, String>() {
        @Override
        public String apply(Integer integer) throws Exception {
            return "我是变换过后的" + integer;
        }
    }).subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            Log.e("XYK",s);
        }
    });
}

通过运行结果可以看到,我们在上游发送的数据类型为Integer,到了下游接收到的数据为String类型,中间通过map对其进行了转换,是不是感觉很强大?通过map我们可以将上游数据转化为任意类型发送到下游,就是这么6~

圆形事件1,2,3,经过Map转化之后,变成了三角形事件1,2,3,但是有童鞋要问了,这有什么用呢,我们来举一个实际需求的例子,用Map来做一下:

读取一篇英文文章,将文章中的字符全部转换为大写.

我们先来用非RxJava2来做一下:

//模拟一篇文章
String article = "fkjdsalijfofldaJFOIEjfldanlJR2OnfldajilwafkndaIUPO32,LFKjlijuJFLMA";
        char[] chars = article.toCharArray();

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < chars.length; i++) {
            Log.e(TAG,chars[i] + "");
            if(chars[i] >= 'a' && chars[i] <= 'z'){
                sb.append((chars[i] + "").toUpperCase());
            }else{
                sb.append(chars[i]);
            }
        }

        Log.e(TAG,sb.toString());
//模拟一篇文章
String article = "fkjdsalijfofldaJFOIEjfldanlJR2OnfldajilwafkndaIUPO32,LFKjlijuJFLMA";
        char[] chars = article.toCharArray();

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < chars.length; i++) {
            Log.e(TAG,chars[i] + "");
            if(chars[i] >= 'a' && chars[i] <= 'z'){
                sb.append((chars[i] + "").toUpperCase());
            }else{
                sb.append(chars[i]);
            }
        }

        Log.e(TAG,sb.toString());

好像看上去没什么问题,但是这逼格显然不够高,程序员的精髓不就是要敲出一段逼格超高的代码么,我们试试用RxJava2:

//模拟一篇文章
        String article = "fkjdsalijfofldaJFOIEjfldanlJR2OnfldajilwafkndaIUPO32,LFKjlijuJFLMA";

        final char[] chars = article.toCharArray();
        Observable.create(new ObservableOnSubscribe<Character>() {
            @Override
            public void subscribe(ObservableEmitter<Character> e) throws Exception {
                for (int i = 0; i < chars.length; i++) {
                    e.onNext(chars[i]);
                }
            }
            //delay  延时5秒发送
        }).delay(5, TimeUnit.SECONDS)
                //事件类型转换
                .map(new Function<Character, String>() {
                    @Override
                    public String apply(Character s) throws Exception {
                        if (s >= 'a' && s <= 'z') {
                            return s.toString().toUpperCase();
                        } else {
                            return s.toString();
                        }
                    }
                })
                //线程调度
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String s) throws Exception {
                        Log.e(TAG, s);
                    }
                });
//模拟一篇文章
        String article = "fkjdsalijfofldaJFOIEjfldanlJR2OnfldajilwafkndaIUPO32,LFKjlijuJFLMA";

        final char[] chars = article.toCharArray();
        Observable.create(new ObservableOnSubscribe<Character>() {
            @Override
            public void subscribe(ObservableEmitter<Character> e) throws Exception {
                for (int i = 0; i < chars.length; i++) {
                    e.onNext(chars[i]);
                }
            }
            //delay  延时5秒发送
        }).delay(5, TimeUnit.SECONDS)
                //事件类型转换
                .map(new Function<Character, String>() {
                    @Override
                    public String apply(Character s) throws Exception {
                        if (s >= 'a' && s <= 'z') {
                            return s.toString().toUpperCase();
                        } else {
                            return s.toString();
                        }
                    }
                })
                //线程调度
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String s) throws Exception {
                        Log.e(TAG, s);
                    }
                });

瞬间逼格就上去了,而且还做了线程调度等操作,是不是心头顿时感觉一串666飘过,这仅仅是最基础的转化操作符,接下来我们在看一个FlatMap:

FlatMap

FlatMap,上来就看到map,这个操作符和刚才的map有什么区别呢,flatmap可以将上游发送过来的数据,变换为多个数据,然后合并为一个事件发送到下游,这么说是不是有点难懂?恩,还是直接上代码:

Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> e) throws Exception {
            e.onNext(1);
            e.onNext(2);
            e.onNext(3);
        }
    }).flatMap(new Function<Integer, ObservableSource<String>>() {
        @Override
        public ObservableSource<String> apply(Integer integer) throws Exception {
            List<String> list = new ArrayList<String>();
            for (int i = 0; i < 5; i++) {
                list.add("我是变换过的" + integer);
            }
            return Observable.fromIterable(list);
        }
    }).subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            Log.e("XYK", s);
        }
    });
}
Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> e) throws Exception {
            e.onNext(1);
            e.onNext(2);
            e.onNext(3);
        }
    }).flatMap(new Function<Integer, ObservableSource<String>>() {
        @Override
        public ObservableSource<String> apply(Integer integer) throws Exception {
            List<String> list = new ArrayList<String>();
            for (int i = 0; i < 5; i++) {
                list.add("我是变换过的" + integer);
            }
            return Observable.fromIterable(list);
        }
    }).subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            Log.e("XYK", s);
        }
    });
}

通过运行结果可以看到,上游发送的数据在到达flatmap的时候,经过处理,将每个事件变成了5个,而后将5个合并为1个事件发送到下游,并且我们可以注意到,发送到下游的数据是无序的,那么这时候就要说了,我要接收的事件是有序的怎么办,这就是接下来要说的concatMap.

ConcatMap:



ConcatMap和FlatMap一样,只不过一个是有序,一个是无序而已,我们直接把上边的代码做一个更改:

Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> e) throws Exception {
            e.onNext(1);
            e.onNext(2);
            e.onNext(3);
        }
    }).concatMap(new Function<Integer, ObservableSource<String>>() {
        @Override
        public ObservableSource<String> apply(Integer integer) throws Exception {
            List<String> list = new ArrayList<String>();
            for (int i = 0; i < 5; i++) {
                list.add("我是变换过的" + integer);
            }
            return Observable.fromIterable(list);
        }
    }).subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            Log.e("XYK", s);
        }
    });
}
Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> e) throws Exception {
            e.onNext(1);
            e.onNext(2);
            e.onNext(3);
        }
    }).concatMap(new Function<Integer, ObservableSource<String>>() {
        @Override
        public ObservableSource<String> apply(Integer integer) throws Exception {
            List<String> list = new ArrayList<String>();
            for (int i = 0; i < 5; i++) {
                list.add("我是变换过的" + integer);
            }
            return Observable.fromIterable(list);
        }
    }).subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            Log.e("XYK", s);
        }
    });
}

过滤操作符

Filter

Filter,顾名思义,过滤器,可以过滤掉一部分不符合要求的事件,当上游给我们发送的数据超多,而下游需要的只是一些特定的数据,如果全部接收上游发送的数据,很容易造成OOM,为了避免OOM的出现,我们则需要对上游数据进行过滤,具体操作如下:

Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                for (int i = 0; i < 10000; i++) {
                    e.onNext(i);
                }
            }
        }).observeOn(Schedulers.io())
                .subscribeOn(AndroidSchedulers.mainThread())
                .filter(new Predicate<Integer>() {
                    @Override
                    public boolean test(Integer integer) throws Exception {
                        return integer % 7 == 0;
                    }
                }).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                Log.e("XYK",integer + "");
            }
        });
    }
    Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                for (int i = 0; i < 10000; i++) {
                    e.onNext(i);
                }
            }
        }).observeOn(Schedulers.io())
                .subscribeOn(AndroidSchedulers.mainThread())
                .filter(new Predicate<Integer>() {
                    @Override
                    public boolean test(Integer integer) throws Exception {
                        return integer % 7 == 0;
                    }
                }).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                Log.e("XYK",integer + "");
            }
        });
    }

在上面的代码中,我们朝下游发送了10000个数据,而我只需要其中可以被7整除的数据,利用filter,将其他的数据过滤出去,留下需要的数据.

Filter方法使我们经常用到的一个过滤方法,基本已经可以满足大部分应用场所了,最常见的是过滤一些null对象,但是除此之外,还有一些其他的过滤方法,我们也来看下.

Sample

Sample,样品,其功能也是,sample会每隔一段时间对上游数据进行取样,发送到下游,但是这样会导致丢失了大量事件,比较适合特定场合,如对一组数中进行抽样,代码如下:

Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                for (int i = 0; ; i++) {
                    e.onNext(i);
                }
            }
        }).sample(1,TimeUnit.SECONDS)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.e("XYK",integer + "");
                    }
                });
    }
   Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                for (int i = 0; ; i++) {
                    e.onNext(i);
                }
            }
        }).sample(1,TimeUnit.SECONDS)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.e("XYK",integer + "");
                    }
                });
    }

在上边的代码中,使用sample之后,每隔1秒对上游数据采样一次,发送到下游,其他事件则被过滤.

take/takeList

take和takeList方法可以将上游事件中的前N项或者最后N项发送到下游,其他事件则进行过滤,代码如下:

Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                for (int i = 0; ; i++) {
                    e.onNext(i);
                }
            }
        }).take(3)
        //.takeList(3)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.e("XYK",integer + "");
                    }
                });
    }
 Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                for (int i = 0; ; i++) {
                    e.onNext(i);
                }
            }
        }).take(3)
        //.takeList(3)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.e("XYK",integer + "");
                    }
                });
    }

distinct

distinct方法,可以将重复对象去除重复对象,这里我们要用到一个方法,repeat(),产生重复事件,这里重复事件,再去除有些多余,只作为一个例子来展示.

Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                for (int i = 0;i < 50; i++) {
                    e.onNext(i);
                }
            }
        }).take(3)
                //生成重复事件
                .repeat(3)
                .distinct()
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.e("XYK",integer + "");
                    }
                });
Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                for (int i = 0;i < 50; i++) {
                    e.onNext(i);
                }
            }
        }).take(3)
                //生成重复事件
                .repeat(3)
                .distinct()
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.e("XYK",integer + "");
                    }
                });



组合操作符

zip操作符:

Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
        e.onNext(1);
        e.onNext(2);
        e.onNext(3);
        e.onNext(4);
    }
});

Observable<String> observable1 = Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> e) throws Exception {
        e.onNext("这是");
        e.onNext("这个是");
        e.onNext("这个则是");
    }
});

Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> e) throws Exception {
        e.onNext("个");
        e.onNext("只");
        e.onNext("条");
        e.onNext("张");
        e.onNext("本");
        e.onNext("副");
    }
});

Observable.zip(observable, observable1, observable2, new Function3<Integer, String, String, String>() {
    @Override
    public String apply(Integer integer, String s, String s2) throws Exception {
        return s + integer + s2;
    }
}).subscribe(new Consumer<String>() {
    @Override
    public void accept(String s) throws Exception {
        Log.e("XYK",s);
    }
});
Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
        e.onNext(1);
        e.onNext(2);
        e.onNext(3);
        e.onNext(4);
    }
});

Observable<String> observable1 = Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> e) throws Exception {
        e.onNext("这是");
        e.onNext("这个是");
        e.onNext("这个则是");
    }
});

Observable<String> observable2 = Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> e) throws Exception {
        e.onNext("个");
        e.onNext("只");
        e.onNext("条");
        e.onNext("张");
        e.onNext("本");
        e.onNext("副");
    }
});

Observable.zip(observable, observable1, observable2, new Function3<Integer, String, String, String>() {
    @Override
    public String apply(Integer integer, String s, String s2) throws Exception {
        return s + integer + s2;
    }
}).subscribe(new Consumer<String>() {
    @Override
    public void accept(String s) throws Exception {
        Log.e("XYK",s);
    }
});

运行结果:




rxjava throttleFirst 使用_ide_02

Paste_Image.png


我们可以看到,3条上游中分别有4个事件,3个事件,6个事件,经过zip操作符操作之后为什么就只变成了3个事件了呢?我们来打下Log,看看其他事件去哪了.

添加Log之后的运行结果:




rxjava throttleFirst 使用_ide_03

Paste_Image.png


根据运行结果可以看到,上游逐条发送到下游,下游在接收到最后一条上游发送过来的事件之后开始组合,而多余的数据也被发送了,但是并没有被进行组合,这样是不是就看明白了呢?但是这时候有问题了,组合完成之后,多余的数据依旧在发送,如果我们不停发呢?会产生什么后果?,我们来修改一下observable
的代码:

Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
        for (int i = 0; ; i++) {
            Log.e("XYK",i + "");
            e.onNext(i);
        }
    }
});
Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
        for (int i = 0; ; i++) {
            Log.e("XYK",i + "");
            e.onNext(i);
        }
    }
});

运行之后通过Monitors我们查看一下内存:(Sorry,这里没截下图来....可以自己试一下,不过想一下也知道,内存肯定会暴增嘛...)

在内存持续暴增的情况下,可能用不了多久就会OOM,这种情况下我们应该怎么办呢?

还记不记得上篇文章写了啥,过滤啊,我们把不需要的过滤掉不就好了

Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
        for (int i = 0; ; i++) {
            e.onNext(i);
        }
    }
}).filter(new Predicate<Integer>() {
    @Override
    public boolean test(Integer integer) throws Exception {
        return integer % 100 == 0;
    }
});
Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
        for (int i = 0; ; i++) {
            e.onNext(i);
        }
    }
}).filter(new Predicate<Integer>() {
    @Override
    public boolean test(Integer integer) throws Exception {
        return integer % 100 == 0;
    }
});

当然,除此之外还有很多办法,可以根据实际情况来进行组合应用.

RxJava中的zip操作符作用是将多条上游发送的事件进行结合到一起,发送到下游,并且按照顺序来进行结合,如多条上游中发送的事件数量不一致,则以最少的那条中的事件为准,下游接收到的事件数量和其相等.




Rxjava的2.x与1.x的区别(官翻)

Nulls

null 值,如果传入一个null会抛出 NullPointerException

Observable.just(null);

Single.just(null);

Observable.fromCallable(() -> null)
    .subscribe(System.out::println, Throwable::printStackTrace);

Observable.just(1).map(v -> null)
    .subscribe(System.out::println, Throwable::printStackTrace);

Observable<Void> 不再发射任何值,而只是正常结束或者抛出异常。API 设计者可以定义 Observable<Object> 这样的观察者, 因为并不确定具体是什么类型的 Object。例如,如果你需要一个 signaller-like ,你可以定义一个共享的枚举类型,它是一个单独的实例onNext‘d:

enum Irrelevant { INSTANCE; }

Observable<Object> source = Observable.create((ObservableEmitter<Object> emitter) -> {
   System.out.println("Side-effect 1");
   emitter.onNext(Irrelevant.INSTANCE);

   System.out.println("Side-effect 2");
   emitter.onNext(Irrelevant.INSTANCE);

   System.out.println("Side-effect 3");
   emitter.onNext(Irrelevant.INSTANCE);
});

source.subscribe(e -> { /* Ignored. */ }, Throwable::printStackTrace);

Observable 和 Flowable

Observable。 主要的背压问题是有很多很火的代码,像UI events,不能合理的背压,导致了无法意料的 MissingBackpressureExceptionio.reactivex.Observable 设计成非背压的,并增加一个新的io.reactivex.Flowableio.reactivex.Observable

Single

Single类可以发射一个单独onSuccess 或 onError消息。它现在按照Reactive-Streams规范被重新设计,SingleObserver改成了如下的接口。

interface SingleObserver<T> {
    void onSubscribe(Disposable d);
    void onSuccess(T value);
    void onError(Throwable error);
}

onSubscribe (onSuccess | onError)?.

Completable

Completable大部分和以前的一样。因为它在1.x的时候就是按照Reactive-Streams的规范进行设计的。 命名上有些变化, 

rx.Completable.CompletableSubscriber 变成了 io.reactivex.CompletableObserver 和 onSubscribe(Disposable):

interface CompletableObserver<T> {
    void onSubscribe(Disposable d);
    void onComplete();
    void onError(Throwable error);
}

onSubscribe (onComplete | onError)?.

Maybe

Maybe 。从概念上来说,它是Single 和 CompletableMaybe类结合了MaybeSourceMaybeObserver<T>作为信号接收接口,同样遵循协议onSubscribe (onSuccess | onError | onComplete)?。因为最多有一个元素被发射,Maybe没有背压的概念。onSubscribe(Disposable)请求可能还会触发其他 onXXX方法。和Flowable不同,如果那有一个单独的值要发射,那么只有onSuccess被调用,onComplete不被调用。Flowable的子类操作符一样可以发射0个或1个序列。

Maybe.just(1)
.map(v -> v + 1)
.filter(v -> v == 1)
.defaultIfEmpty(2)
.test()
.assertResult(2);

Base reactive interfaces

基础reactive接口

Flowable实现了 Publisher<T>接口,其他基础类也实现了类似的基础接口

interface ObservableSource<T> {
    void subscribe(Observer<? super T> observer);
}

interface SingleSource<T> {
    void subscribe(SingleObserver<? super T> observer);
}

interface CompletableSource {
    void subscribe(CompletableObserver observer);
}

interface MaybeSource<T> {
    void subscribe(MaybeObserver<? super T> observer);
}

Publisher 和 XSource的一些基础的类型。

Flowable<R> flatMap(Function<? super T, ? extends Publisher<? extends R>> mapper);

Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper);

Publisher作为输入,你可以组合其他的遵从Reactive-Streams规范的库,而不需要包裹或把它们转换成Flowable

如果一个操作符必须要提供一个基础类,那么用户将会收到一个完整的基础类。

Flowable<Flowable<Integer>> windows = source.window(5);

source.compose((Flowable<T> flowable) -> 
    flowable
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread()));

Subjects 和 Processors

Subject类似于行为,即消费者和提供者的事件在同一时间发生。随着Observable/Flowable的分离,支持背压的类都是遵从Reactive-Streams规范的FlowableProcessor<T>的子类。一个关于Subject重要的变化是它们不再支持T -> R这样的转换。io.reactivex.subjects.AsyncSubjectio.reactivex.subjects.BehaviorSubject,io.reactivex.subjects.PublishSubjectio.reactivex.subjects.ReplaySubject 和 io.reactivex.subjects.UnicastSubjectio.reactivex.processors.AsyncProcessorio.reactivex.processors.BehaviorProcessor,io.reactivex.processors.PublishProcessorio.reactivex.processors.ReplayProcessor 和io.reactivex.processors.UnicastProcessor 支持背压。 BehaviorProcessor 和 PublishProcessor 不能协同请求下级的订阅者,如果下游不能保存,则会发射一个MissingBackpressureException异常。其他XProcessor类支持对下游订阅者背压,但是当被订阅源时,它们会无限制的消费。

其他类

rx.observables.ConnectableObservable 现在是io.reactivex.observables.ConnectableObservable<T> 和io.reactivex.flowables.ConnectableFlowable<T>

GroupedObservable

rx.observables.GroupedObservable 现在是io.reactivex.observables.GroupedObservable<T>io.reactivex.flowables.GroupedFlowable<T>.GroupedObservable.from()创建一个实例。在2.x中,所有实例都直接继承了GroupedObservable,因此这个工厂方法不再可用; 现在整个类都是抽象的。subscribeActual行为来达到1.x中相似的功能。

class MyGroup<K, V> extends GroupedObservable<K, V> {
    final K key;

    final Subject<V> subject;

    public MyGroup(K key) {
        this.key = key;
        this.subject = PublishSubject.create();
    }

    @Override
    public T getKey() {
        return key;
    }

    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        subject.subscribe(observer);
    }
}

功能接口

1.x 和 2.x 是跑在Java 6以上的虚拟机的,所以我们不能使用Java8的功能接口(functional interfaces),比如java.util.function.Function。但我们可以按照这个例子来定义自己的功能接口(functional interfaces)。throws Exception。这对于consumers 和 mappers 来说是一个巨大的便利,你不需要用try-catch捕获异常。

Flowable.just("file.txt")
.map(name -> Files.readLines(name))
.subscribe(lines -> System.out.println(lines.size()), Throwable::printStackTrace);

IOException。你可以直接调用Files.readLines(name)而不需要捕获异常。

Actions

Action3-Action9ActionNAction0 被操作符io.reactivex.functions.ActionScheduler代替。Action1被重命名为ConsumerAction2 被重命名为BiConsumer。 ActionN 被Consumer<Object[]>

Functions

io.reactivex.functions.Function 和io.reactivex.functions.BiFunction, 把Func3 - Func9 分别改成了 Function3 - Function9 。FuncNFunction<Object[], R>代替。Func1<T, Boolean>但原始返回类型为Predicate<T>io.reactivex.functions.Functions类提供了常见的转换功能Function<Object[], R>

Subscriber

org.reactivestreams.Subscription,而不是分别用rx.Producer 和 rx.Subscription。这就可以用比1.x中rx.Subscriber更少的内部状态来创建一个stream consumers。

Flowable.range(1, 10).subscribe(new Subscriber<Integer>() {
    @Override
    public void onSubscribe(Subscription s) {
        s.request(Long.MAX_VALUE);
    }

    @Override
    public void onNext(Integer t) {
        System.out.println(t);
    }

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

    @Override
    public void onComplete() {
        System.out.println("Done");
    }
});

rx 包改成org.reactivestreams。此外org.reactivestreams.SubscriberFlowable定义了抽象类DefaultSubscriberResourceSubscriber 和 DisposableSubscriber 分别提供了类似于rx.Subscriber的资源跟踪支持,并且可以从外面取消 dispose():

ResourceSubscriber<Integer> subscriber = new ResourceSubscriber<Integer>() {
    @Override
    public void onStart() {
        request(Long.MAX_VALUE);
    }

    @Override
    public void onNext(Integer t) {
        System.out.println(t);
    }

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

    @Override
    public void onComplete() {
        System.out.println("Done");
    }
};

Flowable.range(1, 10).delay(1, TimeUnit.SECONDS).subscribe(subscriber);

subscriber.dispose();

onCompleted被重命名为onCompleteObservable.subscribe(Subscriber)返回Subscription,用户经常添加SubscriptionCompositeSubscription中,例如:

CompositeSubscription composite = new CompositeSubscription();

composite.add(Observable.range(1, 5).subscribe(new TestSubscriber<Integer>()));由于Reactive-Streams规范,Publisher.subscribe无返回值。为了弥补这一点,我们增加了E subscribeWith(E subscriber)方法。因为在2.x中ResourceSubscriber 直接实现了Disposable,所以代码可以这样写。
Publisher.subscribe
E subscribeWith(E subscriber)
ResourceSubscriber
Disposable
CompositeDisposable composite2 = new CompositeDisposable();

composite2.add(Flowable.range(1, 5).subscribeWith(subscriber));

在onSubscribe/onStart中调用request

Subscriber.onSubscribeResourceSubscriber.onStart中调用request(n)将会立即调用onNext,实例代码如下:

Flowable.range(1, 3).subscribe(new Subscriber<Integer>() {

    @Override
    public void onSubscribe(Subscription s) {
        System.out.println("OnSubscribe start");
        s.request(Long.MAX_VALUE);
        System.out.println("OnSubscribe end");
    }

    @Override
    public void onNext(Integer v) {
        System.out.println(v);
    }

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

    @Override
    public void onComplete() {
        System.out.println("Done");
    }
});

This will print: 
将会打印:

OnSubscribe start
1
2
3
Done
OnSubscribe end

onSubscribe/onStart中做了一些初始化的工作,而这些工作是在request后面时,会出现一些问题,在onNext执行时,你的初始化工作的那部分代码还没有执行。为了避免这种情况,请确保你调用request时,已经把所有初始化工作做完了。request要经过延迟的逻辑直到上游的Producer到达时。在2.x中,总是Subscription先传递下来,90%的情况下没有延迟请求的必要。

Subscription

rx.Subscription负责流和资源的生命周期管理,即退订和释放资源,例如scheduled tasks。Reactive-Streams规范用这个名称指定source和consumer之间的关系: org.reactivestreams.Subscriptionrx.Subscription被改成了 io.reactivex.Disposableorg.reactivestreams.Publisher 定义subscribe()为无返回值,Flowable.subscribe(Subscriber)不再返回任何Subscription。其他的基础类型也遵循这种规律。subscribe的重载方法返回DisposableSubscription容器类型已经被重命名和修改。CompositeSubscription

  •  改成 

CompositeDisposable

SerialSubscription

  •  和

MultipleAssignmentSubscription

  •  被合并到了 

SerialDisposable

  • 。 

set()

  •  方法取消了旧值,而

replace()

  • 方法没有。

RefCountSubscription

背压

Flowable被设计成适合下游请求,然而这个不意味着MissingBackpressureException不会出现。这个异常仍然存在。但这一次,onNext会抛出这个异常。Observable完全不支持背压,但可以被替换。

Reactive-Streams compliance

Flowable-based sources和operators是遵从Reactive-Streams 1.0.0规范的,除了一个规则§3.9和解释的规则§1.3:

§3.9: While the Subscription is not cancelled, Subscription.request(long n) MUST signal onError with a java.lang.IllegalArgumentException if the argument is <= 0. The cause message MUST include a reference to this rule and/or quote the full rule.

every operator dealing with request()) for a bug-case. RxJava 2 (and Reactor 3 in fact) reports the IllegalArgumentException to RxJavaPlugins.onError and ignores it otherwise. RxJava 2 passes the Test Compatibility Kit (TCK) by applying a custom operator that routes the IllegalArgumentException into the Subscriber.onError

§1.3: onSubscribe, onNext, onError and onComplete signaled to a Subscriber MUST be signaled sequentially (no concurrent notifications).

onSubscribe 和 onNext之间往返。也就是说在onSubscribe中,调用request(1)后将会调用onNext,在onNext返回后request(1)才会返回。虽然大部分操作符都是这样的,但操作符observeOn会异步的调用onNext,因此onSubscribe会和onNext同时被调用。这就是由TCK来检测,我们使用another operator来延迟下游请求直到onSubscribe返回。再次声明,这种异步行为不是RxJava 2的一个问题,因为在Reactor 3中操作符是线程安全的执行onSubscribe。Akka-Stream的转换类似于延迟请求。Flowable增加了一个标准的操作符,把这两种行为改到一个单独的方法。

Runtime hooks

RxJavaPlugins类,现在支持运行时改变回调。测试需要重写schedulers,生命周期方法可以通过回调函数。RxJavaObservableHook和友类现在都取消了,RxJavaHooks功能被加入到了RxJavaPlugins

Schedulers

computationionewThread 和 trampoline,可以通过io.reactivex.schedulers.Schedulers这个实用的工具类来调度。immediate 调度器。 它被频繁的误用,并没有正常的实现 Scheduler 规范;它包含用于延迟动作的阻塞睡眠,并且不支持递归调度。你可以使用Schedulers.trampoline()来代替它。Schedulers.test()已经被移除,这样避免了默认调度器休息的概念差异。那些返回一个”global”的调度器实例是鉴于test()总是返回一个新的TestScheduler实例。现在我们鼓励测试人员使用这样简单的代码new TestScheduler()io.reactivex.Scheduler抽象类现在支持直接调度任务,不需要先创建然后通过Worker调度。

public abstract class Scheduler {

    public Disposable scheduleDirect(Runnable task) { ... }

    public Disposable scheduleDirect(Runnable task, long delay, TimeUnit unit) { ... }

    public Disposable scheduleDirectPeriodically(Runnable task, long initialDelay, 
        long period, TimeUnit unit) { ... }

    public long now(TimeUnit unit) { ... }

    // ... rest is the same: lifecycle methods, worker creation
}

Worker的开销。方法有一个默认的实现,你可以直接复用 createWorkernow()被改成接受一个用于指定单位量的TimeUnit的方法。

进入reactive的世界

rx.Observable.create()方法,该方法虽然很强大,但导致了你很少使用内置典型的操作符。不幸的是,有太多的代码依赖于这个库,所以我们不能删除或重命名它。FlowableObservableSingleMaybe 和 Completable 都有安全的create操作符去支持背压和取消。

Flowable.create((FlowableEmitter<Integer> emitter) -> {
    emitter.onNext(1);
    emitter.onNext(2);
    emitter.onComplete();
}, BackpressureStrategy.BUFFER);

fromEmitter已经被重命名为Flowable.create。其他基础类型也有类似的create方法。

离开reactive的世界

SubscriberObserverSingleObserverMaybeObserver 和 CompletableObserver) 以及functional-interface 基础consumers(例如 subscribe(Consumer<T>, Consumer<Throwable>, Action)),以前在1.x中独立的BlockingObservable 已经集成了主要的基础类型。现在你可以直接调用blockingX来阻塞等待结果:

List<Integer> list = Flowable.range(1, 100).toList().blockingGet(); // toList() returns Single

Integer i = Flowable.range(100, 100).blockingLast();

rx.Subscriber 和org.reactivestreams.Subscriber重要的区别是,你的SubscriberObserver不允许抛出任何致命的异常。这意味着下面这样的代码不再是合法的:

Subscriber<Integer> subscriber = new Subscriber<Integer>() {
    @Override
    public void onSubscribe(Subscription s) {
        s.request(Long.MAX_VALUE);
    }

    public void onNext(Integer t) {
        if (t == 1) {
            throw new IllegalArgumentException();
        }
    }

    public void onError(Throwable e) {
        if (e instanceof IllegalArgumentException) {
            throw new UnsupportedOperationException();
        }
    }

    public void onComplete() {
        throw new NoSuchElementException();
    }
};

Flowable.just(1).subscribe(subscriber);

ObserverSingleObserverMaybeObserver 和 CompletableObserversafeSubscribe方法来帮助你处理这样的代码。subscribe(Consumer<T>, Consumer<Throwable>, Action)方法来提供一个回调。

Flowable.just(1)
.subscribe(
    subscriber::onNext, 
    subscriber::onError, 
    subscriber::onComplete, 
    subscriber::onSubscribe
);

Testing

Flowable可以用io.reactivex.subscribers.TestSubscriber测试,而非背压的ObservableSingle,Maybe 和 Completable可以用io.reactivex.observers.TestObserver测试。

test() “operator”

test() 方法,返回TestSubscriber 或 TestObserver:

TestSubscriber<Integer> ts = Flowable.range(1, 5).test();

TestObserver<Integer> to = Observable.range(1, 5).test();

TestObserver<Integer> tso = Single.just(1).test();

TestObserver<Integer> tmo = Maybe.just(1).test();

TestObserver<Integer> tco = Completable.complete().test();

TestSubscriber/TestObserver方法返回自身实例,这让我们可以链式调用各种assertX方法。第三个便利是,你可以流畅的测试你的代码而不需要去创建或者引入TestSubscriber/TestObserver实例。

Flowable.range(1, 5)
.test()
.assertResult(1, 2, 3, 4, 5)
;

值得注意的新的断言方法

assertResult(T... items)

  • : 断言在

onComplete

  • 中将会按指定顺序收到给定的值,并且没有错误。

assertFailure(Class<? extends Throwable> clazz, T... items)

  • : 断言将会收到指定的异常。

assertFailureAndMessage(Class<? extends Throwable> clazz, String message, T... items)

  • : 和

assertFailure

  • 一样,但还会验证 

getMessage()awaitDone(long time, TimeUnit unit)assertOf(Consumer<TestSubscriber<T>> consumer)Flowable改为Observable,所以测试代码不需要改变,内部的已经把TestSubscriber改成了TestObserver

提前取消和请求

TestObserver中的test()方法有一个 test(boolean cancel) 重载,它能在订阅前取消TestSubscriber/TestObserver:

PublishSubject<Integer> pp = PublishSubject.create();

// nobody subscribed yet
assertFalse(pp.hasSubscribers());

pp.test(true);

// nobody remained subscribed
assertFalse(pp.hasSubscribers());

TestSubscriber 有 test(long initialRequest) 和 test(long initialRequest, boolean cancel) 重载,用于指定初始请求数量以及TestSubscriber是否应该立即被取消。如果initialRequest被给定,TestSubscriber 实例通常需要被捕获以便访问request()方法:

PublishProcessor<Integer> pp = PublishProcessor.create();

TestSubscriber<Integer> ts = pp.test(0L);

ts.request(1);

pp.onNext(1);
pp.onNext(2);

ts.assertFailure(MissingBackpressureException.class, 1);

测试异步代码

对于给定的异步代码,流畅的阻塞终端事件是可能的:

Flowable.just(1)
.subscribeOn(Schedulers.single())
.test()
.awaitDone(5, TimeUnit.SECONDS)
.assertResult(1);

Mockito & TestSubscriber

Observer的用户需要去使用Subscriber.onSubscribe方法去提出初始的请求,否则序列化将会挂起或者失败:

@SuppressWarnings("unchecked")
public static <T> Subscriber<T> mockSubscriber() {
    Subscriber<T> w = mock(Subscriber.class);

    Mockito.doAnswer(new Answer<Object>() {
        @Override
        public Object answer(InvocationOnMock a) throws Throwable {
            Subscription s = a.getArgumentAt(0, Subscription.class);
            s.request(Long.MAX_VALUE);
            return null;
        }
    }).when(w).onSubscribe((Subscription)any());

    return w;}

操作符的差别

2.x中大部分操作符仍然被保留,实际上大部分行为和1.x一样。下面的列表中列出了每一个基础类的在1.x和2.x的区别

通常来说,很多操作符提供了重载,允许指定运行上游的内部缓冲区的大小或者预先分配的数量。

fromArrayfromIterable。这么做的原因是,当用Java 8编译时,javac往往不能区分功能接口类型。@Beta 或 @Experimental的操作符已经成为正式操作符了。

1.x Observable 到 2.x Flowable

工厂方法:

1.x

2.x

amb

amb(ObservableSource...)

RxRingBuffer.SIZE

bufferSize()

combineLatest

bufferSize 参数的重载, combineLatest(List)

concat

prefetch 参数的重载, 5-9 重载被删除 , 使用 concatArray

N/A

concatArray 和 concatArrayDelayError

N/A

concatArrayEager 和 concatArrayEagerDelayError

concatDelayError

增加带延时的重载

concatEagerDelayError

增加带延时的重载

create(SyncOnSubscribe)

generate

create(AsnycOnSubscribe)

不存在

create(OnSubscribe)

create(FlowableOnSubscribe, BackpressureStrategy), 支持unsafeCreate()

from

fromArrayfromIterablefromFuture

N/A

fromPublisher

fromAsync

create()

N/A

intervalRange()

limit

take

merge

prefetch的重载

mergeDelayError

prefetch的重载

sequenceEqual

bufferSize的重载

switchOnNext

prefetch的重载

switchOnNextDelayError

prefetch的重载

timer

被废弃

zip

bufferSize 和 delayErrors 的重载, 拆分成了 zipArray 和 zipIterable

实例方法:

1.x

2.x

all

RC3 返回 Single<Boolean>

any

RC3 返回 Single<Boolean>

asObservable

hide(), 隐藏所有的身份

buffer

Collection

cache(int)

被废弃

collect

RC3 返回 Single<U>

collect(U, Action2<U, T>)

collectInto 和 RC3 返回 Single<U>

concatMap

prefetch

concatMapDelayError

prefetch的重载, 支持延时

concatMapEager

prefetch的重载

concatMapEagerDelayError

prefetch的重载, 支持延时

count

RC3 返回 Single<Long>

countLong

count

distinct

Collection

doOnCompleted

doOnComplete

doOnUnsubscribe

Flowable.doOnCancel 和 doOnDispose , additional info

N/A

doOnLifecylce 来处理 onSubscriberequest 和 cancel

elementAt(int)

RC3

elementAt(Func1, int)

filter(predicate).elementAt(int)

elementAtOrDefault(int, T)

elementAt(int, T) 和 RC3 返回 Single<T>

elementAtOrDefault(Func1, int, T)

filter(predicate).elementAt(int, T)

first()

RC3 重命名为 firstElement 返回 Maybe<T>

first(Func1)

filter(predicate).first()代替

firstOrDefault(T)

first(T) RC3 返回 Single<T>

firstOrDefault(Func1, T)

filter(predicate).first(T)代替

flatMap

prefetch的重载

N/A

forEachWhile(Predicate<T>, [Consumer<Throwable>, [Action]])

groupBy

bufferSize和 delayError的重载, 支持 支持内部自定义map,RC1中没有

ignoreElements

RC3 返回 Completable

isEmpty

RC3 返回 Single<Boolean>

last()

RC3 重命名为 lastElement 返回 Maybe<T>

last(Func1)

filter(predicate).last()代替

lastOrDefault(T)

last(T) RC3 返回 Single<T>

lastOrDefault(Func1, T)

filter(predicate).last(T)代替

nest

just代替

publish(Func1)

prefetch的重载

reduce(Func2)

RC3 返回 Maybe<T>

N/A

reduceWith(Callable, BiFunction) 为了减少自定义Subscriber, 返回 Single<T>

N/A

repeatUntil(BooleanSupplier)

repeatWhen(Func1, Scheduler)

subscribeOn(Scheduler).repeatWhen(Function)

retry

retry(Predicate)retry(int, Predicate)

N/A

retryUntil(BooleanSupplier)

retryWhen(Func1, Scheduler)

subscribeOn(Scheduler).retryWhen(Function)

N/A

sampleWith(Callable, BiFunction)

single()

RC3 重命名为 singleElement 返回 Maybe<T>

single(Func1)

filter(predicate).single()代替

singleOrDefault(T)

single(T) RC3 返回 Single<T>

singleOrDefault(Func1, T)

filter(predicate).single(T)代替

skipLast

bufferSize 和 delayError

startWith

startWithArray

N/A

startWithArray

N/A

subscribeWith

switchMap

prefetch

switchMapDelayError

prefetch

takeLastBuffer

被删除

N/A

test()

timeout(Func0<Observable>, ...)

timeout(Publisher, ...) 删除了方法, 如果有需要,使用defer(Callable<Publisher>>)

toBlocking().y

blockingY() 操作符, 除了 toFuture

toCompletable

RC3 被删除, 使用 ignoreElements代替

toList

RC3 返回 Single<List<T>>

toMap

RC3 返回 Single<Map<K, V>>

toMultimap

RC3 返回 Single<Map<K, Collection<V>>>

N/A

toFuture

N/A

toObservable

toSingle

RC3 被删除, 使用 single(T)代替

toSortedList

RC3 增加 Single<List<T>>

withLatestFrom

5-9 个参数的重载被删除

zipWith

prefetch 和 delayErrors

不同的返回类型

Single

操作符

旧返回值

新返回值

备注

all(Predicate)

Observable<Boolean>

Single<Boolean>

如果所有的元素都匹配,则发射true

any(Predicate)

Observable<Boolean>

Single<Boolean>

如果所有的元素都匹配,则发射true

count()

Observable<Long>

Single<Long>

计算序列中元素的数量

elementAt(int)

Observable<T>

Maybe<T>

Emits 给定位置处的元素或完成的元素

elementAt(int, T)

Observable<T>

Single<T>

发射指定位置的元素或默认元素

first(T)

Observable<T>

Single<T>

NoSuchElementException

firstElement()

Observable<T>

Maybe<T>

发射第一个元素或者结束

ignoreElements()

Observable<T>

Completable

忽略所有非终端事件

isEmpty()

Observable<Boolean>

Single<Boolean>

如果源为空,则发射true

last(T)

Observable<T>

Single<T>

发射最后一个元素或默认值

lastElement()

Observable<T>

Maybe<T>

发射最后一个元素或结束

reduce(BiFunction)

Observable<T>

Maybe<T>

发射减少的值或者结束

reduce(Callable, BiFunction)

Observable<U>

Single<U>

发射减少的值或者初始的值

reduceWith(U, BiFunction)

Observable<U>

Single<U>

发射减少的值或者初始的值

single(T)

Observable<T>

Single<T>

发射唯一的元素或默认值

singleElement()

Observable<T>

Maybe<T>

发射唯一的元素或结束

toList()

Observable<List<T>>

Single<List<T>>

List

toMap()

Observable<Map<K, V>>

Single<Map<K, V>>

Map

toMultimap()

Observable<Map<K, Collection<V>>>

Single<Map<K, Collection<V>>>

Map

toSortedList()

Observable<List<T>>

Single<List<T>>

List

移除

为了保证最终的2.0API尽可能干净,我们删除了一些候选的方法和组件。

删除时的版本

组件

备注

RC3

Flowable.toCompletable()

Flowable.ignoreElements()代替

RC3

Flowable.toSingle()

Flowable.single(T)代替

RC3

Flowable.toMaybe()

Flowable.singleElement()代替

RC3

Observable.toCompletable()

Observable.ignoreElements()代替

RC3

Observable.toSingle()

Observable.single(T)代替

RC3

Observable.toMaybe()

Observable.singleElement()代替

其他改变

doOnCancel/doOnDispose/unsubscribeOn

doOnUnsubscribe总是执行终端事件,因为SafeSubscriber调用了unsubscribe。这实际上是没有必要的。Reactive-Streams规范中,一个终端事件到达Subscriber,上游的Subscription会取消,因此调用 cancel()是一个空操作。unsubscribeOn也没被在终端路径上调用,但只有实际在链上调用cancel时,才会调用unsubscribeOn。 因此,下面的序列不会被调用 

doOnCancel:

Flowable.just(1, 2, 3)
.doOnCancel(() -> System.out.println("Cancelled!"))
.subscribe(System.out::println);

take操作符在传送过程中取消onNext

Flowable.just(1, 2, 3)
.doOnCancel(() -> System.out.println("Cancelled!"))
.take(2)
.subscribe(System.out::println);

using操作符代替。