RxJava操作符(二)

注:只包含標(biāo)準(zhǔn)包中的操作符,用于個(gè)人學(xué)習(xí)及備忘
參考博客:http://blog.csdn.net/maplejaw_/article/details/52396175

本篇將介紹rxjava中的錯(cuò)誤處理/重試機(jī)制、連接操作、阻塞操作以及工具集的使用,只針對用法不涉及原理,對RxJava不熟悉的可參考:http://gank.io/post/560e15be2dca930e00da1083

錯(cuò)誤處理 / 重試機(jī)制

  • onErrorResumeNext:當(dāng)原始的Observable在遇到錯(cuò)誤時(shí),使用備用的Observable

      Observable.just(1, 2, "3")
              .cast(Integer.class)    //強(qiáng)制轉(zhuǎn)換成Integer類型,強(qiáng)轉(zhuǎn)String類型數(shù)據(jù)時(shí)異常
              .onErrorResumeNext(new Func1<Throwable, Observable<? extends Integer>>() {
                  @Override
                  public Observable<? extends Integer> call(Throwable throwable) {
                      return Observable.just(4, 5, 6);
                  }
              })
              .subscribe(new Action1<Integer>() {
                  @Override
                  public void call(Integer integer) {
                      Log.d("debug", integer.toString()); //打印1,2,4,5,6
                  }
              });
    
      Observable.just(1, 2, "3")
              .cast(Integer.class)    //強(qiáng)制轉(zhuǎn)換成Integer類型,強(qiáng)轉(zhuǎn)String類型數(shù)據(jù)時(shí)異常
              .onErrorResumeNext(Observable.just(4, 5, 6))
              .subscribe(new Action1<Integer>() {
                  @Override
                  public void call(Integer integer) {
                      Log.d("debug", integer.toString()); //打印1,2,4,5,6
                  }
              });
    
  • onExceptionResumeNext:當(dāng)原始Observable在遇到異常時(shí),使用備用的Observable。與onErrorResumeNext類似,區(qū)別在于onErrorResumeNext可以處理所有的錯(cuò)誤,onExceptionResumeNext只能處理異常。

      Observable.just(1, 2, "3")
              .cast(Integer.class)    //強(qiáng)制轉(zhuǎn)換成Integer類型,強(qiáng)轉(zhuǎn)String類型數(shù)據(jù)時(shí)異常
              .onExceptionResumeNext(Observable.just(4, 5, 6))
              .subscribe(new Action1<Integer>() {
                  @Override
                  public void call(Integer integer) {
                      Log.d("debug", integer.toString()); //打印1,2,4,5,6
                  }
              });
    
  • onErrorReturn:當(dāng)原始Observable在遇到錯(cuò)誤時(shí)發(fā)射一個(gè)指定的數(shù)據(jù)

      Observable.just(1, 2, "3", 4)
              .cast(Integer.class)
              .onErrorReturn(new Func1<Throwable, Integer>() {
                  @Override
                  public Integer call(Throwable throwable) {
                      return 5;
                  }
              })
              .subscribe(new Action1<Integer>() {
                  @Override
                  public void call(Integer integer) {
                      Log.d("debug", integer.toString()); //打印1,2,5
                  }
              });
    
  • retry:當(dāng)原始的Observable在遇到錯(cuò)誤時(shí)進(jìn)行重試

      Observable.just(1, 2, "3", 4)
              .cast(Integer.class)
              .retry()    //默認(rèn)無限重試次數(shù)
              .observeOn(Schedulers.newThread())
              .subscribe(new Action1<Integer>() {
                  @Override
                  public void call(Integer integer) {
                      Log.d("debug", integer.toString()); //打印1,2,1,2,1,2 ...
                  }
              }, new Action1<Throwable>() {
                  @Override
                  public void call(Throwable throwable) {
                      Log.d("debug", "onError");
                  }
              });
    
      Observable.just(1, 2, "3", 4)
              .cast(Integer.class)
              .retry(2)    //設(shè)置最多重試2次
              .subscribe(new Action1<Integer>() {
                  @Override
                  public void call(Integer integer) {
                      Log.d("debug", integer.toString()); //打印1,2,1,2,1,2,onError
                  }
              }, new Action1<Throwable>() {
                  @Override
                  public void call(Throwable throwable) {
                      Log.d("debug", "onError");
                  }
              });
    
      Observable.just(1, 2, "3", 4)
              .cast(Integer.class)
              .retry(new Func2<Integer, Throwable, Boolean>() {
                  @Override
                  public Boolean call(Integer count, Throwable throwable) {
                      Log.d("debug", "count:" + count); //count表示是第幾次判斷是否重試
                      return count != 2;    //返回true表示重試,返回false表示終止
                  }
              })    
              .subscribe(new Action1<Integer>() {
                  @Override
                  public void call(Integer integer) {
                      Log.d("debug", integer.toString()); //打印1,2,count:1,1,2,count:2,onError
                  }
              }, new Action1<Throwable>() {
                  @Override
                  public void call(Throwable throwable) {
                      Log.d("debug", "onError");
                  }
              });
    
  • retryWhen:當(dāng)原始Observable在遇到錯(cuò)誤,將錯(cuò)誤傳遞給另一個(gè)Observable來決定是否要重新訂閱這個(gè)Observable,如果發(fā)送的是onCompleted或者onError事件,將不會(huì)觸發(fā)重訂閱。相對的,如果它發(fā)送onNext事件,則觸發(fā)重訂閱(不管onNext實(shí)際上是什么事件),內(nèi)部調(diào)用的是retry
    參考博客:http://www.cnblogs.com/resentment/p/5988241.html

      Observable.just(1, 2, "3", 4)
              .cast(Integer.class)
              //官方例子:第一次等待1秒重試,第二次等待2秒,第三次等待3秒,第四次停止重試
              .retryWhen(new Func1<Observable<? extends Throwable>, Observable<Long>>() {
                  @Override
                  public Observable<Long> call(Observable<? extends Throwable> observable) {
                      return observable.zipWith(Observable.range(1, 3), new Func2<Throwable, Integer, Integer>() {
                          @Override
                          public Integer call(Throwable throwable, Integer integer) {
                              return integer;
                          }
                      }).flatMap(new Func1<Integer, Observable<Long>>() {
                          @Override
                          public Observable<Long> call(Integer integer) {
                              return Observable.timer(integer,TimeUnit.SECONDS);
                          }
                      });
                  }
              })
              .subscribe(new Action1<Integer>() {
                  @Override
                  public void call(Integer integer) {
                      Log.d("debug", integer.toString()); //打印1,2,1,2,1,2,1,2
                  }
              }, new Action1<Throwable>() {
                  @Override
                  public void call(Throwable throwable) {
                      Log.d("debug", "onError");
                  }
              });
      /**
       * 注:輸入的Observable必須作為輸出Observable的源,必須對Observable<Throwable>做出反應(yīng),然后基于它發(fā)送事件。
       */
      Observable.just(1, 2, "3", 4)
              .subscribeOn(Schedulers.newThread())
              .cast(Integer.class)
              .retryWhen(new Func1<Observable<? extends Throwable>, Observable<?>>() {    //相當(dāng)于retry(),即無限重試
                  @Override
                  public Observable<?> call(Observable<? extends Throwable> observable) {
                      return observable;
                  }
              })
              .subscribe(new Action1<Integer>() {
                  @Override
                  public void call(Integer integer) {
                      Log.d("debug", integer.toString());
                  }
              }, new Action1<Throwable>() {
                  @Override
                  public void call(Throwable throwable) {
                      Log.d("debug", "onError");
                  }
              });
    
      Observable.just(1, 2, "3", 4)
              .cast(Integer.class)
              //重試3次,每次間隔1秒
              .retryWhen(new Func1<Observable<? extends Throwable>, Observable<?>>() {    
                  @Override
                  public Observable<?> call(Observable<? extends Throwable> observable) {
                      return observable.zipWith(Observable.interval(1, TimeUnit.SECONDS).take(3), new Func2<Throwable, Long, Long>() {
                          @Override
                          public Long call(Throwable throwable, Long aLong) {
                              return aLong;
                          }
                      });
                  }
              })
              .subscribe(new Action1<Integer>() {
                  @Override
                  public void call(Integer integer) {
                      Log.d("debug", integer.toString());  //打印1,2,1,2,1,2,1,2
                  }
              }, new Action1<Throwable>() {
                  @Override
                  public void call(Throwable throwable) {
                      Log.d("debug", "onError");
                  }
              });
    

