Rxjava2的学习与总结

本文出自Zone的博客,如需转载请标明出处,尊重原创谢谢 博客地址:https://luhaoaimama1.github.io/2017/07/31/rxjava/

Rxjava2基础认知

  • 形式正确的有限Observable 调用观察者的onCompleted正好一次或者它的onError正好一次,而且此后不能再调用观察者的任何其它方法。如果onComplete 或者 onError 走任何一个 都会 主动解除订阅关系;

    • 如果解除订阅关系以后在发射 onError 则会 报错;而发射onComplete则不会。
    • 注意解除订阅关系 还是可以发射 onNext
  • Disposable类:

    • dispose():主动解除订阅
    • isDisposed():查询是否解除订阅 true 代表 已经解除订阅
  • CompositeDisposable类:可以快速解除所有添加的Disposable类 每当我们得到一个Disposable时就调用CompositeDisposable.add()将它添加到容器中, 在退出的时候, 调用CompositeDisposable.clear() 即可快速解除.
  
  
  1. CompositeDisposable compositeDisposable=new CompositeDisposable();
  2. Observable.create(new ObservableOnSubscribe<Integer>() {
  3. @Override
  4. public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
  5. emitter.onNext(1);
  6. emitter.onComplete();或者 emitter.onError(new Throwable("O__O "));
  7. }
  8. }).subscribe(new Observer<Integer>() {
  9. private Disposable mDisposable;
  10. @Override
  11. public void onSubscribe(Disposable d) {
  12. <!-- 订阅 -->
  13. mDisposable = d;
  14. <!-- 添加到容器中 -->
  15. compositeDisposable.add(d);
  16. }
  17. @Override
  18. public void onNext(Integer value) {
  19. <!-- 判断mDisposable.isDisposed() 如果解除了则不需要处理 -->
  20. }
  21. @Override
  22. public void onError(Throwable e) {
  23. }
  24. @Override
  25. public void onComplete() {
  26. }
  27. });
  28. <!-- 解除所有订阅者 -->
  29. compositeDisposable.clear();

基础概念

  • Scheduler scheduler

timer() alt+点击timer可查看 关于timer的方法 可以看到时候有这个参数的变体!

  • Callable bufferSupplier:自定义装载的容器
  
  
  1. Observable.range(1, 10)
  2. //() -> new ArrayList<>() 则是bufferSupplier
  3. .buffer(2, 1,() -> new ArrayList<>())
  4. .subscribe(integers -> System.out.println(integers));

创建操作

  • create : 创建一个具有发射能力的Observable
  
  
  1. Observable.create(e -> {
  2. e.onNext("Love");
  3. e.onNext("For");
  4. e.onNext("You!");
  5. e.onComplete();
  6. }).subscribe(s -> System.out.println(s));
  • just:只是简单的原样发射,可将数组或Iterable当做单个数据。它接受一至九个参数
  
  
  1. Observable.just("Love", "For", "You!")
  2. .subscribe(s -> System.out.println(s));
  • empty:创建一个不发射任何数据但是正常终止的Observable
  • never:创建一个不发射数据也不终止的Observable
  • error:创建一个不发射数据以一个错误终止的Observable
  
  
  1. Observable.empty();
  2. Observable.never();
  3. Observable.error(new Throwable("O__O"))
  • timer 在延迟一段给定的时间后发射一个简单的数字0
  
  
  1. Observable.timer(1000, TimeUnit.MILLISECONDS)
  2. .subscribe(s -> System.out.println(s));
  • range:
    • start:起始值
    • count:一个是范 围的数据的数目。0不发送 ,负数 异常
  
  
  1. Observable.range(5, 3)
  2. //输出 5,6,7
  3. .subscribe(s -> System.out.println(s));
  • intervalRange
    • start,count:同range
    • initialDelay 发送第一个值的延迟时间
    • period 每两个发射物的间隔时间
    • unit,scheduler 额你懂的
  
  
  1. Observable.intervalRange(5, 100, 3000, 100,
  2. TimeUnit.MILLISECONDS, Schedulers.io())
  3. .subscribe(s -> System.out.println(s));
  • interval:相当于intervalRange的start=0;

    period 这个值一旦设定后是不可变化的

  
  
  1. //period 以后的美每次间隔 这个值一旦设定后是不可变化的 所以 count方法无效的!
  2. int[] s = new int[]{0};
  3. Observable.interval(3000, 100 + count(s), TimeUnit.MILLISECONDS, Schedulers.io())
  4. .subscribe(s2 -> System.out.println(s2));
  5. private int count(int[] s) {
  6. int result = s[0] * 1000;
  7. s[0] = s[0] + 1;
  8. return result;
  9. }
  • defer 直到有观察者订阅时才创建Observable,并且为每个观察者创建一个新的Observable
  
  
  1. Observable.defer(() -> Observable.just("Love", "For", "You!"))
  2. .subscribe(s -> System.out.println(s));
  • from系列
    • fromArray
            
            
      1. Integer[] items = {0, 1, 2, 3, 4, 5};
      2. Observable.fromArray(items).subscribe(
      3. integer -> System.out.println(integer));
    • fromCallable
            
            
      1. Observable.fromCallable(() -> Arrays.asList("hello", "gaga"))
      2. .subscribe(strings -> System.out.println(strings))
    • fromIterable
            
            
      1. Observable.fromIterable(Arrays.<String>asList("one", "two", "three"))
      2. .subscribe(integer -> System.out.println(integer));
    • fromFuture
            
            
      1. Observable.fromFuture(Observable.just(1).toFuture())
      2. .doOnComplete(() -> System.out.println("complete"))
      3. .subscribe();

过滤操作

  • elementAt:只发射第N项数据
  
  
  1. <!-- 无默认值版本 -->
  2. Observable.just(1,2)
  3. .elementAt(0)
  4. .subscribe(o -> System.out.print(o ));//结果:1
  5. <!-- 带默认值的变体版本 -->
  6. Observable.range(0, 10)
  7. // 如果索引值大于数据 项数,它会发射一个默认值(通过额外的参数指定),而不是抛出异常。
  8. // 但是如果你传递一 个负数索引值,它仍然会抛出一个 IndexOutOfBoundsException 异常。
  9. .elementAt(100, -100)
  10. .subscribe(o -> System.out.print(o + "t"));
  • IgnoreElements:如果你不关心一个Observable发射的数据,但是希望在它完成时或遇到错误终止时收到通知

        
        
    1. Observable.range(0, 10)
    2. .ignoreElements()
    3. .subscribe(() -> System.out.println("complete")
    4. , throwable -> System.out.println("throwable"));
  • take系列

    • 变体 count系列:只发射前面的N项数据
        
        
    1. Observable.range(0,10)
    2. .take(3)
    3. .subscribe(o -> System.out.print(o + "t"))
    • 变体 time系列: 发射Observable开始的那段时间发射 的数据,
        
        
    1. Observable.range(0,10)
    2. .take(100, TimeUnit.MILLISECONDS)
    3. .subscribe(o -> System.out.print(o + "t"));
  • takeLast

    • 变体 count系列:只发射后面的N项数据
        
        
    1. Observable.range(0,10)
    2. .takeLast(3)
    3. .subscribe(o -> System.out.print(o + "t"));
    • 变体 time系列: 发射在原始Observable的生命周 期内最后一段时间内发射的数据
        
        
    1. Observable.range(0,10)
    2. .takeLast(100, TimeUnit.MILLISECONDS)
    3. .subscribe(o -> System.out.print(o + "t"));
  • takeUntil:发送complete的结束条件 当然发送结束之前也会包括这个值
  
  
  1. Observable.just(2,3,4,5)
  2. //发送complete的结束条件 当然发送结束之前也会包括这个值
  3. .takeUntil(integer -> integer>3)
  4. .subscribe(o -> System.out.print(o + "t"));//2,3,4
  • takeWhile:当不满足这个条件 会发送结束 不会包括这个值
  
  
  1. Observable.just(2,3,4,5)
  2. //当不满足这个条件 会发送结束 不会包括这个值
  3. .takeWhile(integer ->integer<=4 )
  4. .subscribe(o -> System.out.print(o + "t"));//2,3,4
  • skip系列

    • 变体 count系列:丢弃Observable发射的前N项数据
            
            
      1. Observable.range(0,5)
      2. .skip(3)
      3. .subscribe(o -> System.out.print(o + "t"));
    • 变体 time系列:丢弃原始Observable开始的那段时间发 射的数据
            
            
      1. Observable.range(0,5)
      2. .skip(3)
      3. .subscribe(o -> System.out.print(o + "t"));
  • skipLast

    • 变体 count系列:丢弃Observable发射的前N项数据
        
        
    1. Observable.range(0,5)
    2. .skipLast(3)
    3. .subscribe(o -> System.out.print(o + "t"));
    • 变体 time系列:丢弃在原始Observable的生命周 期内最后一段时间内发射的数据
            
            
      1. Observable.range(0,10)
      2. .skipLast(100, TimeUnit.MILLISECONDS)
      3. .subscribe(o -> System.out.print(o + "t"));
  • distinct:去重

    • keySelector:这个函数根据原始Observable发射的数据项产生一个 Key,然后,比较这些Key而不是数据本身,来判定两个数据是否是不同的

            
            
      1. Observable.just(1, 2, 1, 2, 3)
      2. //这个函数根据原始Observable发射的数据项产生一个 Key,
      3. // 然后,比较这些Key而不是数据本身,来判定两个数据是否是不同的
      4. .distinct(integer -> Math.random())
      5. .subscribe(o -> System.out.print(o + "t"));
      6. 日志:
      7. 原因 key不同 所以当做数据不同处理
      8. 1 2 1 2 3
    • 无参版本 就是内部实现了的keySelector通过生成的key就是value本身
        
        
    1. Observable.just(1, 2, 1, 2, 3)
    2. .distinct()
    3. .subscribe(o -> System.out.print(o + "t"));
    4. 日志:
    5. 1 2 3
  • distinctUntilChanged(相邻去重):它只判定一个数据和它的直接前驱是 否是不同的。

    其他概念与distinct一样

  • throttleWithTimeout/debounce:

