RxJava2 學習(二)

jayqiu發表於2018-08-30

RxAndroid 學習和操作符的理解

RxJava 的觀察者模式

1)RxJava 有四個基本概念:Observable (可觀察者,即被觀察者)、 Observer (觀察者)、 subscribe (訂閱)、事件。Observable 和 Observer 通過 subscribe() 方法實現訂閱關係,從而 Observable 可以在需要的時候發出事件來通知 Observer。
2)與傳統觀察者模式不同, RxJava 的事件回撥方法除了普通事件 onNext() (相當於 onClick() / onEvent())之外,還定義了兩個特殊的事件:onCompleted() 和 onError()。
3)onCompleted(): 事件佇列完結。RxJava 不僅把每個事件單獨處理,還會把它們看做一個佇列。RxJava 規定,當不會再有新的 onNext() 發出時,需要觸發 onCompleted() 方法作為標誌。
4)onError(): 事件佇列異常。在事件處理過程中出異常時,onError() 會被觸發,同時佇列自動終止,不允許再有事件發出。
5)在一個正確執行的事件序列中, onCompleted() 和 onError() 有且只有一個,並且是事件序列中的最後一個。需要注意的是,onCompleted() 和 onError() 二者也是互斥的,即在佇列中呼叫了其中一個,就不應該再呼叫另一個。

上游可以傳送無限個onNext, 下游也可以接收無限個onNext. 當上遊傳送了一個onComplete後, 上游onComplete之後的事件將會繼續傳送, 而下游收到onComplete事件之後將不再繼續接收事件. 當上遊傳送了一個onError後, 上游onError之後的事件將繼續傳送, 而下游收到onError事件之後將不再繼續接收事件. 上游可以不傳送onComplete或onError. 最為關鍵的是onComplete和onError必須唯一併且互斥, 即不能發多個onComplete, 也不能發多個onError, 也不能先發一個onComplete, 然後再發一個onError

RxJava多執行緒選項

name 說明
Schedulers.io() 代表io操作的執行緒, 通常用於網路,讀寫檔案等io密集型的操作
Schedulers.computation() 代表CPU計算密集型的操作, 即不會被 I/O 等操作限制效能的操作,例如圖形的計算。這個 Scheduler 使用的固定的執行緒池,大小為 CPU 核數。不要把 I/O 操作放在 computation() 中,否則 I/O 操作的等待時間會浪費 CPU。
Schedulers.newThread() 代表一個常規的新執行緒
AndroidSchedulers.mainThread() 代表Android的主執行緒

newThread() 差不多,區別在於 io() 的內部實現是是用一個無數量上限的執行緒池,可以重用空閒的執行緒,因此多數情況下 io() 比 newThread() 更有效率。不要把計算工作放在 io() 中,可以避免建立不必要的執行緒。

建立一個普通的

private void create() {
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                Log.e(TAG, "emit 1");
                emitter.onNext(1);
                Log.e(TAG, "emit 2");
                emitter.onNext(2);
                Log.e(TAG, "emit 3");
                emitter.onNext(3);
                Log.e(TAG, "emit complete");
                emitter.onComplete();
                Log.e(TAG, "emit 4");
                emitter.onNext(4);
            }
        }).subscribe(new Observer<Integer>() {
            private Disposable mDisposable;
            private int i;

            @Override
            public void onSubscribe(Disposable d) {
                Log.e(TAG, "subscribe");
                mDisposable = d;
            }

            @Override
            public void onNext(Integer value) {
                Log.e(TAG, "onNext: " + value);
                i++;
                if (i == 2) {
                    Log.e(TAG, "dispose");
                    mDisposable.dispose();
                    Log.e(TAG, "isDisposed : " + mDisposable.isDisposed());
                }
            }

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

            @Override
            public void onComplete() {
                Log.e(TAG, "complete");
            }
        });
    }
複製程式碼

使用just時,just是將資料作為一個完整的物件一次性發射的,最後呼叫的fromArray map 是一個變形的過程eg 由△--->口

  private void just() {
          String[] students = {"jay", "tom"};
          String[] students22 = {"jay22", "tom22"};
          //------------------對兩個陣列進行合併後一次性發出------------------------
          Observable.just(students, students22).subscribe(new Consumer<String[]>() {
              @Override
              public void accept(String[] strings) throws Exception {
                  for (String s : strings) {
                      Log.e(TAG, "1=just===" + s);
                  }
              }
          });
          Observable observable1 = Observable.just("100", "2000").map(new Function<String, Object>() {
              @Override
              public Integer apply(String s) throws Exception {

                  return Integer.parseInt(s);
              }
          });
          observable1.subscribe(new Consumer<Integer>() {
              @Override
              public void accept(Integer integer) throws Exception {
                  Log.e(TAG, "1====" + integer);
              }
          });
          //---------------------------------------------------
          Observable<String> observable2 = Observable.just(students).map(new Function<String[], String>() {
              @Override
              public String apply(String[] strings) throws Exception {
                  String str = "";
                  for (String s : strings) {
                      str = str + s;
                  }
                  return str;
              }
          });
          observable2.subscribe(new Consumer<String>() {
              @Override
              public void accept(String s) throws Exception {
                  Log.e(TAG, "observable2==" + s);
              }
          });


          //==============================================
          Observable observable = Observable.just(students, students22).map(new Function<String[], String>() {
              @Override
              public String apply(String[] strings) throws Exception {
                  String str = "";
                  for (String s : strings) {
                      str = str + s;
                  }
                  return str;
              }
          });

          observable.subscribe(new Consumer<String>() {
              @Override
              public void accept(String strings) throws Exception {
                  Log.e(TAG, "222===" + strings);

              }
          });


      }
