Android - RxJava2.0 操作符整理歸納

老婆保佑,代碼無BUG

目錄

  • 一:創建操作
  • 二:合并操作
  • 三:過濾操作
  • 四:切換線程
  • 五:條件/布爾操作
  • 六:聚合操作
  • 七:轉換操作
  • 八:變換操作
  • 九:錯誤處理/重試機制
  • 十:連接操作
  • 十一:阻塞操作
  • 十二:工具集
  • 十三:Flowable (2.0出來的) 非操作符

前言

RxJava,這個詞,如果是android 開發的小伙伴,估計早就聽過不知道多少遍了,如果你對RxJava 一點都不了解,推薦RxJava 入門 拋物線寫的會讓你對RxJava,有個認識,本文只要是記錄操作符,畢竟太多了,記不住啊

一:創建操作

create

Observable.create(new Observable.OnSubscribe<String>() {

        @Override
        public void call(Subscriber<? super String> subscriber) {

            subscriber.onNext("item1");
            subscriber.onNext("item2");
            subscriber.onCompleted();
        }
    });

just

Observable observable = Observable.just("Hello", "Hi", "Aloha");
// 將會依次調用:
// onNext("Hello");
// onNext("Hi");
// onNext("Aloha");
// onCompleted();

from

String[] words = {"Hello", "Hi", "Aloha"};
Observable observable = Observable.from(words);
// 將會依次調用:
// onNext("Hello");
// onNext("Hi");
// onNext("Aloha");
// onCompleted();

empty

創建一個什么都不做直接通知完成的Observable

error

創建一個什么都不做直接通知錯誤的Observable

never

創建一個什么都不做的Observable

Observable observable1=Observable.empty();//直接調用onCompleted。
Observable observable2=Observable.error(new RuntimeException());//直接調用onError。這里可以自定義異常
Observable observable3=Observable.never();//啥都不做

timer

創建一個在給定的延時之后

Observable.timer(1000,TimeUnit.MILLISECONDS)
            .subscribe(new Action1<Long>() {
                @Override
                public void call(Long aLong) {
                    Log.d("JG",aLong.toString()); // 0
                }
            });

interval

創建一個按照給定的時間間隔發射從0開始的整數序列的

Observable.interval(1, TimeUnit.SECONDS)
            .subscribe(new Action1<Long>() {
                @Override
                public void call(Long aLong) {
                     //每隔1秒發送數據項,從0開始計數
                     //0,1,2,3....
                }
            });

range:

創建一個發射指定范圍的整數序列的Observable<Integer>

Observable.range(2,5).subscribe(new Action1<Integer>() {
        @Override
        public void call(Integer integer) {
            Log.d("JG",integer.toString());// 2,3,4,5,6 從2開始發射5個數據
        }
    });

defer

只有當訂閱者訂閱才創建Observable,為每個訂閱創建一個新的Observable。內部通過OnSubscribeDefer在訂閱時調用Func0創建Observable。

Observable.defer(new Func0<Observable<String>>() {
        @Override
        public Observable<String> call() {
            return Observable.just("hello");
        }
    }).subscribe(new Action1<String>() {
        @Override
        public void call(String s) {
            Log.d("JG",s);
        }
    });

二:合并操作

concat

按順序連接多個Observables。需要注意的是Observable.concat(a,b)等價于a.concatWith(b)。

Observable<Integer> observable1=Observable.just(1,2,3,4);
    Observable<Integer>  observable2=Observable.just(4,5,6);

    Observable.concat(observable1,observable2)
            .subscribe(item->Log.d("JG",item.toString()));//1,2,3,4,4,5,6

startWith

在數據序列的開頭增加一項數據。startWith的內部也是調用了concat

 Observable.just(1,2,3,4,5)
            .startWith(6,7,8)
    .subscribe(item->Log.d("JG",item.toString()));//6,7,8,1,2,3,4,5

merge

將多個Observable合并為一個。不同于concat,merge不是按照添加順序連接,而是按照時間線來連接。其中mergeDelayError將異常延遲到其它沒有錯誤的Observable發送完畢后才發射。而merge則是一遇到異常將停止發射數據,發送onError通知。

image

zip