操作符会过滤掉发射速率过快的数据项 throttleWithTimeout/debounce: 含义相同 如果发送数据后 指定时间段内没有新数据的话 。则发送这条 如果有新数据 则以这个新数据作为将要发送的数据项,并且重置这个时间段,重新计时。

  
  
  1. Observable.create(e -> {
  2. e.onNext("onNext 0");
  3. Thread.sleep(100);
  4. e.onNext("onNext 1");
  5. Thread.sleep(230);
  6. e.onNext("onNext 2");
  7. Thread.sleep(300);
  8. e.onNext("onNext 3");
  9. Thread.sleep(400);
  10. e.onNext("onNext 4");
  11. Thread.sleep(500);
  12. e.onNext("onNext 5");
  13. e.onNext("onNext 6");
  14. })
  15. .debounce(330, TimeUnit.MILLISECONDS)
  16. // .throttleWithTimeout(330, TimeUnit.MILLISECONDS)
  17. .subscribeOn(Schedulers.newThread())
  18. .observeOn(Schedulers.newThread())
  19. .subscribe(o -> System.out.println(o));//结果 3 4 6
  • filter:只发射通过了谓词测试的数据项

        
        
    1. Observable.range(0, 10)
    2. //过滤掉false的元素
    3. .filter(integer -> integer % 2 == 0)
    4. .subscribe(o -> System.out.print(o + "t"));
  • ofType:ofType 是 filter 操作符的一个特殊形式。它过滤一个Observable只返回指定类型的数据
  
  
  1. Observable.just(0, "what?", 1, "String", 3)
  2. //ofType 是 filter 操作符的一个特殊形式。它过滤一个Observable只返回指定类型的数据。
  3. .ofType(String.class)
  4. .subscribe(o -> System.out.print(o + "t"));
  • first:只发射第一项(或者满足某个条件的第一项)数 感觉和take(1) elementAt(0)差不多
  
  
  1. Observable.range(0, 10)
  2. //如果元数据没有发送 则有发送默认值
  3. .first(-1)
  4. .subscribe(o -> System.out.print(o + "t"));
  • last:只发射最后一项(或者满足某个条件的最后一项)数据 感觉和takeLast(1)差不多
  
  
  1. Observable.empty()
  2. //如果元数据没有发送 则有发送默认值
  3. .last(-1)
  4. .subscribe(o -> System.out.print(o + "t"));
  • sample/throttleLast: 周期采样后 发送最后的数据
  • throttleFirst:周期采样 的第一条数据 发送

    注意: 如果是已经被发送过的 则不会继续发送

  
  
  1. Observable.create(e -> {
  2. e.onNext("onNext 0");
  3. Thread.sleep(100);
  4. e.onNext("onNext 1");
  5. Thread.sleep(50);
  6. e.onNext("onNext 2");
  7. Thread.sleep(70);
  8. e.onNext("onNext 3");
  9. Thread.sleep(200);
  10. e.onNext("onNext 4");
  11. e.onNext("onNext 5");
  12. })
  13. .subscribeOn(Schedulers.newThread())
  14. .observeOn(Schedulers.newThread())
  15. <!-- 结果 : onNext 2 onNext 3 onNext 5 -->
  16. .sample(200, TimeUnit.MILLISECONDS,Schedulers.newThread())
  17. <!-- 结果 : onNext 2 onNext 3 onNext 5 -->
  18. // .throttleLast(200, TimeUnit.MILLISECONDS,Schedulers.newThread())
  19. <!-- 结果 : onNext 0 onNext 3 onNext 4 -->
  20. // .throttleFirst(200, TimeUnit.MILLISECONDS,Schedulers.newThread())
  21. .subscribe(o -> System.out.print(o + "t"));

辅助操作

  • repeat:不是创建一个Observable,而是重复发射原始,Observable的数据序列,这个序列或者是无限的,或者通过 repeat(n) 指定重复次数
  
  
  1. Observable.just("Love", "For", "You!")
  2. .repeat(3)//重复三次
  3. .subscribe(s -> System.out.println(s));
  • repeatUntil:getAsBoolean 如果返回 true则不repeat false则repeat.主要用于动态控制
  
  
  1. Observable.just("Love", "For", "You!")
  2. .repeatUntil(new BooleanSupplier() {
  3. @Override
  4. public boolean getAsBoolean() throws Exception {
  5. System.out.println("getAsBoolean");
  6. count++;
  7. if (count == 3)
  8. return true;
  9. else
  10. return false;
  11. }
  12. }).subscribe(s -> System.out.println(s));
  • delay:延迟一段指定的时间再发射来自Observable的发射物

    注意: delay 不会平移 onError 通知,它会立即将这个通知传递给订阅者,同时丢弃任何待 发射的 onNext 通知。 然而它会平移一个 onCompleted 通知

  
  
  1. Observable.range(0, 3)
  2. .delay(1400, TimeUnit.MILLISECONDS)
  3. .subscribe(o -> System.out.println("===>" + o + "t"));
  • delaySubscription:让你你可以延迟订阅原始Observable
  
  
  1. Observable.just(1)
  2. .delaySubscription(2000, TimeUnit.MILLISECONDS)
  3. .subscribe(o -> System.out.println("===>" + o + "t")
  4. , throwable -> System.out.println("===>throwable")
  5. , () -> System.out.println("===>complete")
  6. , disposable -> System.out.println("===>订阅"));
  • do系列

    • doOnEach:注册一个回调,它产生的Observable每发射一项数据就会调用它一次
            
            
      1. Observable.range(0, 3)
      2. .doOnEach(integerNotification -> System.out.println(integerNotification.getValue()))
      3. .subscribe(o -> System.out.print("===>" + o + "t"));
      4. 日志:
      5. doOnEach:
      6. doOnEach:0===>0
      7. doOnEach:1===>1
      8. doOnEach:2===>2
      9. doOnEach:null
    • doOnNext:注类似doOnEach 不是接受一个 Notification 参数,而是接受发射的数据项。
            
            
      1. Observable.range(0, 3)
      2. .doOnNext(integer -> {
      3. if (integer == 2)
      4. throw new Error("O__O");
      5. System.out.print(integer);
      6. })
      7. .subscribe(o -> System.out.print("===>" + o + "t")
      8. , throwable -> System.out.print("===>throwable")
      9. , () -> System.out.print("===>complete"));
      10. 日志:
      11. 0===>0 1===>1 ===>throwable
    • doOnSubscribe:注册一个动作,在观察者订阅时使用
            
            
      1. Observable.range(0, 3)
      2. .doOnSubscribe(disposable -> System.out.print("开始订阅"))
      3. .subscribe(o -> System.out.print("===>" + o + "t"));
      4. 日志:
      5. 开始订阅===>0 ===>1 ===>2
    • doOnComplete:注册一个动作,在观察者OnComplete时使用

            
            
      1. Observable.range(0, 3)
      2. .doOnComplete(() -> System.out.print("doOnComplete"))
      3. .subscribe(o -> System.out.print("===>" + o + "t"));
      4. 日志:
      5. ===>0 ===>1 ===>2 doOnComplete
    • doOnError:注册一个动作,在观察者doOnError时使用

            
            
      1. Observable.error(new Throwable("?"))
      2. .doOnError(throwable -> System.out.print("throwable"))
      3. .subscribe(o -> System.out.print("===>" + o + "t"));
      4. 日志:
      5. 异常信息....
      6. throwable
    • doOnTerminate:注册一个动作,Observable终止之前会被调用,无论是正 常还是异常终止。
            
            
      1. Observable.range(0, 3)
      2. .doOnTerminate(() -> System.out.print("t doOnTerminate"))
      3. .subscribe(o -> System.out.print("===>" + o + "t"));
      4. 日志:
      5. ===>0 ===>1 ===>2 doOnTerminate
    • doFinally:注册一个动作,当它产生的Observable终止之后会被调用,无论是正常还 是异常终止。在doOnTerminate之后执行

            
            
      1. Observable.range(0, 3)
      2. .doFinally(() -> System.out.print("t doFinally"))
      3. .doOnTerminate(() -> System.out.print("t doOnTerminate"))
      4. .subscribe(o -> System.out.print("===>" + o + "t"));
      5. 日志:
      6. ===>0 ===>1 ===>2 doOnTerminate doFinally
    • doOnDispose:注册一个动作,当【观察者取消】订阅它生成的Observable它就会被调

      注意:貌似需要在 为出现complete和error的时候 dispose才会触发 ~

        
        
    1. Disposable ab = Observable.interval(1, TimeUnit.SECONDS)
    2. .take(3)
    3. .doOnDispose(() -> System.out.println("解除订阅"))
    4. .subscribe(o -> System.out.print("===>" + o + "t"));
    5. ab.dispose();
    6. 日志:
    7. 解除订阅
  • materialize:将数据项和事件通知都当做数据项发射
  • dematerialize:materialize相反
  
  
  1. Observable.range(0, 3)
  2. //将Observable转换成一个通知列表。
  3. .materialize()
  4. //与上面的作用相反,将通知逆转回一个Observable
  5. .dematerialize()
  6. .subscribe(o -> System.out.print("===>" + o + "t"));
  • observeOn:指定一个观察者在哪个调度器上观察这个Observable
  • subscribeOn:指定Observable自身在哪个调度器上执行