連接操作

  • ConnectableObservable:可連接的Observable,一種特殊的Observable對象,不會(huì)在訂閱時(shí)就開始發(fā)射數(shù)據(jù),而是調(diào)用connect操作符時(shí)才開始發(fā)射數(shù)據(jù),可以用來靈活控制發(fā)射數(shù)據(jù)的時(shí)機(jī),需要注意的是,如果實(shí)在開始發(fā)射數(shù)據(jù)后再進(jìn)行訂閱,就只能接收到訂閱以后發(fā)射的數(shù)據(jù)

  • ConnectableObservable.connect():指示一個(gè)可連接的Observable開始發(fā)射數(shù)據(jù),沒有訂閱時(shí)也可發(fā)射數(shù)據(jù)

  • Observable.publish():將一個(gè)Observable轉(zhuǎn)換為可連接的Observable

  • ConnectableObservable.refCount():將一個(gè)可連接的Observable轉(zhuǎn)換成普通的Obervable

      /**
       * ConnectableObservable,ConnectableObservable轉(zhuǎn)換成的普通Observable,以及普通的Observable之間的比較
       */
    
      //第一種:ConnectableObservable
      new Thread(new Runnable() {
          @Override
          public void run() {
              ConnectableObservable<Long> co = Observable.interval(1, TimeUnit.SECONDS)
                      .take(3).publish();//轉(zhuǎn)換成可連接的Observable
    
              co.subscribe(new Action1<Long>() {
                  @Override
                  public void call(Long aLong) {
                      Log.d("debug", aLong.toString()); //沒有接收到數(shù)據(jù)
                  }
              });
    
              co.connect();   //開始發(fā)射數(shù)據(jù),第一個(gè)訂閱者接收到數(shù)據(jù),每秒打印一次,分別打印 0,1,2
    
              //延遲1.5秒后開始訂閱
              SystemClock.sleep(1500);
              co.subscribe(new Action1<Long>() {
                  @Override
                  public void call(Long aLong) {
                      Log.d("debug", aLong + 3 + ""); //只能接收到訂閱以后發(fā)射的數(shù)據(jù),打印4,5
                  }
              });
    
              //再延遲2.5秒后再次訂閱,此時(shí)數(shù)據(jù)已經(jīng)發(fā)送完畢
              SystemClock.sleep(2500);
              co.subscribe(new Action1<Long>() {
                  @Override
                  public void call(Long aLong) {
                      Log.d("debug", aLong + 6 + ""); //沒有接收到數(shù)據(jù)
                  }
              });
          }
      }).start();
    
      //第二種:ConnectableObservable轉(zhuǎn)換成的普通Observable
      new Thread(new Runnable() {
          @Override
          public void run() {
              ConnectableObservable<Long> co = Observable.interval(1, TimeUnit.SECONDS)
                      .take(3).publish();//轉(zhuǎn)換成可連接的Observable
    
              co.subscribe(new Action1<Long>() {
                  @Override
                  public void call(Long aLong) {
                      Log.d("debug", aLong.toString()); //沒有接收到數(shù)據(jù)
                  }
              });
    
              co.connect();   //開始發(fā)射數(shù)據(jù),第一個(gè)訂閱者接收到數(shù)據(jù),每秒打印一次,分別打印 0,1,2
    
              //延遲1.5秒后開始訂閱
              SystemClock.sleep(1500);
              co.refCount()   //轉(zhuǎn)換成普通Observable
                      .subscribe(new Action1<Long>() {
                          @Override
                          public void call(Long aLong) {
                              Log.d("debug", aLong + 3 + ""); //只能接收到訂閱以后發(fā)射的數(shù)據(jù),打印4,5
                          }
                      });
    
              //再延遲2.5后再次訂閱,此時(shí)數(shù)據(jù)已經(jīng)發(fā)送完畢
              SystemClock.sleep(2500);
              co.refCount()   //轉(zhuǎn)換成普通Observable
                      .subscribe(new Action1<Long>() {
                          @Override
                          public void call(Long aLong) {
                              Log.d("debug", aLong + 6 + ""); //Observable重新發(fā)送數(shù)據(jù),打印6,7,8
                          }
                      });
          }
      }).start();
    
      //第三種:普通的Observable
      new Thread(new Runnable() {
          @Override
          public void run() {
              Observable<Long> ob = Observable.interval(1, TimeUnit.SECONDS).take(3);
    
              ob.subscribe(new Action1<Long>() {
                  @Override
                  public void call(Long aLong) {
                      Log.d("debug", aLong.toString()); //打印0,1,2
                  }
              });
    
              //延遲1.5秒后開始訂閱
              SystemClock.sleep(1500);
              ob.subscribe(new Action1<Long>() {
                  @Override
                  public void call(Long aLong) {
                      Log.d("debug", aLong + 3 + ""); //Observable重新發(fā)射數(shù)據(jù),打印3,4,5
                  }
              });
    
              //再延遲2.5后再次訂閱,此時(shí)數(shù)據(jù)已經(jīng)發(fā)送完畢
              SystemClock.sleep(2500);
              ob.subscribe(new Action1<Long>() {
                  @Override
                  public void call(Long aLong) {
                      Log.d("debug", aLong + 6 + ""); //Observable重新發(fā)射數(shù)據(jù),打印6,7,8
                  }
              });
          }
      }).start();
    
  • Observable.replay():返回一個(gè)可連接的Observable,并且可以緩存其發(fā)射過的數(shù)據(jù),這樣即使有訂閱者在其發(fā)射數(shù)據(jù)之后進(jìn)行訂閱也能收到其之前發(fā)射過的數(shù)據(jù),使用時(shí)最好設(shè)置其緩存大小,避免占用太多內(nèi)存
    參考博客:http://blog.csdn.net/lizubing1992/article/details/51321422