使用一個函數組合多個Observable發射的數據集合,然后再發射這個結果。如果多個Observable發射的數據量不一樣,則以最少的Observable為標準進行壓合。內部通過OperatorZip進行壓合

image
Observable<Integer>  observable1=Observable.just(1,2,3,4);
Observable<Integer>  observable2=Observable.just(4,5,6);
    Observable.zip(observable1, observable2, new Func2<Integer, Integer, String>() {
        @Override
        public String call(Integer item1, Integer item2) {
            return item1+"and"+item2;
        }
    })
    .subscribe(item->Log.d("JG",item)); //1and4,2and5,3and6

combineLatest

當兩個Observables中的任何一個發射了一個數據時,通過一個指定的函數組合每個Observable發射的最新數據(一共兩個數據),然后發射這個函數的結果。類似于zip,但是,不同的是zip只有在每個Observable都發射了數據才工作,而combineLatest任何一個發射了數據都可以工作,每次與另一個Observable最近的數據壓合。具體請看下面流程圖。
zip工作流程

image

三:過濾操作

filter

過濾數據。內部通過OnSubscribeFilter過濾數據。

Observable.just(3,4,5,6)
            .filter(new Func1<Integer, Boolean>() {
                @Override
                public Boolean call(Integer integer) {
                    return integer>4;
                }
            })
    .subscribe(item->Log.d("JG",item.toString())); //5,6

ofType

過濾指定類型的數據,與filter類似,

Observable.just(1,2,"3")
            .ofType(Integer.class)
            .subscribe(item -> Log.d("JG",item.toString()));

take

只發射開始的N項數據或者一定時間內的數據。內部通過OperatorTake和OperatorTakeTimed過濾數據。

Observable.just(3,4,5,6)
            .take(3)//發射前三個數據項
            .take(100, TimeUnit.MILLISECONDS)//發射100ms內的數據

takeLast

只發射最后的N項數據或者一定時間內的數據。內部通過OperatorTakeLast和OperatorTakeLastTimed過濾數據。takeLastBuffer和takeLast類似,不同點在于takeLastBuffer會收集成List后發射。

 Observable.just(3,4,5,6)
            .takeLast(3)
            .subscribe(integer -> Log.d("JG",integer.toString()));//4,5,6

first/firstOrDefault:

只發射第一項(或者滿足某個條件的第一項)數據,可以指定默認值。

Observable.just(3,4,5,6)
            .first()
            .subscribe(integer -> Log.d("JG",integer.toString()));//3
            
Observable.just(3,4,5,6)
            .first(new Func1<Integer, Boolean>() {
                @Override
                 public Boolean call(Integer integer) {
                     return integer>3;
                 }
             }) .subscribe(integer -> Log.d("JG",integer.toString()));//4

last/lastOrDefault:

只發射最后一項(或者滿足某個條件的最后一項)數據,可以指定默認值。

skip

跳過開始的N項數據或者一定時間內的數據。內部通過OperatorSkip和OperatorSkipTimed實現過濾。

Observable.just(3,4,5,6)
               .skip(1)
            .subscribe(integer -> Log.d("JG",integer.toString()));//4,5,6

skipLast

跳過最后的N項數據或者一定時間內的數據。內部通過OperatorSkipLast和OperatorSkipLastTimed實現過濾。

        Observable.just(3,4,5,6)
                 .elementAt(2)
        .subscribe(item->Log.d("JG",item.toString())); //5

ignoreElements

丟棄所有數據,只發射錯誤或正常終止的通知。內部通過OperatorIgnoreElements實現。

distinct

過濾重復數據,內部通過OperatorDistinct實現。

 Observable.just(3,4,5,6,3,3,4,9)
       .distinct()
      .subscribe(item->Log.d("JG",item.toString())); //3,4,5,6,9

distinctUntilChanged

過濾掉連續重復的數據。內部通過OperatorDistinctUntilChanged實現

 Observable.just(3,4,5,6,3,3,4,9)
       .distinctUntilChanged()
      .subscribe(item->Log.d("JG",item.toString())); //3,4,5,6,3,4,9

throttleFirst:

定期發射Observable發射的第一項數據。內部通過OperatorThrottleFirst實現。