注意 遇到错误 会立即处理而不是等待下游还没观察的数据 既onError 通知会跳到(并吞掉)原始Observable发射的数据项前面

  
  
  1. Observable.range(0, 3)
  2. .subscribeOn(Schedulers.newThread())
  3. .observeOn(Schedulers.newThread())
  4. .subscribe(o -> System.out.print("===>" + o + "t"));
  • subscribe:操作来自Observable的发射物和通知

        
        
    1. Javadoc: subscribe()
    2. Javadoc: subscribe(onNext)
    3. Javadoc: subscribe(onNext,onError)
    4. Javadoc: subscribe(onNext,onError,onComplete)
    5. Javadoc: subscribe(onNext,onError,onComplete,onSubscribe)
    6. Javadoc: subscribe(Observer)
    7. Javadoc: subscribe(Subscriber)
  • foreach:forEach 方法是简化版的 subscribe ,你同样可以传递一到三个函数给它,解释和传递给 subscribe 时一样

不同的是,你无法使用 forEach 返回的对象取消订阅。也没办法传递一个可以用于取消订阅 的参数

  
  
  1. Observable.range(0, 3)
  2. //subscribe的简化版本 没啥用
  3. .forEach(o -> System.out.println("===>" + o + "t"));
  • serialize:保证上游下游同一线程 ,防止不同线程下 onError 通知会跳到(并吞掉)原始Observable发射的数据项前面的错误行为

        
        
    1. Observable.range(0, 3)
    2. .serialize()
    3. .subscribe(o -> System.out.print("===>" + o + "t"));
  • Timestamp:它将一个发射T类型数据的Observable转换为一个发射类型 为Timestamped 的数据的Observable,每一项都包含数据的原始发射时间

        
        
    1. Observable.interval(100, TimeUnit.MILLISECONDS)
    2. .take(3)
    3. .timestamp()
    4. .subscribe(o -> System.out.println("===>" + o + "t")
    5. , throwable -> System.out.println("===> throwable")
    6. , () -> System.out.println("===> complete")
    7. , disposable -> System.out.println("===> 订阅"));
    8. 日志:
    9. ===> 订阅
    10. ===>Timed[time=1501224256554, unit=MILLISECONDS, value=0]
    11. ===>Timed[time=1501224256651, unit=MILLISECONDS, value=1]
    12. ===>Timed[time=1501224256751, unit=MILLISECONDS, value=2]
    13. ===> complete
  • timeInterval:一个发射数据的Observable转换为发射那些数据发射时间间隔的Observable
  
  
  1. Observable.interval(100, TimeUnit.MILLISECONDS)
  2. .take(3)
  3. // 把发送的数据 转化为 相邻发送数据的时间间隔实体
  4. .timeInterval()
  5. // .timeInterval(Schedulers.newThread())
  6. .subscribe(o -> System.out.println("===>" + o + "t")
  7. , throwable -> System.out.println("===>throwable")
  8. , () -> System.out.println("===>complete")
  9. , disposable -> System.out.println("===>订阅"));
  10. 日志:
  11. ===>订阅
  12. ===>Timed[time=113, unit=MILLISECONDS, value=0]
  13. ===>Timed[time=102, unit=MILLISECONDS, value=1]
  14. ===>Timed[time=97, unit=MILLISECONDS, value=2]
  15. ===>complete
  • timeout
    • 变体:过了一个指定的时长仍没有发射数据(不是仅仅考虑第一个),它会发一个错误
            
            
      1. Observable.interval(100, TimeUnit.MILLISECONDS)
      2. // 过了一个指定的时长仍没有发射数据(不是仅仅考虑第一个),它会发一个错误
      3. .timeout(50, TimeUnit.MILLISECONDS)
      4. .subscribe(o -> System.out.println("===>" + o + "t")
      5. , throwable -> System.out.println("===>timeout throwable")
      6. , () -> System.out.println("===>timeout complete")
      7. , disposable -> System.out.println("===>timeout 订阅"));
      8. timeout:
      9. ===>timeout 订阅
      10. ===>timeout throwable
    • 变体 备用Observable:过了一个指定的时长仍没有发射数据(不是仅仅考虑第一个),它会发一个错误
            
            
      1. Observable<Integer> other;
      2. Observable.empty()
      3. // 过了一个指定的时长仍没有发射数据(不是仅仅考虑第一个),他会用备用Observable 发送数据,本身的会发送一个compelte
      4. .timeout(50, TimeUnit.MILLISECONDS, other = Observable.just(2, 3, 4))
      5. .subscribe(o -> System.out.println("===>" + o + "t")
      6. , throwable -> System.out.println("===>timeout2 throwable")
      7. , () -> System.out.println("===>timeout2 complete")
      8. , disposable -> System.out.println("===>timeout2 订阅"));
      9. other.subscribe(o -> System.out.println("k ===>" + o + "t"));
      10. timeout2:
      11. ===>timeout2 订阅
      12. ===>timeout2 complete
      13. k ===>2
      14. k ===>3
      15. k ===>4

变换操作

  • map:对Observable发射的每一项数据应用一个函数,执行变换操作,就是方形过渡到圆形
  
  
  1. Observable.just(1,2)
  2. .map(integer -> "This is result " + integer)
  3. .subscribe(s -> System.out.println(s));
  • flatMap: 将一个发射数据的Observable变换为多个Observables,然后将它们发射的数据合并后放进一个单独的Observable
    • mapper:根据发射数据映射成Observable
    • combiner: 用来合并 的

注意:FlatMap 对这些Observables发射的数据做的是合并( merge )操作,因此它们可能是交 错的。

  
  
  1. Observable.just(1, 2, 3)
  2. .flatMap(integer -> Observable.range(integer * 10, 2)
  3. , (a, b) -> {
  4. //a : 原始数据的 just(1,2,3) 中的值
  5. //b : 代表 flatMap后合并发送的数据的值
  6. System.out.print("n a:" + a + "t b:" + b);
  7. //return flatMap发送的值 ,经过处理后 而发送的值
  8. return a + b;
  9. })
  10. .subscribe(s -> System.out.print("t"+s));
  11. 日志:
  12. <!-- 这里有顺序是因为没有在其他线程执行 -->
  13. a:1 b:10 11
  14. a:1 b:11 12
  15. a:2 b:20 22
  16. a:2 b:21 23
  17. a:3 b:30 33
  18. a:3 b:31 34
  • concatMap:类似FlatMap但是保证顺序 因为没有合并操作!
  
  
  1. Observable.just(1, 2, 3)
  2. .concatMap(integer -> Observable.range(integer * 10, 2))
  3. .subscribe(s -> System.out.print("t"+s));
  • cast:在发射之前强制将Observable发射的所有数据转换为指定类型
  
  
  1. Observable.just(1, 2, "string")
  2. .cast(Integer.class)//订阅之后才能发横强转
  3. .subscribe(integer -> System.out.println(integer)
  4. , throwable -> System.out.println(throwable.getMessage()));
  • groupBy:通过keySelector的apply的值当做key 进行分组,发射GroupedObservable(有getKey()方法)的group 通过group继续订阅取得其组内的值;
    • keySelector:通过这个的返回值 当做key进行分组
    • valueSelector:value转换
  
  
  1. Observable.range(0, 10)
  2. .groupBy(integer -> integer % 2, integer -> "(" + integer + ")")
  3. .subscribe(group -> {
  4. group.subscribe(integer -> System.out.println(
  5. "key:" + group.getKey() + "==>value:" + integer));
  6. });
  7. 日志:
  8. key:0==>value:(0)
  9. key:1==>value:(1)
  10. key:0==>value:(2)
  11. key:1==>value:(3)
  12. key:0==>value:(4)
  13. key:1==>value:(5)
  14. key:0==>value:(6)
  15. key:1==>value:(7)
  16. key:0==>value:(8)
  17. key:1==>value:(9)
  • window: 依照此范例 每三秒收集,Observable在此时间内发送的值。组装成Observable发送出去。
  
  
  1. Observable.interval(1, TimeUnit.SECONDS).take(7)
  2. //返回值 Observable<Observable<T>> 即代表 发送Observable<T>
  3. .window(3, TimeUnit.SECONDS)
  4. .subscribeOn(Schedulers.io())
  5. .observeOn(Schedulers.io())
  6. .subscribe(integerObservable -> {
  7. System.out.println(integerObservable);
  8. integerObservable.subscribe(integer -> System.out.println(integerObservable+"===>"+integer));
  9. });
  10. 日志:
  11. 为什么不是 345一起? 因为会有太细微的时间差。例如5如果在多线程切换的时候是超过3秒的1毫秒则就尴尬了~
  12. io.reactivex.subjects.UnicastSubject@531c3d1c
  13. io.reactivex.subjects.UnicastSubject@531c3d1c===>0
  14. io.reactivex.subjects.UnicastSubject@531c3d1c===>1
  15. io.reactivex.subjects.UnicastSubject@531c3d1c===>2
  16. io.reactivex.subjects.UnicastSubject@2ea0f969
  17. io.reactivex.subjects.UnicastSubject@2ea0f969===>3
  18. io.reactivex.subjects.UnicastSubject@2ea0f969===>4
  19. io.reactivex.subjects.UnicastSubject@2d30de03
  20. io.reactivex.subjects.UnicastSubject@2d30de03===>5
  21. io.reactivex.subjects.UnicastSubject@2d30de03===>6
  • scan:连续地对数据序列的每一项应用一个函数,然后连续发射结果