//創(chuàng)建緩存2個(gè)數(shù)據(jù)的可連接的Observable
private ConnectableObservable<Long> relayCountObserver() {
    return Observable.interval(1, TimeUnit.SECONDS)
            .observeOn(Schedulers.newThread())
            .take(6)
            .replay(2);
}

//創(chuàng)建緩存3秒前的數(shù)據(jù)的可連接的Observable
private ConnectableObservable<Long> relayTimeObserver() {
    return Observable.interval(1, TimeUnit.SECONDS)
            .observeOn(Schedulers.newThread())
            .take(6)
            .replay(3, TimeUnit.SECONDS);
}

//創(chuàng)建緩存3秒前的最后2個(gè)數(shù)據(jù)的可連接的Observable
private ConnectableObservable<Long> relayTimeAndCountObserver() {
    return Observable.interval(1, TimeUnit.SECONDS)
            .observeOn(Schedulers.newThread())
            .take(6)
            .replay(2, 3, TimeUnit.SECONDS);
}

//創(chuàng)建兩個(gè)觀察者對可連接的Obserable進(jìn)行訂閱,第一個(gè)觀察者直接訂閱,
// 第二個(gè)觀察者在Observable發(fā)射4個(gè)數(shù)據(jù)后再進(jìn)行訂閱
private void subscribe(ConnectableObservable cb) {
    Action1<Long> action2 = new Action1<Long>() {
        @Override
        public void call(Long aLong) {
            Log.d("debug", "action2:" + aLong);
        }
    };

    Action1<Long> action1 = new Action1<Long>() {
        @Override
        public void call(Long aLong) {
            Log.d("debug", "action1:" + aLong);
            if (aLong == 3) {   //發(fā)射第4個(gè)數(shù)據(jù)時(shí)(即過了4秒),action2開始訂閱
                cb.subscribe(action2);
            }
        }
    };

    cb.subscribe(action1);
    cb.connect();
}

    //創(chuàng)建不同的可連接的Obserable進(jìn)行訂閱,并觀察打印結(jié)果
    //訂閱緩存兩個(gè)數(shù)據(jù)的可連接的Observable
    subscribe(relayCountObserver());
    /**
     * action1:打印0,1,2,3,4,5
     * action2:打印2,3,4,5(action2訂閱前已經(jīng)發(fā)射了4個(gè)數(shù)據(jù),即0,1,2,3,
     * 其中2,3被可連接的Observable緩存,因此可獲取到)
     */

    //訂閱緩存3秒的可連接的Observable
    subscribe(relayTimeObserver());
    /**
     * action1:打印0,1,2,3,4,5
     * action2:打印1,2,3,4,5(action2訂閱前已經(jīng)發(fā)射了4秒,可連接的Observable緩存了3秒內(nèi)的數(shù)據(jù),
     * 即1,2,3,因此可獲取到
     */

    //訂閱緩存3秒前最后2個(gè)數(shù)據(jù)的可連接的Observable
    subscribe(relayTimeAndCountObserver());
    /**
     * action1:打印0,1,2,3,4,5
     * action2:打印2,3,4,5(action2訂閱前已經(jīng)發(fā)射了4秒,3秒內(nèi)發(fā)射的數(shù)據(jù)為1,2,3,最后2位數(shù)據(jù)被
     * Observable緩存,即2,3,因此可獲取到
     */