Observable.create(subscriber -> {
        subscriber.onNext(1);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw Exceptions.propagate(e);
        }
        subscriber.onNext(2);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw Exceptions.propagate(e);
        }

        subscriber.onNext(3);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw Exceptions.propagate(e);
        }
        subscriber.onNext(4);
        subscriber.onNext(5);
        subscriber.onCompleted();

    }).throttleFirst(999, TimeUnit.MILLISECONDS)
            .subscribe(item-> Log.d("JG",item.toString())); //結果為1,3,4

throttleWithTimeout/debounce:

發射數據時,如果兩次數據的發射間隔小于指定時間,就會丟棄前一次的數據,直到指定時間內都沒有新數據發射時
才進行發射

Observable.create(subscriber -> {
         subscriber.onNext(1);
         try {
             Thread.sleep(500);
         } catch (InterruptedException e) {
             throw Exceptions.propagate(e);
         }
         subscriber.onNext(2);
         try {
             Thread.sleep(500);
         } catch (InterruptedException e) {
             throw Exceptions.propagate(e);
         }

         subscriber.onNext(3);
         try {
             Thread.sleep(1000);
         } catch (InterruptedException e) {
             throw Exceptions.propagate(e);
         }
         subscriber.onNext(4);
         subscriber.onNext(5);
         subscriber.onCompleted();

     }).debounce(999, TimeUnit.MILLISECONDS)//或者為throttleWithTimeout(1000, TimeUnit.MILLISECONDS)
             .subscribe(item-> Log.d("JG",item.toString())); //結果為3,5

sample/throttleLast:

定期發射Observable最近的數據。內部通過OperatorSampleWithTime實現。

 Observable.create(subscriber -> {
        subscriber.onNext(1);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw Exceptions.propagate(e);
        }
        subscriber.onNext(2);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw Exceptions.propagate(e);
        }

        subscriber.onNext(3);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw Exceptions.propagate(e);
        }
        subscriber.onNext(4);
        subscriber.onNext(5);
        subscriber.onCompleted();

    }).sample(999, TimeUnit.MILLISECONDS)//或者為throttleLast(1000, TimeUnit.MILLISECONDS)
            .subscribe(item-> Log.d("JG",item.toString())); //結果為2,3,5
            

timeout:

如果原始Observable過了指定的一段時長沒有發射任何數據,就發射一個異常或者使用備用的Observable。

   Observable.create(( subscriber) -> {
        subscriber.onNext(1);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw Exceptions.propagate(e);
        }
        subscriber.onNext(2);
       
        subscriber.onCompleted();

    }).timeout(999, TimeUnit.MILLISECONDS,Observable.just(99,100))//如果不指定備用Observable將會拋出異常
            .subscribe(item-> Log.d("JG",item.toString()),error->Log.d("JG","onError")); //結果為1,99,100  如果不指定備用Observable結果為1,onError
}

四:切換線程

.subscribeOn(Schedulers.newThread())                                              
.observeOn(AndroidSchedulers.mainThread())
  • subscribeOn
    • 發送事件的線程
  • observeOn
    • 接收事件的線程

線程選項

  • Schedulers.io()
    • 代表io操作的線程, 通常用于網絡,讀寫文件等io密集型的操作
  • Schedulers.computation()
    • 代表CPU計算密集型的操作, 例如需要大量計算的操作
  • Schedulers.newThread()
    • 代表一個常規的新線程
  • AndroidSchedulers.mainThread()
    • 代表Android的主線程

五:條件/布爾操作

all:

判斷所有的數據項是否滿足某個條件,內部通過OperatorAll實現。

  Observable.just(2,3,4,5)
            .all(new Func1<Integer, Boolean>() {
                @Override
                public Boolean call(Integer integer) {
                    return integer>3;
                }
            })
    .subscribe(new Action1<Boolean>() {
        @Override
        public void call(Boolean aBoolean) {
            Log.d("JG",aBoolean.toString()); //false
        }
    });

exists:

判斷是否存在數據項滿足某個條件。內部通過OperatorAny實現。

   Observable.just(2,3,4,5)
            .exists(integer -> integer>3)
            .subscribe(aBoolean -> Log.d("JG",aBoolean.toString())); //true

contains:

判斷在發射的所有數據項中是否包含指定的數據,內部調用的其實是exists

  Observable.just(2,3,4,5)
            .contains(3)
            .subscribe(aBoolean -> Log.d("JG",aBoolean.toString())); //true
        