感觉就是发送一个有 累加(函数) 过程序列

  • initialValue(可选) 其实就是放到 原始数据之前发射。
  • a 原始数据的中的值
  • b 则是最后应用scan函数后发送的值
  
  
  1. Observable.just(1, 4, 2)
  2. //7是用来 对于第一次的 a的值
  3. .scan(7, (a, b) -> {
  4. //b 原始数据的 just(1,4,2) 中的值
  5. //a 则是最后应用scan 发送的值
  6. System.out.format("a:%d * b:%dn", a, b);
  7. return a * b;
  8. })
  9. .subscribe(integer -> System.out.println("===>:"+integer));
  10. 日志:
  11. ===>:7
  12. a:7 * b:1
  13. ===>:7
  14. a:7 * b:4
  15. ===>:28
  16. a:28 * b:2
  17. ===>:56
  • buffer系列

    • 变体 count系列
        
        
    1. * 范例:发射[1-10]
    2. * buffer count 2 skip 1,结果 [1,2] [2,3] [3,4] 3=2*1+1
    3. * buffer count 2 skip 2,结果 [1,2] [3,4] [5,6] 5=2*2+1
    4. * buffer count 2 skip 3,结果 [1,2] [4,5] [7,8] 7=2*3+1;
        
        
    1. * count:缓存的数量
    2. * skip:每个缓存创建的间隔数量
    3. > 则代表 每次初始偏移量 每次真正的起始值=fistValue+skip*skipCount;
    4. > 注意skip不能小于0
    5. > 可以小于count这样就会导致每个发送的list之间的值会有重复
    6. > 可以大于count这样就会导致每个发送的list之间的值和原有的值之间会有遗漏
    7. > 可以等于count就你懂的了
    8. * bufferSupplier:自定义缓存装载的容器;
        
        
    1. Observable.range(1, 10)
    2. .buffer(2, 1,() -> new ArrayList<>())//有默认的装载器
    3. <!-- 其他方法 -->
    4. <!-- .buffer(2)//skip 默认和count一样 -->
    5. <!-- .buffer(2, () -> new ArrayList<>())-->
    6. .subscribe(integers -> System.out.println(integers));
    7. 解析:每发射1个。创建一个发射物list buffer,每个buffer缓存2个,收集的存入list后发送。
    • 变体 time系列
      • timespan:缓存的时间
      • timeskip:每个缓存创建的间隔时间 同skip 可以小于大于等于timespan
        
        
    1. Observable.interval(500, TimeUnit.MILLISECONDS).take(7)
    2. .buffer(3, 2, TimeUnit.SECONDS, Schedulers.single(),
    3. Functions.createArrayList(16))
    4. .subscribe(integers -> System.out.println(integers));
    5. 解析:每两秒创建一个发射物list buffer,每个buffer缓存三秒 收集的存入list后发送。
    6. 日志:
    7. [0, 1, 2, 3, 4]
    8. [4, 5, 6]
    • 变体 自定义buffer创建和收集时间
      • bufferOpenings:每当 bufferOpenings 发射了一个数据时,它就 创建一个新的 List,开始装入之后的发射数据
      • closingSelector:每当 closingSelector 发射了一个数据时,就结束装填数据 发射List。
  
  
  1. <!-- 范例和time系列的就一样了 -->
  2. Consumer<Long> longConsumer = aLong -> System.out.println("开始创建 bufferSupplier");
  3. Consumer<Long> longConsumer2 = aLong -> System.out.println("结束收集");
  4. Observable.interval(500, TimeUnit.MILLISECONDS).take(7)
  5. // .doOnNext(aLong -> System.out.println("原始发射物:" + aLong))
  6. .buffer(Observable.interval(2, TimeUnit.SECONDS)
  7. .startWith(-1L)//为了刚开始就发射一次
  8. .take(2)//多余的我就不创建了
  9. .doOnNext(longConsumer)
  10. , aLong -> Observable.timer(3, TimeUnit.SECONDS)
  11. .doOnNext(longConsumer2)
  12. , () -> new ArrayList<>())
  13. .subscribe(integers -> System.out.println("buffer发射物" + integers));
  14. 日志:
  15. openings:
  16. 开始创建 bufferSupplier
  17. 开始创建 bufferSupplier
  18. 结束收集
  19. buffer发射物[0, 1, 2, 3, 4]
  20. buffer发射物[4, 5, 6]
  • 变体 仅仅bufer创建时间

    • boundarySupplier 因为发送一个值代表上个缓存的发送 和这个缓存的创建

    这个缓存是连续的, 因为发送一个值代表上个缓存的发送 和这个缓存的创建 有发射物的时候 没缓存就创建了 就是 默认第一个发射物的时候由内部创建 注意 如果不发送事件缓存 存满了 会自动发送出去的

        
        
    1. Observable.interval(500, TimeUnit.MILLISECONDS).take(7)
    2. .buffer(() -> Observable.timer(2, TimeUnit.SECONDS)
    3. .doOnNext(aLong -> System.out.println("开始创建 bufferSupplier"))
    4. , () -> new ArrayList<Object>())
    5. .subscribe(integers -> System.out.println(integers));
    6. 日志:
    7. 开始创建 bufferSupplier
    8. [0, 1, 2]
    9. [3, 4, 5, 6]

合并操作符

  • zip(静态方法):只有当原始的Observable中的每一个都发射了 一条数据时 zip 才发射数据。接受一到九个参数
  
  
  1. Observable<Long> observable1 = Observable.interval(100, TimeUnit.MILLISECONDS)
  2. .take(3)
  3. .subscribeOn(Schedulers.newThread());
  4. Observable<Long> observable2 = Observable.interval(200, TimeUnit.MILLISECONDS)
  5. .take(4)
  6. .subscribeOn(Schedulers.newThread());
  7. Observable.zip(observable1, observable2, (aLong, aLong2) -> {
  8. System.out.print("aLong:" + aLong + "t aLong2:" + aLong2+"t");
  9. return aLong + aLong2;
  10. }).subscribe(o -> System.out.println("===>" + o + "t"));
  11. 日志:
  12. aLong:0 aLong2:0===>0
  13. aLong:1 aLong2:1===>2
  14. aLong:2 aLong2:2===>4
  • zipWith:zip的非静态写法,总是接受两个参数,第一个参数是一个Observable或者一个Iterable。
  
  
  1. observable1.zipWith( observable2, (aLong, aLong2) -> {
  2. System.out.print("aLong:" + aLong + "t aLong2:" + aLong2+"t");
  3. return aLong + aLong2;
  4. }).subscribe(o -> System.out.println("===>" + o + "t"));
  • merge(静态方法):根据时间线 合并多个observer
  
  
  1. Observable<Long> ob1 = Observable.interval(100, TimeUnit.MILLISECONDS)
  2. .take(3)
  3. .subscribeOn(Schedulers.newThread());
  4. Observable<Long> ob2 = Observable.interval(50, TimeUnit.MILLISECONDS)
  5. .take(3)
  6. .map(aLong -> aLong + 10)
  7. .subscribeOn(Schedulers.newThread());
  8. Observable.merge(ob1, ob2)
  9. .subscribe(o -> System.out.print(o + "t"));
  10. 日志结果:可以见出是根据时间线合并
  11. 10 10 0 0 11 11 12 12 1 1 2 2
  • mergeWith:merge非静态写法
  
  
  1. ob1.mergeWith(ob2)
  2. .subscribe(o -> System.out.print( o + "t"));
  • combineLatest(静态方法):使用一个函数结合它们最近发射的数据,然后发射这个函数的返回值,它接受二到九个Observable作为参数 或者单 个Observables列表作为参数
  
  
  1. Observable<Long> observable1 = Observable.interval(100, TimeUnit.MILLISECONDS)
  2. .take(4)
  3. .subscribeOn(Schedulers.newThread());
  4. Observable<Long> observable2 = Observable.interval(200, TimeUnit.MILLISECONDS)
  5. .take(5)
  6. .subscribeOn(Schedulers.newThread());
  7. Observable.combineLatest(observable1, observable2, (aLong, aLong2) -> {
  8. System.out.print("aLong:" + aLong + "t aLong2:" + aLong2+"t");
  9. return aLong + aLong2;
  10. }).subscribe(o -> System.out.println("===>" + o + "t"));
  11. 日志:
  12. aLong:1 aLong2:0 ===>1
  13. aLong:2 aLong2:0 ===>2
  14. aLong:3 aLong2:0 ===>3
  15. aLong:3 aLong2:1 ===>4
  16. aLong:3 aLong2:2 ===>5
  17. aLong:3 aLong2:3 ===>6
  18. aLong:3 aLong2:4 ===>7
  • withLatestFrom:类似zip ,但是只在单个原始Observable发射了一条数据时才发射数据,而不是两个都发