複製程式碼

使用fromArray接收的資料來源是逐個發射的

private void fromArray() {
        String[] students = {"jay", "tom"};
        Observable.fromArray(students).subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(String s) {
                Log.e(TAG, s);
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });
    }
複製程式碼

map 是一個變形的過程eg 由△--->口 由String --->Integer

    private void map() {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                e.onNext("111111");
            }
        }).map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) throws Exception {
                return Integer.parseInt(s);
            }
        })
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer s) throws Exception {
                        Log.e(TAG, "map===" + s);
                    }
                });
    }
複製程式碼

concatMap它和flatMap的作用幾乎一模一樣, 只是它的結果是嚴格按照上游傳送的順序來傳送的, flatMap並不保證事件的順序

private void flatMap() {
        // concatMap它和flatMap的作用幾乎一模一樣, 只是它的結果是嚴格按照上游傳送的順序來傳送的, flatMap並不保證事件的順序
        Disposable subscribe = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(7);
                emitter.onNext(8);
                emitter.onNext(9);
            }
        }).flatMap(new Function<Integer, ObservableSource<List<String>>>() {
            @Override
            public ObservableSource<List<String>> apply(Integer integer) throws Exception {
                final List<String> list = new ArrayList<>();
                for (int i = 0; i < 3; i++) {
                    list.add("I am value " + integer);
                }
                return Observable.just(list);


            }
        }).flatMap(new Function<List<String>, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(List<String> strings) throws Exception {
                String str = strings.toString();
                return Observable.just(str);
            }
        })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String s) throws Exception {
                        mBtnStart.setText(s.toString());
                    }
                });
    }
複製程式碼

Zip通過一個函式將多個Observable傳送的事件結合到一起,然後傳送這些組合到一起的事件. 它按照嚴格的順序應用這個函式。它只發射與發射資料項最少的那個Observable一樣多的資料。

   private void zip() {
        Observable observable = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                for (int i = 0; ; i++) {
                    e.onNext(i);
//                    Thread.sleep(1000);
                }

            }
        }).subscribeOn(Schedulers.io());
        Observable observable2 = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                e.onNext("A");
                Thread.sleep(2000);
                e.onNext("B");
                Thread.sleep(2000);
                e.onNext("C");
                Thread.sleep(2000);
            }
        }).subscribeOn(Schedulers.io());
        Observable.zip(observable, observable2, new BiFunction<Integer, String, String>() {
            @Override
            public String apply(Integer o, String o2) throws Exception {
                return o + o2;
            }
        }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                mBtnStart.setText(s);
            }
        });


    }
複製程式碼

上下流分配(借鑑Season_zlc

    我們把上游看成小日本, 把下游當作葉問, 當呼叫Subscription.request(1)時, 葉問就說我要打一個!
    然後小日本就拿出一個鬼子給葉問, 讓他打, 等葉問打死這個鬼子之後, 再次呼叫request(10),
    葉問就又說我要打十個! 然後小日本又派出十個鬼子給葉問, 然後就在邊上看熱鬧, 看葉問能不能打死十個鬼子,
    等葉問打死十個鬼子後再繼續要鬼子接著打...
複製程式碼

    private void fLowable() {
        Flowable.create(new FlowableOnSubscribe<Integer>() {
            @Override
            public void subscribe(FlowableEmitter<Integer> emitter) throws Exception {
                for (int i = 0; i < 128; i++) {
                    Log.d(TAG, "emit " + i);
                    emitter.onNext(i);
                }
            }
        }, BackpressureStrategy.ERROR)
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<Integer>() {
            @Override
            public void onSubscribe(Subscription s) {
                subscription = s;
                s.request(1);// 每次從水缸裡去取一個
            }

            @Override
            public void onNext(Integer integer) {
                mBtnStart.setText("第" + integer + "個");
            }

            @Override
            public void onError(Throwable t) {

            }

            @Override
            public void onComplete() {

            }
        });
    }

複製程式碼

DOME下載 歡迎Start Star 我的GitHub

# Back

相關文章