sequenceEqual:

用于判斷兩個Observable發射的數據是否相同(數據,發射順序,終止狀態)。

 Observable.sequenceEqual(Observable.just(2,3,4,5),Observable.just(2,3,4,5))
            .subscribe(aBoolean -> Log.d("JG",aBoolean.toString()));//true

isEmpty:

用于判斷Observable發射完畢時,有沒有發射數據。有數據false,如果只收到了onComplete通知則為true。

  Observable.just(3,4,5,6)
               .isEmpty()
              .subscribe(item -> Log.d("JG",item.toString()));//false
              

amb:

給定多個Observable,只讓第一個發射數據的Observable發射全部數據,其他Observable將會被忽略。

    Observable<Integer> observable1=Observable.create(new Observable.OnSubscribe<Integer>() {
        @Override
        public void call(Subscriber<? super Integer> subscriber) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                subscriber.onError(e);
            }
            subscriber.onNext(1);
            subscriber.onNext(2);
            subscriber.onCompleted();
        }
    }).subscribeOn(Schedulers.computation());

    Observable<Integer> observable2=Observable.create(subscriber -> {
        subscriber.onNext(3);
        subscriber.onNext(4);
        subscriber.onCompleted();
    });

    Observable.amb(observable1,observable2)
    .subscribe(integer -> Log.d("JG",integer.toString())); //3,4
    

switchIfEmpty:

如果原始Observable正常終止后仍然沒有發射任何數據,就使用備用的Observable。

   Observable.empty()
            .switchIfEmpty(Observable.just(2,3,4))
    .subscribe(o -> Log.d("JG",o.toString())); //2,3,4
    

defaultIfEmpty:

如果原始Observable正常終止后仍然沒有發射任何數據,就發射一個默認值,內部調用的switchIfEmpty。

takeUntil:

當發射的數據滿足某個條件后(包含該數據),或者第二個Observable發送完畢,終止第一個Observable發送數據。

 Observable.just(2,3,4,5)
            .takeUntil(new Func1<Integer, Boolean>() {
                @Override
                public Boolean call(Integer integer) {
                    return integer==4;
                }
            }).subscribe(integer -> Log.d("JG",integer.toString())); //2,3,4

takeWhile:

當發射的數據滿足某個條件時(不包含該數據),Observable終止發送數據。

  Observable.just(2,3,4,5)
            .takeWhile(new Func1<Integer, Boolean>() {
                @Override
                public Boolean call(Integer integer) {
                    return integer==4;
                }
            })
            .subscribe(integer -> Log.d("JG",integer.toString())); //2,3
            

skipUntil:

丟棄Observable發射的數據,直到第二個Observable發送數據。(丟棄條件數據)

skipWhile:

丟棄Observable發射的數據,直到一個指定的條件不成立(不丟棄條件數據)

六:聚合操作

reduce:

對序列使用reduce()函數并發射最終的結果,內部使用OnSubscribeReduce實現。

  Observable.just(2,3,4,5)
            .reduce(new Func2<Integer, Integer, Integer>() {
                @Override
                public Integer call(Integer sum, Integer item) {
                    return sum+item;
                }
            })
            .subscribe(integer -> Log.d("JG",integer.toString()));//14
            

collect:

使用collect收集數據到一個可變的數據結構。

  Observable.just(3,4,5,6)
               .collect(new Func0<List<Integer>>() { //創建數據結構

                   @Override
                   public List<Integer> call() {
                       return new ArrayList<Integer>();
                   }
               }, new Action2<List<Integer>, Integer>() { //收集器
                   @Override
                   public void call(List<Integer> integers, Integer integer) {
                       integers.add(integer);
                   }
               })
              .subscribe(new Action1<List<Integer>>() {
                  @Override
                  public void call(List<Integer> integers) {
                      
                  }
              });
              

count/countLong:

計算發射的數量,內部調用的是reduce.

doOnNext()

允許我們在每次輸出一個元素之前做一些額外的事情。