但是注意 如果没有合并元素 既辅助Observable一次都没发射的时候 是不发射数据的

  
  
  1. Observable<Long> observable2 = Observable.interval(150, TimeUnit.MILLISECONDS)
  2. .take(4)
  3. .subscribeOn(Schedulers.newThread());
  4. Observable.interval(100, TimeUnit.MILLISECONDS)
  5. .take(3)
  6. .subscribeOn(Schedulers.newThread())
  7. .withLatestFrom(observable2, (aLong, aLong2) -> {
  8. System.out.print("aLong:" + aLong + "t aLong2:" + aLong2 + "t");
  9. return aLong + aLong2;
  10. })
  11. .subscribe(o -> System.out.println("===>" + o + "t"));
  12. 日志:
  13. 明明原始take3为啥不是三条log 因为原始的发送0的时候 ,辅助Observable还没发送过数据
  14. aLong:1 aLong2:0 ===>1
  15. aLong:2 aLong2:1 ===>3
  • switchMap:和flatMap类似,不同的是当原始Observable发射一个新的数据(Observable)时,它将取消订阅前一个Observable
  
  
  1. Observable.interval(500, TimeUnit.MILLISECONDS)
  2. .take(3)
  3. .doOnNext(aLong -> System.out.println())
  4. .switchMap(aLong -> Observable.intervalRange(aLong * 10, 3,
  5. 0, 300, TimeUnit.MILLISECONDS)
  6. .subscribeOn(Schedulers.newThread()))
  7. .subscribe(aLong -> System.out.print(aLong+"t"));
  8. 解析:因为发送2的时候 intervalRange发送第三条数据的时候已经是600ms 500ms的时候原始数据发送了。导致取消订阅前一个Observable
  9. 所以 2 ,12没有发送 但是最后的22发送了 因为原始数据没有新发送的了
  10. // 日志结果
  11. // 0 1
  12. // 10 11
  13. // 20 21 22
  14. // 而不是
  15. // 0 1 2
  16. // 10 11 12
  17. // 20 21 22
  • startWith:是concat()的对应部分,在Observable开始发射他们的数据之前,startWith()通过传递一个参数来先发射一个数据序列
  
  
  1. Observable.just("old")
  2. <!-- 简化版本 T item -->
  3. .startWith("Start")
  4. <!-- 多次应用探究 -->
  5. .startWith("Start2")
  6. <!-- observer -->
  7. .startWith(Observable.just("Other Observable"))
  8. <!-- Iterable -->
  9. .startWith(Arrays.asList("from Iterable"))
  10. <!-- T... -->
  11. .startWithArray("from Array", "from Array2")
  12. .subscribe(s -> System.out.println(s));
  13. 日志:
  14. from Array
  15. from Array2
  16. from Iterable
  17. Other Observable
  18. Start2
  19. Start
  20. old
  • join:任何时候,只要在另一个Observable发射的数据定义的时间窗口内,这个Observable发射了。一条数据,就结合两个Observable发射的数据

  
  
  1. <!-- 此demo 好使但是未让能理解透彻 仅仅想测试能结果的任用 想明白的话 此demo无效 -->
  2. Observable.intervalRange(10, 4, 0, 300, TimeUnit.MILLISECONDS)
  3. .join(Observable.interval(100, TimeUnit.MILLISECONDS)
  4. .take(7)
  5. , aLong -> {
  6. System.out.println("开始收集:"+aLong);
  7. return Observable.just(aLong);
  8. }
  9. , aLong -> Observable.timer(200, TimeUnit.MILLISECONDS)
  10. , (aLong, aLong2) -> {
  11. System.out.print("aLong:" + aLong + "t aLong2:" + aLong2 + "t");
  12. return aLong + aLong2;
  13. }
  14. )
  15. .subscribe(aLong -> System.out.println(aLong));

条件操作

  • all:判定是否Observable发射的所有数据都满足某个条件

        
        
    1. Observable.just(2, 3, 4)
    2. .all(integer -> integer > 3)
    3. .subscribe((aBoolean, throwable) -> System.out.println(aBoolean));
    4. 日志:false
  • amb:给定多个Observable,只让第一个发射数据的Observable发射全部数据

    • ambArray(静态方法):根据测试结果这个静态方法发射的最后一个
            
            
      1. Observable.ambArray(
      2. Observable.intervalRange(0, 3, 200, 100, TimeUnit.MILLISECONDS)
      3. , Observable.intervalRange(10, 3, 300, 100, TimeUnit.MILLISECONDS)
      4. , Observable.intervalRange(20, 3, 100, 100, TimeUnit.MILLISECONDS)
      5. )
      6. .doOnComplete(() -> System.out.println("Complete"))
      7. .subscribe(aLong -> System.out.println(aLong));
      8. 日志:
      9. 20 21 22 Complete
    • ambWith:这个发射原始的
            
            
      1. Observable.intervalRange(0, 3, 200, 100, TimeUnit.MILLISECONDS)
      2. .ambWith(Observable.intervalRange(10, 3, 300, 100, TimeUnit.MILLISECONDS))
      3. .doOnComplete(() -> System.out.println("Complete"))
      4. .subscribe(aLong -> System.out.println(aLong));
      5. 日志:
      6. 0 1 2 Complete
  • contains:判定一个Observable是否发射一个特定的值

        
        
    1. Observable.just(2, 3, 4)
    2. .contains(2)
    3. .subscribe((aBoolean, throwable) -> System.out.println(aBoolean));
  • switchIfEmpty:如果原始Observable正常终止后仍然没有发射任何数据,就使用备用的Observable
  
  
  1. Observable.empty()
  2. .switchIfEmpty(Observable.just(2, 3, 4))
  3. .subscribe(o -> System.out.println("===>" + o + "t")); //2,3,4
  • defaultIfEmpty:发射来自原始Observable的值,如果原始Observable没有发射任何值,就发射一个默认值,内部调用的switchIfEmpty。
  
  
  1. Observable.empty()
  2. .defaultIfEmpty(1)
  3. .subscribe(o -> System.out.println("===>" + o + "t")); //1
  • sequenceEqual:判定两个Observables是否发射相同的数据序列。(数据,发射顺序,终止状态)
  
  
  1. Observable.sequenceEqual(
  2. Observable.just(2, 3, 4)
  3. , Observable.just(2, 3, 4))
  4. .subscribe((aBoolean, throwable) -> System.out.println(aBoolean));
  5. <!-- 它还有一个版本接受第三个参数,可以传递一个函数用于比较两个数据项是否相同。 -->
  6. Observable.sequenceEqual(
  7. Observable.just(2, 3, 4)
  8. , Observable.just(2, 3, 4)
  9. , (integer, integer2) -> integer + 1 == integer2)
  10. .subscribe((aBoolean, throwable) -> System.out.println(aBoolean));
  • skipUntil:丢弃原始Observable发射的数据,直到第二个Observable发射了一项数据
  
  
  1. Observable.intervalRange(30, 20, 500, 100, TimeUnit.MILLISECONDS)
  2. .skipUntil(Observable.timer(1000, TimeUnit.MILLISECONDS))
  3. .doOnNext(integer -> System.out.println(integer))
  4. //此时用这个主要是 测试环境 有执行时间 所以用阻塞比较好
  5. .blockingSubscribe();
  • skipWhile:丢弃Observable发射的数据,直到一个指定的条件不成立
  
  
  1. Observable.just(1,2,3,4)
  2. //从2开始 因为2条件不成立
  3. .skipWhile(aLong -> aLong==1)
  4. .doOnNext(integer -> System.out.println(integer))
  5. //此时用这个主要是 测试环境 有执行时间 所以用阻塞比较好
  6. .blockingSubscribe();
  • takeUntil:当第二个Observable发射了一项数据或者终止时,丢弃原始Observable发射的任何数据
  
  
  1. <!-- 条件变体 -->
  2. Observable.just(2,3,4,5)
  3. .takeUntil(integer -> integer<=4)
  4. .subscribe(o -> System.out.print(o + "t"));//2,3,4
  5. <!-- Observable变体 -->
  6. Observable.intervalRange(30, 20, 500, 100, TimeUnit.MILLISECONDS)
  7. .takeUntil(Observable.timer(1000, TimeUnit.MILLISECONDS))
  8. .doOnNext(integer -> System.out.println(integer))
  9. .doOnComplete(() -> System.out.println("Complete"))
  10. //此时用这个主要是 测试环境 有执行时间 所以用阻塞比较好
  11. .blockingSubscribe();
  • takeWhile:发射Observable发射的数据,直到一个指定的条件不成立
  
  
  1. Observable.just(2,3,4,5)
  2. .takeWhile(integer ->integer<=4 )
  3. .subscribe(o -> System.out.print(o + "t"));//2,3