阻塞操作

BlockingObservable:一個(gè)阻塞的Observable,普通的Observable可使用Observable.toBlocking(?)方法或者BlockingObservable.from(?)方法轉(zhuǎn)換成BlockingObservable

  • forEach:對BlockingObservable發(fā)射的每一項(xiàng)數(shù)據(jù)調(diào)用一個(gè)方法,會(huì)阻塞直到Observable完成

      Observable.interval(500, TimeUnit.MILLISECONDS,Schedulers.newThread())
              .take(3)
              .toBlocking()
              .forEach(new Action1<Long>() {
                  @Override
                  public void call(Long aLong) {
                      Log.d("debug", aLong.toString() + " " + Thread.currentThread().getName());
                  }
              });
      
      Log.d("debug", Thread.currentThread().getName());  //打印當(dāng)前線程名
      
      /**
       * 日志輸出:阻塞的Observable會(huì)在Observable完成前阻塞當(dāng)前線程
       * 0 RxNewThreadScheduler-1
       * 1 RxNewThreadScheduler-1
       * 2 RxNewThreadScheduler-1
       * main
       */
    

*first / firstOrDefault / last / lastOrDefault:這幾個(gè)操作符的用法與在普通的Observable中用法相同,用于阻塞操作時(shí)會(huì)直接返回發(fā)射的數(shù)據(jù)(使用first或last時(shí),找不到指定元素會(huì)報(bào)異常)

    Integer first = just(1, 2, 3).toBlocking().first();
    Log.d("debug", first.toString());   //打印1

    Integer first1 = just(1, 2, 3).toBlocking().first(new Func1<Integer, Boolean>() {
        @Override
        public Boolean call(Integer integer) {
            return integer > 2;
        }
    });
    Log.d("debug", first1.toString());  //打印3

    Integer first3 = Observable.just(1, 2, 3).toBlocking().firstOrDefault(4, new Func1<Integer, Boolean>() {
        @Override
        public Boolean call(Integer integer) {
            return integer > 3;
        }
    });
            
    Log.d("debug", first3.toString());  //打印4

    //last與lastOrDefault也是一樣,不重復(fù)了
  • single / singleOrDefault:如果Observable終止時(shí)只發(fā)射了一個(gè)值或者滿足條件的值只有一個(gè),返回那個(gè)值,否則拋出異?;蛘甙l(fā)射默認(rèn)值

      Integer single1 = Observable.just(1).toBlocking().single();
      Log.d("debug", single1.toString());     //打印1
    
      Integer single2 = Observable.just(1, 2, 3).toBlocking().single();
      Log.d("debug", single2.toString());     //報(bào)異常,發(fā)射的數(shù)據(jù)不止1個(gè)
    
      Integer single3 = Observable.from(new ArrayList<Integer>()).toBlocking().single();
      Log.d("debug", single3.toString());  //報(bào)異常,沒有發(fā)射數(shù)據(jù)
    
      Integer single4 = Observable.just(1, 2, 3).toBlocking().single(new Func1<Integer, Boolean>() {
          @Override
          public Boolean call(Integer integer) {
              return integer > 2;
          }
      });
      Log.d("debug", single4.toString());  //打印3
    
      Integer single5 = Observable.just(1, 2, 3).toBlocking().single(new Func1<Integer, Boolean>() {
          @Override
          public Boolean call(Integer integer) {
              return integer > 1;
          }
      });
      Log.d("debug", single5.toString());  //報(bào)異常,此時(shí)滿足條件的有2,3
    
      Integer singleOrDefault1 = Observable.just(1, 2, 3).toBlocking().singleOrDefault(5);
      Log.d("debug", singleOrDefault1.toString()); //報(bào)異常,發(fā)射多個(gè)數(shù)據(jù)時(shí)報(bào)異常
    
      Integer singleOrDefault2 = Observable.from(new ArrayList<Integer>()).toBlocking().singleOrDefault(5);
      Log.d("debug", singleOrDefault2.toString());  //打印5,沒有發(fā)射數(shù)據(jù)時(shí)發(fā)射默認(rèn)值
    
  • mostRecent:返回一個(gè)Iterable,Iterable返回的值總為Observable最后發(fā)射的數(shù)據(jù),Observable未發(fā)射數(shù)據(jù)前總返回一個(gè)指定的默認(rèn)值,Observable結(jié)束后不再返回

      new Thread(new Runnable() {
          @Override
          public void run() {
              BlockingObservable<Integer> blockingObservable = Observable.create(new Observable.OnSubscribe<Integer>() {
                  @Override
                  public void call(Subscriber<? super Integer> subscriber) {
                      SystemClock.sleep(1000);
                      subscriber.onNext(1);
                      SystemClock.sleep(1000);
                      subscriber.onNext(2);
                      SystemClock.sleep(1000);
                      subscriber.onNext(3);
                      SystemClock.sleep(1000);
                      subscriber.onCompleted();
                  }
              }).subscribeOn(Schedulers.newThread()).toBlocking();
              Iterable<Integer> integers = blockingObservable.mostRecent(4);
              for (Integer integer : integers) {
                  Log.d("debug", integer.toString());
                  SystemClock.sleep(500);     //打印4,4,1,1,2,2,3,3
              }
          }
      }).start();
    
  • next:返回一個(gè)Iterable,每當(dāng)Iterable準(zhǔn)備返回一個(gè)值時(shí),都會(huì)阻塞直到Observable發(fā)射下一個(gè)數(shù)據(jù),然后返回這個(gè)值

      new Thread(new Runnable() {
          @Override
          public void run() {
              BlockingObservable<Integer> blockingObservable = Observable.create(new Observable.OnSubscribe<Integer>() {
                  @Override
                  public void call(Subscriber<? super Integer> subscriber) {
                      SystemClock.sleep(1000);
                      subscriber.onNext(1);
                      SystemClock.sleep(1000);
                      subscriber.onNext(2);
                      SystemClock.sleep(1000);
                      subscriber.onNext(3);
                      SystemClock.sleep(1000);
                      subscriber.onCompleted();
                  }
              }).subscribeOn(Schedulers.newThread()).toBlocking();
              Iterable<Integer> integers = blockingObservable.next();
              Iterator<Integer> iterator = integers.iterator();
    
              long startTime = System.currentTimeMillis();  //開始時(shí)間
    
              Integer next1 = iterator.next();    //阻塞了1秒
              Log.d("debug", System.currentTimeMillis() - startTime + ":" + next1);   //打印1003:1
    
              Integer next2 = iterator.next();
              Log.d("debug", System.currentTimeMillis() - startTime + ":" + next2);   //打印2004:2
    
              Integer next3 = iterator.next();
              Log.d("debug", System.currentTimeMillis() - startTime + ":" + next3);   //打印3004:3
          }
      }).start();
    
  • latest:返回一個(gè)Iterable,與next()操作符類似,但是它不會(huì)阻塞等待下一個(gè)值,而是立即返回最近發(fā)射的數(shù)據(jù)項(xiàng),只在Observable未發(fā)出時(shí)阻塞

      new Thread(new Runnable() {
          @Override
          public void run() {
              Iterable<Integer> latest = Observable.create(new Observable.OnSubscribe<Integer>() {
                  @Override
                  public void call(Subscriber<? super Integer> subscriber) {
                      SystemClock.sleep(1000);
                      subscriber.onNext(1);
                      SystemClock.sleep(1000);
                      subscriber.onNext(2);
                      SystemClock.sleep(1000);
                      subscriber.onNext(3);
                      SystemClock.sleep(1000);
                      subscriber.onCompleted();
                  }
              }).subscribeOn(Schedulers.newThread()).toBlocking().latest();
    
              Iterator<Integer> iterator = latest.iterator();
              long startTime = System.currentTimeMillis();
    
              Integer next1 = iterator.next();    //阻塞了1秒
              Log.d("debug", System.currentTimeMillis() - startTime + ":" + next1);   //打印1003:1
    
              Integer next2 = iterator.next();
              Log.d("debug", System.currentTimeMillis() - startTime + ":" + next2);   //打印2004:2
    
              Integer next3 = iterator.next();
              Log.d("debug", System.currentTimeMillis() - startTime + ":" + next3);   //打印3004:3
          }
      }).start();
    
  • toIterable:將一個(gè)發(fā)射數(shù)據(jù)序列的Observable轉(zhuǎn)換為一個(gè)Iterable,通過這個(gè)Iterable可獲取到Observable發(fā)射的所有數(shù)據(jù),每當(dāng)Iterable準(zhǔn)備返回一個(gè)值時(shí),如果Observable未發(fā)射該項(xiàng)數(shù)據(jù),則阻塞直到Observable發(fā)射并返回該值,如果Observable已發(fā)射該項(xiàng)數(shù)據(jù),則直接返回(與next, latest之間的差異見下面代碼)

      BlockingObservable<Integer> blockingObservable = Observable.create(new Observable.OnSubscribe<Integer>() {
          @Override
          public void call(Subscriber<? super Integer> subscriber) {
              SystemClock.sleep(1000);
              subscriber.onNext(1);
              SystemClock.sleep(1000);
              subscriber.onNext(2);
              SystemClock.sleep(1000);
              subscriber.onNext(3);
              SystemClock.sleep(1000);
              subscriber.onCompleted();
          }
      }).subscribeOn(Schedulers.newThread()).toBlocking();
    
      new Thread(new Runnable() {
          @Override
          public void run() {
              Iterable<Integer> iterable  = blockingObservable.toIterable();
    
              Iterator<Integer> iterator = iterable.iterator();
              long startTime = System.currentTimeMillis();
    
              Integer next1 = iterator.next();    //阻塞了1秒
              Log.d("debug", System.currentTimeMillis() - startTime + ":" + next1);   //打印1003:1
    
              SystemClock.sleep(3000);    //等待3秒,此時(shí)Observable的數(shù)據(jù)已經(jīng)全部發(fā)射完成
    
              Integer next2 = iterator.next();    //直接返回
              Log.d("debug", System.currentTimeMillis() - startTime + ":" + next2);   //打印4002:2
    
              Integer next3 = iterator.next();    //直接返回
              Log.d("debug", System.currentTimeMillis() - startTime + ":" + next3);   //打印4004:3
          }
      }).start();
    
      new Thread(new Runnable() {
          @Override
          public void run() {
              Iterable<Integer> integers = blockingObservable.next();
              Iterator<Integer> iterator = integers.iterator();
    
              long startTime = System.currentTimeMillis();  //開始時(shí)間
    
              Integer next1 = iterator.next();    //阻塞了1秒
              Log.d("debug", System.currentTimeMillis() - startTime + ":" + next1);   //打印1003:1
    
              SystemClock.sleep(1500);    //阻塞1.2秒,此時(shí)數(shù)據(jù)2發(fā)射完成,數(shù)據(jù)3未發(fā)射
    
              Integer next2 = iterator.next();
              //(next返回的是Observable最近發(fā)射數(shù)據(jù)的下一個(gè)數(shù)據(jù),下個(gè)數(shù)據(jù)發(fā)射完成前進(jìn)行阻塞)
              Log.d("debug", System.currentTimeMillis() - startTime + ":" + next2);   //打印3004:3
          }
      }).start();
    
      new Thread(new Runnable() {
          @Override
          public void run() {
              Iterable<Integer> integers = blockingObservable.latest();
              Iterator<Integer> iterator = integers.iterator();
    
              long startTime = System.currentTimeMillis();  //開始時(shí)間
    
              Integer next1 = iterator.next();    //阻塞了1秒
              Log.d("debug", System.currentTimeMillis() - startTime + ":" + next1);   //打印1001:1
    
              SystemClock.sleep(2500);    //阻塞2.5秒,此時(shí)數(shù)據(jù)2和3發(fā)射完成
    
              Integer next2 = iterator.next();
              //(latest返回的是Observable最近發(fā)射的數(shù)據(jù),數(shù)據(jù)未發(fā)射時(shí)進(jìn)行阻塞)
              Log.d("debug", System.currentTimeMillis() - startTime + ":" + next2);   //打印3501:3
          }
      }).start();
    
  • getIterator:與toIterable類似,返回的是一個(gè)Iterator,不重復(fù)了

  • toFuture:將Observable轉(zhuǎn)換為一個(gè)返回單個(gè)數(shù)據(jù)項(xiàng)的Future,如果原始Observable發(fā)射多個(gè)數(shù)據(jù)項(xiàng),F(xiàn)uture會(huì)收到一個(gè)IllegalArgumentException;如果原始Observable沒有發(fā)射任何數(shù)據(jù),F(xiàn)uture會(huì)收到一個(gè)NoSuchElementException

      Future<Integer> future = Observable.just(1).toBlocking().toFuture();
      try {
          Integer integer = future.get();
          Log.d("debug", integer.toString()); //打印1
      } catch (Exception e) {
          e.printStackTrace();
      }
    