Observable.just(list).flatMap(new Function<List<String>, ObservableSource<?>>() {
            @Override
            public ObservableSource<?> apply(List<String> strings) throws Exception {
                return Observable.fromIterable(strings);
            }
        }).take(5).doOnNext(new Consumer<Object>() {
            @Override
            public void accept(Object o) throws Exception {
                System.out.println("準備工作");
            }
        }).subscribe(new Consumer<Object>() {
            @Override
            public void accept(Object s) throws Exception {
                System.out.println((String)s);
            }
        });


七:轉換操作

toList:

收集原始Observable發射的所有數據到一個列表,然后返回這個列表.

    Observable.just(2,3,4,5)
            .toList()
            .subscribe(new Action1<List<Integer>>() {
                @Override
                public void call(List<Integer> integers) {
                    
                }
            });

toSortedList:

收集原始Observable發射的所有數據到一個有序列表,然后返回這個列表。

   Observable.just(6,2,3,4,5)
            .toSortedList(new Func2<Integer, Integer, Integer>() {//自定義排序
                @Override
                public Integer call(Integer integer, Integer integer2) {
                    return integer-integer2; //>0 升序 ,<0 降序
                }
            })
            .subscribe(new Action1<List<Integer>>() {
                @Override
                public void call(List<Integer> integers) {
                    Log.d("JG",integers.toString()); // [2, 3, 4, 5, 6]
                }
            });

toMap:

將序列數據轉換為一個Map。我們可以根據數據項生成key和生成value。

    Observable.just(6,2,3,4,5)
            .toMap(new Func1<Integer, String>() {
                @Override
                public String call(Integer integer) {
                    return "key:" + integer; //根據數據項生成map的key
                }
            }, new Func1<Integer, String>() {
                @Override
                public String call(Integer integer) {
                    return "value:"+integer; //根據數據項生成map的kvalue
                }
            }).subscribe(new Action1<Map<String, String>>() {
        @Override
        public void call(Map<String, String> stringStringMap) {
            Log.d("JG",stringStringMap.toString()); // {key:6=value:6, key:5=value:5, key:4=value:4, key:2=value:2, key:3=value:3}
        }
    });

toMultiMap

: 類似于toMap,不同的地方在于map的value是一個集合。

八:變換操作

map

: 對Observable發射的每一項數據都應用一個函數來變換。

 Observable.just(6,2,3,4,5)
            .map(integer -> "item:"+integer)
            .subscribe(s -> Log.d("JG",s));//item:6,item:2....

cast:

在發射之前強制將Observable發射的所有數據轉換為指定類型

flatMap:

將Observable發射的數據變換為Observables集合,然后將這些Observable發射的數據平坦化的放進一個單獨的Observable,內部采用merge合并。

       Observable.just(2,3,5)
            .flatMap(new Func1<Integer, Observable<String>>() {
                @Override
                public Observable<String> call(Integer integer) {
                    return Observable.create(subscriber -> {
                        subscriber.onNext(integer*10+"");
                        subscriber.onNext(integer*100+"");
                        subscriber.onCompleted();
                    });
                }
            })
    .subscribe(o -> Log.d("JG",o)) //20,200,30,300,50,500

flatMapIterable:

和flatMap的作用一樣,只不過生成的是Iterable而不是Observable。

        Observable.just(2,3,5)
            .flatMapIterable(new Func1<Integer, Iterable<String>>() {
                @Override
                public Iterable<String> call(Integer integer) {
                    return Arrays.asList(integer*10+"",integer*100+"");
                }
            }).subscribe(new Action1<String>() {
              @Override
              public void call(String s) {
            
              }
    });

concatMap:

類似于flatMap,由于內部使用concat合并,所以是按照順序連接發射。

switchMap:

和flatMap很像,將Observable發射的數據變換為Observables集合,當原始Observable發射一個新的數據(Observable)時,它將取消訂閱前一個Observable。

  Observable.create(new Observable.OnSubscribe<Integer>() {

        @Override
        public void call(Subscriber<? super Integer> subscriber) {
            for(int i=1;i<4;i++){
                subscriber.onNext(i);
                Utils.sleep(500,subscriber);//線程休眠500ms
            }

            subscriber.onCompleted();
        }
    }).subscribeOn(Schedulers.newThread())
      .switchMap(new Func1<Integer, Observable<Integer>>() {
             @Override
           public Observable<Integer> call(Integer integer) {
                   //每當接收到新的數據,之前的Observable將會被取消訂閱
                    return Observable.create(new Observable.OnSubscribe<Integer>() {
                        @Override
                        public void call(Subscriber<? super Integer> subscriber) {
                            subscriber.onNext(integer*10);
                            Utils.sleep(500,subscriber);
                            subscriber.onNext(integer*100);
                            subscriber.onCompleted();
                        }
                    }).subscribeOn(Schedulers.newThread());
                }
            })
            .subscribe(s -> Log.d("JG",s.toString()));//10,20,30,300