错误处理

  • onErrorReturn:让Observable遇到错误时发射一个特殊的项并且正常终止
  
  
  1. <!-- 遇到错误处理范例 -->
  2. Observable.error(new Throwable("我擦 空啊"))
  3. .onErrorReturnItem("hei")
  4. .subscribe(o -> System.out.println("===>" + o + "t")
  5. , throwable -> System.out.println("===>throwable")
  6. , () -> System.out.println("===>complete"));
  7. 日志:
  8. ===>hei
  9. ===>complete
  10. <!-- 遇到错误不处理范例 -->
  11. Observable.error(new Throwable("我擦 空啊"))
  12. .onErrorReturn(throwable -> {
  13. System.out.println("错误信息:" + throwable.getMessage());
  14. return throwable;
  15. })
  16. .subscribe(o -> System.out.println("===>" + o + "t")
  17. , throwable -> System.out.println("===>throwable")
  18. , () -> System.out.println("===>complete"));
  19. 日志:
  20. 错误信息:我擦 空啊
  21. ===>java.lang.Throwable: 我擦 空啊
  22. ===>complete
  • resumeNext:让Observable在遇到错误时开始发射第二个Observable的数据序列

    • onErrorResumeNext:可以处理所有的错误
            
            
      1. Observable.error(new Throwable("我擦 空啊"))
      2. .onErrorResumeNext(throwable -> {
      3. System.out.println("错误信息:" + throwable.getMessage());
      4. return Observable.range(0, 3);
      5. })
      6. .subscribe(o -> System.out.print("===>" + o + "t")
      7. , throwable -> System.out.print("===>throwable"+ "t")
      8. , () -> System.out.print("===>complete"+ "t"));
      9. 日志:
      10. 错误信息:我擦 空啊
      11. ===>0 ===>1 ===>2 ===>complete
    • onExceptionResumeNext:只能处理异常。

    Throwable 不是一个 Exception ,它会将错误传递给观察者的 onError 方法,不会使用备用 的Observable。

        
        
    1. <!-- Throwable不能处理范例 -->
    2. Observable.error(new Throwable("我擦 空啊"))
    3. .onExceptionResumeNext(observer -> Observable.range(0, 3))
    4. .subscribe(o -> System.out.println("===>" + o + "t")
    5. , throwable -> System.out.println("===>throwable")
    6. , () -> System.out.println("===>complete"));
    7. 日志:
    8. ===>throwable
    9. <!-- 正确演示范例 无效ing 求解答~ todo -->
  • retry:如果原始Observable遇到错误,重新订阅它期望它能正常终止

    • 变体count 重复次数
            
            
      1. Observable.create(e -> {
      2. e.onNext(1);
      3. e.onNext(2);
      4. e.onError(new Throwable("hehe"));
      5. })
      6. .retry(2)
      7. .subscribe(o -> System.out.print("===>" + o + "t")
      8. , throwable -> System.out.print("===>throwablet")
      9. , () -> System.out.print("===>completet"));
      10. 日志:
      11. ===>1 ===>2 ===>1 ===>2 ===>1 ===>2 ===>throwable
    • 变体Predicate 条件判定 如果返回 true retry,false 放弃 retry
            
            
      1. Observable.create(e -> {
      2. e.onNext(1);
      3. e.onNext(2);
      4. e.onError(new Throwable("hehe"));
      5. })
      6. .retry(throwable -> throwable.getMessage().equals("hehe1"))
      7. .subscribe(o -> System.out.print("===>" + o + "t")
      8. , throwable -> System.out.print("===>throwablet")
      9. , () -> System.out.print("===>completet"));
      10. 日志:
      11. ===>1 ===>2 ===>throwable
  • retryWhen: 需要一个Observable 通过判断 throwableObservable,Observable发射一个数据 就重新订阅,发射的是 onError 通知,它就将这个通知传递给观察者然后终止。
  
  
  1. <!-- 正常范例 -->
  2. Observable.just(1, "2", 3)
  3. .cast(Integer.class)
  4. <!-- 结果:1,1,complete 原因这个Observable发了一次数据 -->
  5. .retryWhen(throwableObservable -> Observable.timer(1, TimeUnit.SECONDS))
  6. <!-- 结果:1,1,1,1,complete 原因这个Observable发了三次数据 -->
  7. .retryWhen(throwableObservable -> Observable.interval(1, TimeUnit.SECONDS)
  8. .take(3))
  9. .subscribe(o -> System.out.println("retryWhen 1===>" + o + "t")
  10. , throwable -> System.out.println("retryWhen 1===>throwable")
  11. , () -> System.out.println("retryWhen 1===>complete"));
  12. <!-- 通过判断throwable 进行处理范例 -->
  13. Observable.just(1, "2", 3)
  14. .cast(Integer.class)
  15. .retryWhen(throwableObservable -> {
  16. return throwableObservable.switchMap(throwable -> {
  17. if (throwable instanceof IllegalArgumentException)
  18. return Observable.just(throwable);
  19. <!-- 这种方式OK -->
  20. // else{
  21. // PublishSubject<Object> pb = PublishSubject.create();
  22. // pb .onError(throwable);
  23. // return pb;
  24. // }
  25. else
  26. //方法泛型
  27. return Observable.<Object>error(throwable);
  28. <!-- 这种方式也OK -->
  29. // return Observable.just(1).cast(String.class);
  30. });
  31. })
  32. .subscribe(o -> System.out.println("retryWhen 2===>" + o + "t")
  33. , throwable -> System.out.println("retryWhen 2===>throwable")
  34. , () -> System.out.println("retryWhen 2===>complete"));
  35. 日志:
  36. retryWhen 2===>1
  37. retryWhen 2===>throwable

阻塞操作

  • toList
        
        
    1. Observable.just(1, 2, 3)
    2. .toList().blockingGet()
    3. .forEach(aLong -> System.out.println(aLong));
  • toSortList
        
        
    1. Observable.just(5, 2, 3)
    2. .toSortedList()
    3. .blockingGet()
    4. .forEach(integer -> System.out.println(integer))
  • toMap
        
        
    1. Map<String, Integer> map = Observable.just(5, 2, 3)
    2. // .toMap(integer -> integer + "_")
    3. //key 就是5_,value就是5+10 mapSupplier map提供者
    4. .toMap(integer -> integer + "_"
    5. , integer -> integer + 10
    6. , () -> new HashMap<>())
    7. .blockingGet();
  • toFuture

    这个操作符将Observable转换为一个返 回单个数据项的 Future 带有返回值的任务 如果原始Observable发射多个数据项, Future 会收到1个 IllegalArgumentException 如果原始Observable没有发射任何数据, Future 会收到一 个 NoSuchElementException 如果你想将发射多个数据项的Observable转换为 Future ,可以这样 用: myObservable.toList().toFuture()

  
  
  1. Observable.just(1, 2, 3)
  2. .toList()//转换成Single<List<T>> 这样就变成一个数据了
  3. .toFuture()
  4. .get()
  5. .forEach(integer -> System.out.println(integer));
  • blockingSubscribe

        
        
    1. Observable.just(1, 2, 3)
    2. .blockingSubscribe(integer -> System.out.println(integer));
  • blockingForEach:对BlockingObservable发射的每一项数据调用一个方法,会阻塞直到Observable完成。

        
        
    1. Observable.interval(100, TimeUnit.MILLISECONDS)
    2. .doOnNext(aLong -> {
    3. if (aLong == 10)
    4. throw new RuntimeException();
    5. }).onErrorReturnItem(-1L)
    6. .blockingForEach(aLong -> System.out.println(aLong));
  • blockingIterable

        
        
    1. Observable.just(1, 2, 3)
    2. .blockingIterable()
    3. // .blockingIterable(5);
    4. .forEach(aLong -> System.out.println("aLong:" + aLong));
  • blockingFirst

        
        
    1. Observable.empty()
    2. // .blockingFirst();
    3. //带默认值版本
    4. .blockingFirst(-1));
  • blockingLast:

        
        
    1. Observable.just(1,2,3)
    2. // .blockingLast();
    3. //带默认值版本
    4. .blockingLast(-1));
  • blockingMostRecent:返回一个总是返回Observable最近发射的数据的Iterable,类似于while的感觉

        
        
    1. Iterable<Long> c = Observable.interval(100, TimeUnit.MILLISECONDS)
    2. .doOnNext(aLong -> {
    3. if (aLong == 10)
    4. throw new RuntimeException();
    5. }).onErrorReturnItem(-1L)
    6. .blockingMostRecent(-3L);
    7. for (Long aLong : c) {
    8. System.out.println("aLong:" + aLong);
    9. }
    10. 日志很长 可以自己一试变知
  • blockingSingle:

终止时只发射了一个值,返回那个值 empty 无默认值 报错, 默认值的话显示默认值 多个值的话 有无默认值都报错

  
  
  1. System.out.println("emit 1 value:" + Observable.just(1).blockingSingle());
  2. System.out.println("default empty single:" + Observable.empty().blockingSingle(-1));
  3. System.out.println("default emit 1 value:" + Observable.just(1).blockingSingle(-1));
  4. try {
  5. System.out.println("empty single:" + Observable.empty().blockingSingle());
  6. System.out.println("emit many value:" + Observable.just(1, 2).blockingSingle());
  7. System.out.println("default emit many value:" + Observable.just(1, 2)
  8. .blockingSingle(-1));
  9. } catch (Exception e) {
  10. e.printStackTrace();
  11. }
  12. 日志:
  13. emit 1 value:1
  14. default empty single:-1
  15. default emit 1 value:1
  16. java.util.NoSuchElementException

组合操作

  • compose:有多个 Observable ,并且他们都需要应用一组相同的 变换
  
  
  1. <!-- 用一个工具类去写 这样符合单一职责 -->
  2. //composes 工具类
  3. public class RxComposes {
  4. public static <T> ObservableTransformer<T, T> applyObservableAsync() {
  5. return upstream -> upstream.subscribeOn(Schedulers.io())
  6. .observeOn(AndroidSchedulers.mainThread());
  7. }
  8. }
  9. Observable.empty()
  10. .compose(RxComposes.applyObservableAsync())
  11. .subscribe(integer -> System.out.println("ob3:" + integer));
  • ConnectableObservable:可连接的Observable在 被订阅时并不开始发射数据,只有在它的 connect() 被调用时才开始用这种方法, 你可以 等所有的潜在订阅者都订阅了这个Observable之后才开始发射数据。即使没有任何订阅者订阅它,你也可以使用 connect 让他发射

    • replay(Observable的方法): 每次订阅 都对单个订阅的重复播放一边
      • bufferSize:对源发射队列的缓存数量, 从而对新订阅的进行发射;

    Observable的方法 返回是ConnectableObservable 切记要让ConnectableObservable具有重播的能力,必须Obserable的时候调用replay,而不是ConnectableObservable 的时候调用replay

        
        
    1. //this is OK,too!
    2. ConnectableObservable<Integer> co = Observable.just(1, 2, 3)
    3. //类似 publish直接转成 ConnectableObservable 切记要重复播放的话必须Obserable的时候调用replay
    4. //而不是ConnectableObservable 的时候调用replay 所以 .publish().replay()则无效
    5. .replay(3);//重复播放的 是1 2 3
    6. // .replay(2);//重复播放的 是 2 3
    7. co.doOnSubscribe(disposable -> System.out.print("订阅1:"))
    8. .doFinally(() -> System.out.println())
    9. .subscribe(integer -> System.out.print(integer + "t"));
    10. co.connect();//此时开始发射数据 不同与 refCount 只发送一次
    11. co.doOnSubscribe(disposable -> System.out.print("订阅2:"))
    12. .doFinally(() -> System.out.println())
    13. .subscribe(integer -> System.out.print(integer + "t"));
    14. co.doOnSubscribe(disposable -> System.out.print("订阅3:"))
    15. .doFinally(() -> System.out.println())
    16. .subscribe(integer -> System.out.print(integer + "t"));
    17. replay(3)日志:只能缓存原始队列的两个【1,2,3
    18. 订阅11 2 3
    19. 订阅21 2 3
    20. 订阅31 2 3
    21. replay(2)日志:只能缓存原始队列的两个【2,3
    22. 订阅11 2 3
    23. 订阅2 2 3
    24. 订阅3 2 3
    • publish(Observable的方法):将普通的Observable转换为可连接的Observable

            
            
      1. ConnectableObservable<Integer> co = Observable.just(1, 2, 3)
      2. .publish();
      3. co.subscribe(integer -> System.out.println("订阅1:" + integer));
      4. co.subscribe(integer -> System.out.println("订阅2:" + integer));
      5. co.subscribe(integer -> System.out.println("订阅3:" + integer));
      6. co.connect();//此时开始发射数据
    • refCount(ConnectableObservable的方法): 操作符把从一个可连接的Observable连接和断开的过程自动化了, 就像reply的感觉式样 每次订阅 都对单个订阅的重复播放一边

            
            
      1. Observable<Integer> co = Observable.just(1, 2, 3)
      2. .publish()
      3. //类似于reply 跟时间线有关 订阅开始就开始发送
      4. .refCount();
      5. co.doOnSubscribe(disposable -> System.out.print("订阅1:"))
      6. .doFinally(() -> System.out.println())
      7. .subscribe(integer -> System.out.print(integer + "t"));
      8. co.doOnSubscribe(disposable -> System.out.print("订阅2:"))
      9. .doFinally(() -> System.out.println())
      10. .subscribe(integer -> System.out.print(integer + "t"));
      11. Observable.timer(300, TimeUnit.MILLISECONDS)
      12. .doOnComplete(() -> {
      13. co.doOnSubscribe(disposable -> System.out.print("订阅3:"))
      14. .doFinally(() -> System.out.println())
      15. .subscribe(integer -> System.out.print(integer + "t"));
      16. }).blockingSubscribe();
      17. 日志:
      18. 订阅11 2 3
      19. 订阅21 2 3
      20. 订阅31 2 3

Subjects

Subject可以看成是一个桥梁或者代理,在某些ReactiveX实现中(如RxJava),它同时充当 了Observer和Observable的角色。因为它是一个Observer,它可以订阅一个或多个 Observable;又因为它是一个Observable,它可以转发它收到(Observe)的数据,也可以发射 新的数据。

对我来说为什么用subjects呢?所有Subject都可以直接发射,不需要 发射器的引用 和 Observable.create()不同

  • AsyncSubject:简单的说使用AsyncSubject无论输入多少参数,永远只输出最后一个参数。

    但是如果因为发生了错误而终止,AsyncSubject将不会发射任何数据,只是简单的向前传递这个错误通知。

  
  
  1. AsyncSubject<Integer> source = AsyncSubject.create();
  2. source.subscribe(o -> System.out.println("1:"+o)); // it will emit only 4 and onComplete
  3. source.onNext(1);
  4. source.onNext(2);
  5. source.onNext(3);
  6. <!-- it will emit 4 and onComplete for second observer also. -->
  7. source.subscribe(o -> System.out.println("2:"+o));
  8. source.onNext(4);
  9. source.onComplete();
  10. 日志:
  11. 1:4
  12. 2:4
  • BehaviorSubject:会发送离订阅最近的上一个值,没有上一个值的时候会发送默认值。

如果原始的Observable因为发生了一个错误而终止,BehaviorSubject将不会发射任何 数据,只是简单的向前传递这个错误通知。

  
  
  1. BehaviorSubject<Integer> source = BehaviorSubject.create();
  2. //默认值版本
  3. // BehaviorSubject<Integer> source = BehaviorSubject.createDefault(-1);
  4. source.subscribe(o -> System.out.println("1:"+o)); // it will get 1, 2, 3, 4 and onComplete
  5. source.onNext(1);
  6. source.onNext(2);
  7. source.onNext(3);
  8. <!-- it will emit 3(last emitted), 4 and onComplete for second observer also. -->
  9. source.subscribe(o -> System.out.println("2:"+o));
  10. source.onNext(4);
  11. source.onComplete();
  12. 日志:
  13. 1:1
  14. 1:2
  15. 1:3
  16. 2:3
  17. 1:4
  18. 2:4
  • publishSubject(subject里最常用的):可以说是最正常的Subject,从那里订阅就从那里开始发送数据。

    如果原始的Observable因为发生了一个错误而终止,PublishSubject将不会发射任何数据,只 是简单的向前传递这个错误通知。

  
  
  1. PublishSubject bs = PublishSubject.create();
  2. bs.subscribe(o -> System.out.println("1:"+o));
  3. bs.onNext(1);
  4. bs.onNext(2);
  5. bs.subscribe(o -> System.out.println("2:"+o));
  6. bs.onNext(3);
  7. bs.onComplete();
  8. bs.subscribe(o -> System.out.println("3:"+o));
  9. 日志:
  10. 1:1
  11. 1:2
  12. 1:3
  13. 2:3
  • replaySubject: 无论何时订阅,都会将所有历史订阅内容全部发出。
  
  
  1. ReplaySubject bs = ReplaySubject.create();
  2. bs.subscribe(o -> System.out.println("1:"+o));
  3. // 无论何时订阅都会收到1,2,3
  4. bs.onNext(1);
  5. bs.onNext(2);
  6. bs.onNext(3);
  7. bs.onComplete();
  8. bs.subscribe(o -> System.out.println("2:"+o));
  9. 日志:
  10. 1:1
  11. 1:2
  12. 1:3
  13. 2:1
  14. 2:2
  15. 2:3