工具集

  • materialize: 將Observable轉(zhuǎn)換成一個(gè)通知列表

      Observable.just(1,2,3)
              .materialize()
              .subscribe(new Action1<Notification<Integer>>() {
                  @Override
                  public void call(Notification<Integer> integerNotification) {
                      Log.d("debug", integerNotification.getKind() + " " + integerNotification.getValue());
                      /**
                       * 打印
                       * OnNext 1
                       * OnNext 2
                       * OnNext 3
                       * OnCompleted null
                       */
                  }
              });
    
  • dematerialize:與materialize作用相反,將通知逆轉(zhuǎn)成一個(gè)Observable

      Observable.just(1, 2, 3)
              .materialize()      //轉(zhuǎn)換成通知列表
              .dematerialize()    //逆轉(zhuǎn)回Observable
              .subscribe(new Action1<Object>() {
                  @Override
                  public void call(Object o) {
                      Log.d("debug", o.toString());   //打印1,2,3
                  }
              });
    
  • timestamp:給Observable發(fā)射的每個(gè)數(shù)據(jù)項(xiàng)添加一個(gè)時(shí)間戳

      Observable.just(1, 2, 3)
              .timestamp()
              .subscribe(new Action1<Timestamped<Integer>>() {
                  @Override
                  public void call(Timestamped<Integer> integerTimestamped) {
                      Log.d("debug", integerTimestamped.getTimestampMillis() + " " + integerTimestamped.getValue());
                      /**
                       * 打印
                       * 1506740662707 1
                       * 1506740662707 2
                       * 1506740662708 3
                       */
                  }
              });
    
  • serialize:強(qiáng)制Observable按次序發(fā)射數(shù)據(jù)并且要求功能是完好的

  • cache:緩存Observable發(fā)射的數(shù)據(jù)序列并發(fā)射相同的數(shù)據(jù)序列給后續(xù)的訂閱者

      new Thread(new Runnable() {
          @Override
          public void run() {
              Observable<Long> cache = Observable.interval(500, TimeUnit.MILLISECONDS)
                      .take(4)
                      .cache();
    
              cache.subscribe(new Action1<Long>() {
                  @Override
                  public void call(Long aLong) {
                      Log.d("debug", aLong.toString());   //打印0,1,2,3
                  }
              });
    
              SystemClock.sleep(1200);
              cache.subscribe(new Action1<Long>() {
                  @Override
                  public void call(Long aLong) {
                      Log.d("debug", aLong.toString());   //打印0,1,2,3
                  }
              });
          }
      }).start();
    
  • observeOn:指定觀察者觀察Observable的調(diào)度器

  • subscribeOn:指定Observable執(zhí)行任務(wù)的調(diào)度器

  • doOnEach:注冊一個(gè)動(dòng)作,對Observable發(fā)射的每個(gè)數(shù)據(jù)項(xiàng)使用

      Observable.just(1, 2, 3)
              .doOnEach(new Observer<Integer>() {
                  @Override
                  public void onCompleted() {
                      Log.d("debug", "doOnEach: onCompleted");
                  }
    
                  @Override
                  public void onError(Throwable e) {
                      Log.d("debug", "doOnEach: onError");
                  }
    
                  @Override
                  public void onNext(Integer integer) {
                      Log.d("debug", "doOnEach: onNext " + integer);
                  }
              })
              .subscribe(new Action1<Integer>() {
                  @Override
                  public void call(Integer integer) {
                      Log.d("debug", integer.toString());
                  }
              });
      /**
       * 打印
       * doOnEach: onNext 1
       * 1
       * doOnEach: onNext 2
       * 2
       * doOnEach: onNext 3
       * 3
       * doOnEach: onCompleted
       */
    
      Observable.just(1, 2, 3)
              .doOnEach(new Action1<Notification<? super Integer>>() {
                  @Override
                  public void call(Notification<? super Integer> notification) {
                      Log.d("debug", "doOnEach: " + notification.getKind() + " " + notification.getValue());
                  }
              })
              .subscribe(new Action1<Integer>() {
                  @Override
                  public void call(Integer integer) {
                      Log.d("debug", integer.toString());
                  }
              });
      /**
       * 打印
       * doOnEach: onNext 1
       * 1
       * doOnEach: onNext 2
       * 2
       * doOnEach: onNext 3
       * 3
       * doOnEach: onCompleted null
       */
    
  • doOnCompleted:注冊一個(gè)動(dòng)作,對正常完成的Observable使用(即在OnCompleted)

  • doOnError:注冊一個(gè)動(dòng)作,對發(fā)生錯(cuò)誤的Observable使用(即在OnError)

  • doOnTerminate:注冊一個(gè)動(dòng)作,對完成的Observable使用,無論是否發(fā)生錯(cuò)誤

  • doOnSubscribe:注冊一個(gè)動(dòng)作,在觀察者訂閱時(shí)使用(可通過subscribeOn指定發(fā)生的線程)

  • doOnUnsubscribe: 注冊一個(gè)動(dòng)作,在觀察者取消訂閱時(shí)使用

  • finallyDo / doAfterTerminate: 注冊一個(gè)動(dòng)作,在Observable完成時(shí)使用

  • delay:延時(shí)發(fā)射Observable的結(jié)果。即讓原始Observable在發(fā)射每項(xiàng)數(shù)據(jù)之前都暫停一段指定的時(shí)間段。效果是Observable發(fā)射的數(shù)據(jù)項(xiàng)在時(shí)間上向前整體平移了一個(gè)增量(除了onError,它會(huì)即時(shí)通知)

  • delaySubscription:延時(shí)處理訂閱請求

  • using:創(chuàng)建一個(gè)只在Observable生命周期存在的資源,當(dāng)Observable終止時(shí)這個(gè)資源會(huì)被自動(dòng)釋放

      Observable.using(new Func0<File>() {//資源工廠
          @Override
          public File call() {  //創(chuàng)建資源
    
              File file = new File(getCacheDir(), "a.txt");
              if (!file.exists()) {
                  try {
                      Log.d("debug", "--create--");
                      file.createNewFile();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
              return file;
          }
      }, new Func1<File, Observable<String>>() { //返回生成的Observable
          @Override
          public Observable<String> call(File file) {
              return Observable.just(file.exists() ? "exist" : "no exist");
          }
      }, new Action1<File>() {//釋放資源動(dòng)作
          @Override
          public void call(File file) {
              if (file != null && file.exists()) {
                  Log.d("debug", "--delete--");
                  file.delete();
              }
          }
      })
              .subscribe(new Action1<String>() {
                  @Override
                  public void call(String s) {
                      Log.d("debug", s);
                  }
              });
    
      /**
       * 打印
       * --create--
       * exist
       * --delete--
       */
    
  • single / singleOrDefault:強(qiáng)制返回單個(gè)數(shù)據(jù),與阻塞操作中的single基本相同,Observable發(fā)射多個(gè)數(shù)據(jù)時(shí)拋出異常,沒有發(fā)射數(shù)據(jù)時(shí),single拋出異常,singleOrDefault則返回默認(rèn)數(shù)據(jù)

最后

Rxjava標(biāo)準(zhǔn)庫的操作符已經(jīng)介紹完畢

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,572評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,071評論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,409評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,569評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,360評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,895評論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,979評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,123評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,643評論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,559評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,742評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,250評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 43,981評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,363評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,622評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,354評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,707評論 2 370

推薦閱讀更多精彩內(nèi)容

  • 注:只包含標(biāo)準(zhǔn)包中的操作符,用于個(gè)人學(xué)習(xí)及備忘參考博客:http://blog.csdn.net/maplejaw...
    小白要超神閱讀 2,209評論 2 8
  • 作者: maplejaw本篇只解析標(biāo)準(zhǔn)包中的操作符。對于擴(kuò)展包,由于使用率較低,如有需求,請讀者自行查閱文檔。 創(chuàng)...
    maplejaw_閱讀 45,723評論 8 93
  • 創(chuàng)建unfaseCreate(create)創(chuàng)建一個(gè)Observable(被觀察者),當(dāng)被觀察者(Observer...
    chuwe1閱讀 7,020評論 3 8
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,776評論 18 139
  • 三月的蒲公英 緩緩在飛 這場風(fēng)足足刮了七個(gè)春天 有人面向風(fēng) 祈禱雨 我一開始就知道 無論急或緩 風(fēng)是如何都停不下來...
    我是趙眠閱讀 314評論 0 0