scan:

與reduce很像,對Observable發射的每一項數據應用一個函數,然后按順序依次發射每一個值。

  Observable.just(2,3,5)
            .scan(new Func2<Integer, Integer, Integer>() {
                @Override
                public Integer call(Integer sum, Integer item) {
                    return sum+item;
                }
            })
    .subscribe(integer -> Log.d("JG",integer.toString())) //2,5,10
Observable.just(1, 2, 3, 4, 5)
        .scan(-1,new Func2<Integer, Integer, Integer>() {
            @Override
            public Integer call(Integer sum, Integer item) {
                return sum + item;
            }
        })

groupBy:

將Observable分拆為Observable集合,將原始Observable發射的數據按Key分組,每一個Observable發射一組不同的數據。

   Observable.just(2,3,5,6)
            .groupBy(new Func1<Integer, String>() {
                @Override
                public String call(Integer integer) {//分組
                    return integer%2==0?"偶數":"奇數";
                }
            })
    .subscribe(new Action1<GroupedObservable<String, Integer>>() {
        @Override
        public void call(GroupedObservable<String, Integer> o) {

            o.subscribe(new Action1<Integer>() {
                @Override
                public void call(Integer integer) {
                    Log.d("JG",o.getKey()+":"+integer.toString()); //偶數:2,奇數:3,...
                }
            });
        }
    })
    

buffer:

它定期從Observable收集數據到一個集合,然后把這些數據集合打包發射,而不是一次發射一個

    Observable.just(2,3,5,6)
            .buffer(3)
            .subscribe(new Action1<List<Integer>>() {
                @Override
                public void call(List<Integer> integers) {
                    
                }
            })

window:

定期將來自Observable的數據分拆成一些Observable窗口,然后發射這些窗口,而不是每次發射一項。

   Observable.just(2,3,5,6)
            .window(3)
            .subscribe(new Action1<Observable<Integer>>() {
                @Override
                public void call(Observable<Integer> integerObservable) {
                    integerObservable.subscribe(new Action1<Integer>() {
                        @Override
                        public void call(Integer integer) {
                            
                        }
                    });
                }
            })

九:錯誤處理/重試機制

onErrorResumeNext:

當原始Observable在遇到錯誤時,使用備用Observable。。

  Observable.just(1,"2",3)
    .cast(Integer.class)
    .onErrorResumeNext(Observable.just(1,2,3))
    .subscribe(integer -> Log.d("JG",integer.toString())) //1,2,3
    ;

onExceptionResumeNext:

當原始Observable在遇到異常時,使用備用的Observable。與onErrorResumeNext類似,區別在于onErrorResumeNext可以處理所有的錯誤,onExceptionResumeNext只能處理異常。

onErrorReturn:

當原始Observable在遇到錯誤時發射一個特定的數據。

 Observable.just(1,"2",3)
            .cast(Integer.class)
            .onErrorReturn(new Func1<Throwable, Integer>() {
                @Override
                public Integer call(Throwable throwable) {
                    return 4;
                }
            }).subscribe(new Action1<Integer>() {
        @Override
        public void call(Integer integer) {
            Log.d("JG",integer.toString());1,4
        }
    });

retry:

當原始Observable在遇到錯誤時進行重試。

    Observable.just(1,"2",3)
    .cast(Integer.class)
    .retry(3)
    .subscribe(integer -> Log.d("JG",integer.toString()),throwable -> Log.d("JG","onError"))
    ;//1,1,1,1,onError

retryWhen