Single与Completable

参考:http://developer.51cto.com/art/201703/535298.htm

使用场景:其实这个网络请求并不是一个连续事件流,你只会发起一次 Get 请求返回数据并且只收到一个事件。我们都知道这种情况下 onComplete 会紧跟着 onNext 被调用,那为什么不把它们合二为一呢?

  • Single:它总是只发射一个值,或者一个错误通知,而不是发射 一系列的值。因此,不同于Observable需要三个方法onNext, onError, onCompleted,订阅Single只需要两 个方法:

Single只会调用这两个方法中的一个,而且只会调用一次,调用了任何一个方法之后,订阅关 系终止。

  
  
  1. * onSuccess - Single发射单个的值到这个方法
  2. * onError - 如果无法发射需要的值,Single发射一个Throwable对象到这个方法
  
  
  1. <!-- retrofit 范例-->
  2. public interface APIClient {
  3. @GET("my/api/path")
  4. Single<MyData> getMyData();
  5. }
  6. apiClient.getMyData()
  7. .subscribe(new Consumer<MyData>() {
  8. @Override
  9. public void accept(MyData myData) throws Exception {
  10. // handle data fetched successfully and API call completed
  11. }
  12. }, new Consumer<Throwable>() {
  13. @Override
  14. public void accept(Throwable throwable) throws Exception{
  15. // handle error event
  16. }
  17. });
  18. <!-- 单独使用范例: -->
  19. Single.just("Amit")
  20. .subscribe(s -> System.out.println(s)
  21. , throwable -> System.out.println("异常"));

使用场景:通过 PUT 请求更新数据 我只关心 onComplete 事件。使用 Completable 时我们忽略 onNext 事件,只处理 onComplete 和 onError 事件

  • Completable:本质上来说和 Observable 与 Single 不一样,因为它不发射数据。
  
  
  1. <!-- retrofit 范例-->
  2. public interface APIClient {
  3. @PUT("my/api/updatepath")
  4. Completable updateMyData(@Body MyData data);
  5. }
  6. apiClient.updateMyData(myUpdatedData)
  7. .subscribe(new Action() {
  8. @Override
  9. public void run() throws Exception {
  10. // handle completion
  11. }
  12. }, new Consumer<Throwable>() {
  13. @Override
  14. public void accept(Throwable throwable) throws Exception{
  15. // handle error
  16. }
  17. });
  18. <!-- 单独使用范例: -->
  19. Completable.timer(1000, TimeUnit.MILLISECONDS)
  20. .subscribe(() -> System.out.println("成功")
  21. , throwable -> System.out.println("异常"));
  • andThen( Completable中的方法最常用):在这个操作符中你可以传任何Observable、Single、Flowable、Maybe或者其他Completable,它们会在原来的 Completable 结束后执行

        
        
    1. apiClient.updateMyData(myUpdatedData)
    2. .andThen(performOtherOperation()) // a Single<OtherResult>
    3. .subscribe(new Consumer<OtherResult>() {
    4. @Override
    5. public void accept(OtherResult result) throws Exception {
    6. // handle otherResult
    7. }
    8. }, new Consumer<Throwable>() {
    9. @Override
    10. public void accept(Throwable throwable) throws Exception{
    11. // handle error
    12. }
    13. });

自定义操作符

  • lift 原理图

  
  
  1. @Test
  2. public void lift(){
  3. Observable.just(1,2)
  4. //也是代理模式 observer是真正订阅
  5. .lift(observer -> new Observer<Integer>() {
  6. @Override
  7. public void onSubscribe(Disposable d) {
  8. }
  9. @Override
  10. public void onNext(Integer integer) {
  11. observer.onNext(integer+"?");
  12. }
  13. @Override
  14. public void onError(Throwable e) {
  15. }
  16. @Override
  17. public void onComplete() {
  18. }
  19. })
  20. .subscribe(o -> System.out.println(o));
  21. }
  22. 日志:
  23. 1?
  24. 2?

实用技巧

flatMap 与 zip 配合的实用范例:

  
  
  1. Observable.fromArray(new File("/Users/fuzhipeng/Documents"))
  2. .flatMap(file -> Observable.fromArray(file.listFiles()))
  3. //比较经典的 就是Observable.just(file) 把 file一个元素转成 observer从而进行zip合并的难题解决了
  4. .flatMap(file ->
  5. Observable.zip(Observable.just(file)
  6. , Observable.timer(1, TimeUnit.SECONDS)
  7. , (file1, aLong) -> file1))
  8. .filter(file -> file.getName().endsWith(".png"))
  9. .take(5)
  10. .map(file -> file.getName())
  11. .subscribeOn(Schedulers.io())
  12. .observeOn(Schedulers.newThread())
  13. .subscribe(s -> System.out.println(s));
  14. while (true) {
  15. }

map的实用范例:

  
  
  1. //有些服务几口设计,返回数据外层会包裹一些额外信息,可以使用map()吧外层格式剥掉
  2. Observable.just(1)
  3. .map(integer -> new Integer[]{1, 2, 3})
  4. .subscribe(integers -> System.out.println(integers));

方法泛型的实用范例:

  
  
  1. Observable.just(1, "2", 3)
  2. .cast(Integer.class)
  3. .retryWhen(throwableObservable -> {
  4. return throwableObservable.switchMap(throwable -> {
  5. if (throwable instanceof IllegalArgumentException)
  6. return Observable.just(throwable);
  7. //todo 方法泛型 如果我不写<Object> 则会报错
  8. return Observable.<Object>error(throwable);
  9. //这个报错!!!
  10. // return Observable.error(throwable);
  11. });
  12. })
  13. .subscribe(o -> System.out.println("===>" + o + "t")
  14. , throwable -> System.out.println("===>throwable")
  15. , () -> System.out.println("===>complete"));

BehaviorSubject的使用技巧:

cache BehaviorSubject 是桥梁 并且有 发送最近的缓存特性!

  
  
  1. BehaviorSubject<Object> cache = BehaviorSubject.create();
  2. Observable.timer(1,TimeUnit.SECONDS)
  3. .subscribeOn(Schedulers.newThread())
  4. .observeOn(Schedulers.newThread())
  5. .subscribe(cache);
  6. //可以想象成上面是方法 这里是方法被调用
  7. cache.subscribe(o -> System.out.println(o));//结果0

Observable 发射元素的封装范例:

  
  
  1. //创建一个Observable 可以直接发送的 原因 获取rx内部方法需要final很恶心 所以...
  2. RxEmitter<Integer> emitter = new RxEmitter();
  3. Observable.create(emitter)
  4. .subscribe(integer -> System.out.println(integer));
  5. emitter.onNext(1);
  6. emitter.onNext(2);
  7. public class RxEmitter<T> implements ObservableOnSubscribe<T>, ObservableEmitter<T> {
  8. ObservableEmitter<T> e;
  9. @Override
  10. public void subscribe(ObservableEmitter<T> e) throws Exception {
  11. this.e = e;
  12. }
  13. @Override
  14. public void onNext(T value) {
  15. e.onNext(value);
  16. }
  17. @Override
  18. public void onError(Throwable error) {
  19. e.onError(error);
  20. }
  21. @Override
  22. public void onComplete() {
  23. e.onComplete();
  24. }
  25. @Override
  26. public void setDisposable(Disposable d) {
  27. e.setDisposable(d);
  28. }
  29. @Override
  30. public void setCancellable(Cancellable c) {
  31. e.setCancellable(c);
  32. }
  33. @Override
  34. public boolean isDisposed() {
  35. return e.isDisposed();
  36. }
  37. @Override
  38. public ObservableEmitter<T> serialize() {
  39. return e.serialize();
  40. }
  41. @Override
  42. public boolean tryOnError(Throwable t) {
  43. return e.tryOnError(t);
  44. }
  45. }

Reference&Thanks:

https://www.gitbook.com/book/mcxiaoke/rxdocs/details

基本上所有的都参考此文档 很神!

http://blog.csdn.net/maplejaw_/article/details/52396175

http://developer.51cto.com/art/201703/535298.htm

http://gank.io/post/560e15be2dca930e00da1083

https://github.com/amitshekhariitbhu/RxJava2-Android-Samples

http://www.jianshu.com/u/c50b715ccaeb

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值