: 當原始Observable在遇到錯誤,將錯誤傳遞給另一個Observable來決定是否要重新訂閱這個Observable,內部調用的是retry。

  Observable.just(1,"2",3)
    .cast(Integer.class)
    .retryWhen(new Func1<Observable<? extends Throwable>, Observable<Long>>() {
        @Override
        public Observable<Long> call(Observable<? extends Throwable> observable) {
            return Observable.timer(1, TimeUnit.SECONDS);
        }
    })
    .subscribe(integer -> Log.d("JG",integer.toString()),throwable -> Log.d("JG","onError"));
    //1,1

十:連接操作

ConnectableObservable與普通的Observable差不多,但是可連接的Observable在被訂閱時并不開始發射數據,只有在它的connect()被調用時才開始。用這種方法,你可以等所有的潛在訂閱者都訂閱了這個Observable之后才開始發射數據。

ConnectableObservable.connect()

指示一個可連接的Observable開始發射數據.

Observable.publish()

將一個Observable轉換為一個可連接的Observable

Observable.replay()

確保所有的訂閱者看到相同的數據序列的ConnectableObservable,即使它們在Observable開始發射數據之后才訂閱。

ConnectableObservable.refCount()

讓一個可連接的Observable表現得像一個普通的Observable。

       ConnectableObservable<Integer> co= Observable.just(1,2,3)
                .publish();

        co .subscribe(integer -> Log.d("JG",integer.toString()) );
        co.connect();//此時開始發射數據

十一:阻塞操作

BlockingObservable是一個阻塞的Observable。普通的Observable 轉換為 BlockingObservable,可以使用 Observable.toBlocking(?)方法或者BlockingObservable.from(?)方法。內部通過CountDownLatch實現了阻塞操作。。

以下的操作符可以用于BlockingObservable,如果是普通的Observable,務必使用Observable.toBlocking()轉為阻塞Observable后使用,否則達不到預期的效果。

在Rxjava1中的BlockingObservable已經在Rxjava2中去掉了,在Rxjava2中已經集成到了Observable中。

名稱 解析
blockingForEach() 對Observable發射的每一項數據調用一個方法,會阻塞直到Observable完成
blockingFirst() 阻塞直到Observable發射了一個數據,然后返回第一項數據
blockingMostRecent() 返回一個總是返回Observable最近發射的數據的iterable
blockingLatest() 返回一個iterable,會阻塞直到或者除非Observable發射了一個iterable沒有返回的值,然后返回這個值
blockingNext() 返回一個iterable,阻塞直到返回另外一個值
blockingLast() 阻塞直到Observable終止,然后返回最后一項數據
blockingIterable() 將Observable轉換返回一個iterable.
blockingSingle() 如果Observable終止時只發射了一個值,返回那個值,否則拋出異常
blockingSubscribe() 在當前線程訂閱,和forEach類似

十二:工具集

materialize:

將Observable轉換成一個通知列表。

 Observable.just(1,2,3)
           .materialize()
           .subscribe(new Action1<Notification<Integer>>() {
               @Override
               public void call(Notification<Integer> notification) {
                   Log.d("JG",notification.getKind()+" "+notification.getValue());
                   //OnNext 1
                   //OnNext 2
                   //OnNext 3
                   //OnCompleted null
               }
           });

dematerialize:

與上面的作用相反,將通知逆轉回一個Observable。

timestamp:

給Observable發射的每個數據項添加一個時間戳。

  Observable.just(1,2,3)
           .timestamp()
           .subscribe(new Action1<Timestamped<Integer>>() {
               @Override
               public void call(Timestamped<Integer> timestamped) {
                   Log.d("JG",timestamped.getTimestampMillis()+" "+timestamped.getValue());
                   //1472627510548 1
                   //1472627510549 2
                   //1472627510549 3
               }
           });

timeInterval:

給Observable發射的兩個數據項間添加一個時間差,實現在OperatorTimeInterval中
timeInterval

serialize:

強制Observable按次序發射數據并且要求功能是完好的

cache:

緩存Observable發射的數據序列并發射相同的數據序列給后續的訂閱者

observeOn:

指定觀察者觀察Observable的調度器

subscribeOn:

指定Observable執行任務的調度器

doOnEach:

注冊一個動作,對Observable發射的每個數據項使用

   Observable.just(2,3)
             .doOnEach(new Action1<Notification<? super Integer>>() {
                 @Override
                 public void call(Notification<? super Integer> notification) {
                     Log.d("JG","--doOnEach--"+notification.toString());
                 }
             })
             .subscribe(integer -> Log.d("JG",integer.toString()));
 //結果為:            
  // --doOnEach--[rx.Notification@133c40b0 OnNext 2]
 // 2
  // --doOnEach--[rx.Notification@133c40b0 OnNext 3]
 // 3
// --doOnEach--[rx.Notification@df4db0e OnCompleted]

doOnCompleted':

注冊一個動作,對正常完成的Observable使用

doOnError:

注冊一個動作,對發生錯誤的Observable使用

doOnTerminate

:注冊一個動作,對完成的Observable使用,無論是否發生錯誤

  Observable.just(2,3)
            .doOnTerminate(new Action0() {
                @Override
                public void call() {
                    Log.d("JG","--doOnTerminate--");
                }
            })
            .subscribe(integer -> Log.d("JG",integer.toString()));
// 2 , 3 , --doOnTerminate--

doOnSubscribe:

注冊一個動作,在觀察者訂閱時使用。內部由OperatorDoOnSubscribe實現doOnSubscribe

doOnUnsubscribe

: 注冊一個動作,在觀察者取消訂閱時使用。內部由OperatorDoOnUnsubscribe實現,在call中加入一個解綁動作。
doOnUnsubscribe

finallyDo/doAfterTerminate:

注冊一個動作,在Observable完成時使用

Observable.just(2,3)
            .doAfterTerminate(new Action0() {
                @Override
                public void call() {
                    Log.d("JG","--doAfterTerminate--");
                }
            })
            .subscribe(integer -> Log.d("JG",integer.toString()));
//2,3,  --doAfterTerminate-- 

delay:

延時發射Observable的結果。即讓原始Observable在發射每項數據之前都暫停一段指定的時間段。效果是Observable發射的數據項在時間上向前整體平移了一個增量(除了onError,它會即時通知)。

delaySubscription:

延時處理訂閱請求。實現在OnSubscribeDelaySubscription中
delaySubscription

using

: 創建一個只在Observable生命周期存在的資源,當Observable終止時這個資源會被自動釋放。

  Observable.using(new Func0<File>() {//資源工廠
        @Override
        public File call() {

            File file = new File(getCacheDir(), "a.txt");
            if(!file.exists()){
                try {
                    Log.d("JG","--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>() {//釋放資源動作
        @Override
        public void call(File file) {
            if(file!=null&&file.exists()){
                Log.d("JG","--delete--");
                file.delete();
            }
        }
    })
    .subscribe(s -> Log.d("JG",s))
    ;
 //--create--
 //exist
 //--delete--

single/singleOrDefault:

強制返回單個數據,否則拋出異常或默認數據。

十三:Flowable (2.0出來的) 非操作符

Flowable<Integer> upstream = Flowable.create(new FlowableOnSubscribe<Integer>() {
            @Override
            public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
                Log.d(TAG, "emit 1");
                emitter.onNext(1);
                Log.d(TAG, "emit 2");
                emitter.onNext(2);
                Log.d(TAG, "emit 3");
                emitter.onNext(3);
                Log.d(TAG, "emit complete");
                emitter.onComplete();
            }
        }, BackpressureStrategy.ERROR); //增加了一個參數

        Subscriber<Integer> downstream = new Subscriber<Integer>() {

            @Override
            public void onSubscribe(Subscription s) {
                Log.d(TAG, "onSubscribe");
                s.request(Long.MAX_VALUE);  //注意這句代碼
            }

            @Override
            public void onNext(Integer integer) {
                Log.d(TAG, "onNext: " + integer);

            }

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

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

s.request(Long.MAX_VALUE); //注意這句代碼

處理事件 默認處理 128 ,當發送的事件 > 處理的事件 MissingBackpressureException異常

BackpressureStrategy

  • BackpressureStrategy.BUFFER
    • 沒有128 的限制
  • BackpressureStrategy.ERROR
    • 默認128
  • BackpressureStrategy.DROP
    • 直接把存不下的事件丟棄
  • BackpressureStrategy.LATEST
    • 只保留最新的事件

寫在最后

感謝作者maplejaw

RxJava操作符大全

推薦Rxjava系列

給初學者的RxJava2.0教程

官網學習筆記

ReactiveX/RxJava文檔中文版

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