RxJava2.0初學總結筆記

(個人知識總結,學習RxJava的時候主要是參照作者Carson_Ho的簡書)

一.RxJava的作用

RxJava主要是基於事件流,實現異步操作的一個庫,鏈式調用。且RxJava採用的是Java中很出名的“觀察者模式”。(在學習了RxJava之後,大家除了什麼“單例模式”之外,又懂一種新的模式了---觀察者模式。)

類似於Handler,AsyncTask。

二.使用RxJava的優點

個人體會還是主要是使用RxJava會使邏輯清晰。

三.RxJava主要的幾個類

1.Observable(被觀察者)

2.Observe(觀察者)

3.Suscribe(訂閱)

三個類的事件傳遞方向爲:Observable(產生事件)---subscribe(將被觀察者和觀察者進行綁定)--->Observe(接收處理事件

通俗可以理解爲:(大哥)Observe,(小弟)Observable(),被觀察者(小弟Observable)一有事,就要用電話(subscribe)給大哥Observe說。大哥接收到小弟(Observable)發出來的訊息,然後開始處理小弟(Observable所發的信息。(個人理解,若比喻有錯誤,請指正)

既然通俗的理解了,在項目中大概哪些地方纔能用到它呢?

1.很多使用是用RxJava配合Retrofit來搭建網絡框架。(也是很多開發者最主要使用的方式)

2.代替Handler,AsyncTask。(對於技術不上不下的人來說,用原生AsyncTask來處理異步操作真的要命)。

其他我還沒發現到。

四.如何初步的使用RxJava

想要使用首先肯定是要創建好我們的---小弟(Observable),大哥(Observe),還有我們的電話(Suscribe),然後再把大哥的心,小弟的心,手機的心串一串~串一個鏈式調用~(玩笑一下)

1.創建小弟-->Observable

create方法創建是一種很基礎簡單的方式

Observable<String> observableDemo=Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(@NonNull ObservableEmitter<String> observableEmitter) throws Exception {
        observableEmitter.onNext("1");
        observableEmitter.onNext("2");
        observableEmitter.onError(new Exception("發生錯誤了"));
        observableEmitter.onComplete();
    }
});

除此之外,還有一種用just()快速創建被觀察者,由代碼可以看出這種方式很明瞭簡潔。

Observable observable2 = Observable.just("A", "B", "C");

fromXXX();//在2.0以前可以直接用from來調用,但是在2.0之後,我們需要確定你的數據類型,指明你的數據類型是fromArray還是fromIterator...

String[] testFrom = {"1", "2"};
//被觀察者
Observable observable = Observable.fromArray(testFrom);

from的類型一般如下所示


2.創建大哥-->Observer

這種是最基本的創建方式

//觀察者
Observer<String> observer = new Observer<String>() {
    @Override
    public void onSubscribe(Disposable disposable) {
    }

    @Override
    public void onNext(String s) {
    }

    @Override
    public void onError(Throwable throwable) {
    }

    @Override
    public void onComplete() {
    }
};
還有一種是由Subscriber來創建
Subscriber subscriber=new Subscriber() {
    @Override
    public void onSubscribe(Subscription s) {
    }

    @Override
    public void onNext(Object o) {
    }

    @Override
    public void onError(Throwable t) {
    }

    @Override
    public void onComplete() {
    }
};

相對於最基本的創建方式來說。subscriber新增了onStart(),unsubscribe()方法。

onStart():未響應事件前調用,可以用來做一些準備工作

unsubscribe();取消訂閱,當調用這個方法之後,觀察者將不再接收和響應事件

*在調用unsubscribe()方法之前,需要用isunsubscribe()判斷狀態,判斷被觀察者(Observable)是否還持有觀察者(Observer)Subscriber的引用,如果引用不能及時釋放,就會出現內存泄漏。

3.訂閱(subscribe)---->電話

observable.subscribe(observer);//被觀察者,訂閱,觀察者

4.鏈式創建

一開始就說RxJava是基於事件流的鏈式調用,現在把它們鏈接起來看一下。

Observable.create(new ObservableOnSubscribe<Integer>() {//創建被觀察者
    @Override
    public void subscribe(@NonNull ObservableEmitter<Integer> observableEmitter) throws Exception {
        observableEmitter.onNext(1);
        observableEmitter.onNext(2);
        observableEmitter.onComplete();
    }
}).subscribe(//綁定
   new Observer<Integer>() {//創建觀察者
    @Override
    public void onSubscribe(@NonNull Disposable disposable) {
    }

    @Override
    public void onNext(@NonNull Integer integer) {
        Log.i("t","被觀察者所發出的值="+integer);
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
    }

    @Override
    public void onComplete() {
    }
});

這種鏈式的好處就是使邏輯上變得簡單清晰。這也是RxJava的一個優點。

5.切斷小弟(Observable)和大哥(Observer)的鏈接---->Disposable.dispose();

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

    @Override
    public void onSubscribe(Disposable d) {
        mDisposable = d;
    }

    @Override
    public void onNext(Integer value) {
        Log.i("t", "onNext: " + value);
        i++;
        if (i == 2) {
            Log.i("t", "dispose");
            mDisposable.dispose();
            Log.i("t", "isDisposed : " + mDisposable.isDisposed());//若已切斷,isDisposed=true;
        }
    }

    @Override
    public void onError(Throwable e) {
    }

    @Override
    public void onComplete() {
    }
});

五.一些常見常用操作符介紹

just();//快速創建被觀察者對象。最多隻能發送10個事件。

Observable observable2 = Observable.just("A", "B", "C");

類似於:onNext("A");onNext("B");onNext("C");

fromArray();//快速創建被觀察者對象。發送10個以上的事件。數組形式

fromIterable();//快速創建被觀察者對象。發送10個以上的事件。集合形式

觀察者接收到的數據爲遍歷數據。

empty();//僅發送complete事件,直接通知完成

error();//僅發送error事件,直接通知異常

never();//不發送任何事件

-----------------------------------延遲操作符---------------------------------------

defer();//快速創建被觀察者對象。此方法作用:直到有觀察者訂閱才動態創建被觀察者對象,併發送事件。每次訂閱後都會得到一個新的被觀察者(Observable),可以確保Observable的數據是最新的。

//延時操作.有觀察者訂閱才能動態創建被觀察者
Observable<Integer> mobservable=Observable.defer(new Callable<ObservableSource<? extends Integer>>() {
    @Override
    public ObservableSource call() throws Exception {
        return Observable.just(i);
    }
});

i=15;
//觀察者被訂閱,開始動態創建被觀察者
mobservable.subscribe(new Observer<Integer>() {
    @Override
    public void onSubscribe(@NonNull Disposable disposable) {
    }

    @Override
    public void onNext(@NonNull Integer integer) {
         //i=15
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
    }

    @Override
    public void onComplete() {
    }
});

timer();//快速創建被觀察者對象。方法作用:延遲指定時間後,發送一個onNext(0);的事件。(Long類型)

*timer默認運行在新線程,可用scheduler來指定線程。

//timer(延遲時間,時間單位)
Observable.timer(5, TimeUnit.SECONDS).subscribe(new Observer<Long>() {
    @Override
    public void onSubscribe(@NonNull Disposable disposable) {
    }

    @Override
    public void onNext(@NonNull Long aLong) {
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
    }

    @Override
    public void onComplete() {
    }
});

interval();//快速創建被觀察者對象。每隔指定時間就發送事件。  

//1第一次延遲的時間5s  2執行事件,每隔1s發送一次。  3計數單位爲秒
Observable.interval(5,1,TimeUnit.SECONDS).subscribe(new Observer<Long>() {
    @Override
    public void onSubscribe(@NonNull Disposable disposable) {
    }

    @Override
    public void onNext(@NonNull Long aLong) {
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
    }

    @Override
    public void onComplete() {
    }
});

發送事件序列:從0開始,五險遞增1的整數序列。

intervalRange();//快速創建被觀察者對象。每隔一段時間就發送事件,可指定事件數量

//1.起始數據 2.事件數量 3.第一次延遲時間 4.執行的間隔秒數 5.計數單位
Observable.intervalRange(2,5,3,1,TimeUnit.SECONDS).subscribe(new Observer<Long>() {
    @Override
    public void onSubscribe(@NonNull Disposable disposable) {

    }

    @Override
    public void onNext(@NonNull Long aLong) {
         //事件數據=2,3,4,5,6
    }

    @Override
    public void onError(@NonNull Throwable throwable) {

    }

    @Override
    public void onComplete() {

    }
});

range();//快速創建被觀察者對象。類似於intervalRange(),但是range()無延遲發送事件。

//1.事件序列起點=0  2.指定事件數量=3
Observable.range(0,3).subscribe(new Observer<Integer>() {
    @Override
    public void onSubscribe(@NonNull Disposable disposable) {
    }

    @Override
    public void onNext(@NonNull Integer integer) {
        //收到的事件=0,1,2
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
    }

    @Override
    public void onComplete() {
    }
});

rangeLong();//快速創建被觀察者對象。類似於range(),區別是,rangeLong()支持Long類數據。

------------------------------------變換操作符--------------------------------------

map();//將被觀察者發送的事件轉換爲任意的類型的事件

Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(@NonNull ObservableEmitter<String> observableEmitter) throws Exception {
        //事件傳遞爲string="1"
        observableEmitter.onNext("1");
    }
    //map操作Function來對被觀察者所發出的事件類型進行變換。string->integer
}).map(new Function<String, Integer>() {
    @Override
    public Integer apply(@NonNull String s) throws Exception {
        return null;
    }
}).subscribe(new Consumer<Integer>() {
    @Override
    public void accept(Integer integer) throws Exception {
        //接收到的integer=1
    }
});

FlatMap();//將被觀察者發送的事件序列進行拆分轉換,再合併爲一個新的事件序列,最後再發送。(類似於打亂事件順序)

Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(@NonNull ObservableEmitter<Integer> observableEmitter) throws Exception {
        observableEmitter.onNext(100);
        observableEmitter.onNext(101);
        observableEmitter.onNext(102);
    }
    //floatMap把原來的事件生產序列進行拆分,再將每個事件拆分轉換成新的,發送三個string最後合併,再發送給被觀察者
}).flatMap(new Function<Integer, ObservableSource<String>>() {
    @Override
    public ObservableSource<String> apply(@NonNull Integer integer) throws Exception {
        List<String> list=new ArrayList<String>();
        for(int i=0;i<3;i++){
            list.add("原事件="+integer+"拆分的新事件="+i);
        }
        return Observable.fromIterable(list);
    }
}).subscribe(new Consumer<String>() {
    @Override
    public void accept(String s) throws Exception {

    }
});

*新事件的合成順序與舊事件的順序無關。

concatMap();//類似於flatmap(),用法和flatmap差不多.區別是新事件的順序=被觀察者舊序列生產的順序。有序的變換事件序列。

Buffer();//定期從被觀察者中獲取一定數量的事件,並放到緩存區中。然後發送。用於緩存被觀察者中的事件。

//buffer->1.設置緩存區的大小 2.設置每次獲取新事件的數量
//例如第一次是3,4,5被存入,第二次是2,3,4(新事物增加爲1,向指針移動一位),一直到nullnull1終止存儲
Observable.just(1,2,3,4,5).buffer(3,1).subscribe(new Observer<List<Integer>>() {
    @Override
    public void onSubscribe(@NonNull Disposable disposable) {

    }

    @Override
    public void onNext(@NonNull List<Integer> integers) {

    }

    @Override
    public void onError(@NonNull Throwable throwable) {

    }

    @Override
    public void onComplete() {

    }
});
----------------------------------組合/合併操作符-----------------------------------

concat:組合多個被觀察者一起發送數據,合併後按發送順序串執行。組合被觀察者數量<=4

concatArray:組合多個被觀察者一起發送數據,合併後按發送順序串執行組合被觀察者數量>4

concat和concatArray的用法類似,只是數量不一樣而已。

Observable.concat(Observable.just(1,2,3),
        Observable.just(10,11,12)).subscribe(new Observer<Integer>() {
    @Override
    public void onSubscribe(@NonNull Disposable disposable) {
    }

    @Override
    public void onNext(@NonNull Integer integer) {
        //接收到的事件=1,2,3,10,11,12
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
    }

    @Override
    public void onComplete() {
    }
});

merge()/mergeArray():組合多個被觀察者一起發送數據,合併後按時間線並行執行

兩者的區別:merge組合被觀察者數量<=4      mergeArray>4(兩者用法相似,只是數量不同)

//1.0開始發送,共發2個數據,第一次事件延遲2s,間隔3s
//2.1開始發送,共發送3個數據,第一次事件延遲2s,間隔3s
Observable.merge(Observable.intervalRange(0,2,2,3,TimeUnit.SECONDS),
        Observable.intervalRange(1,3,2,3,TimeUnit.SECONDS)).subscribe(new Observer<Long>() {
            @Override
            public void onSubscribe(@NonNull Disposable disposable) {

            }

            @Override
            public void onNext(@NonNull Long aLong) {
                //接收到的數據0,1--->1,2--->3
            }

            @Override
            public void onError(@NonNull Throwable throwable) {

            }

            @Override
            public void onComplete() {

            }
        });

concatDelayError()/mergeDelayError();//多個被觀察者中的某一個拋出onError,正常執行是其他的被觀察者就不會執行了。但是concatDelay和mergeDelayError則可以讓所有的被觀察者都發送事件結束之後再觸發onError。(兩者使用相似,用相應的方式即可)

Observable.concatArrayDelayError(
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                // 發送Error事件,因爲使用了concatDelayError,所以第2Observable將會發送事件,等發送完畢後,再發送錯誤事件
                emitter.onError(new NullPointerException());
                emitter.onComplete();
            }
        }),
        Observable.just(4, 5, 6))
        .subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
            }
            @Override
            public void onNext(Integer value) {
            }

            @Override
            public void onError(Throwable e) {
            }

            @Override
            public void onComplete() {
            }
        });

Zip();//合併多個被觀察者發送的事件,生成一個新的事件序列,然後發送。

*最終合併事件數量=多個被觀察者中數量最少的數、

Observable.zip(Observable.just(1, 2, 3,9), Observable.just(10, 11, 12),
        //1.被觀察者對象1的類型  2.被觀察者2的類型  3合併的類型
        //Observable9最終也會被髮送出來,但是如果在1,2被觀察者事件序列之後complete,則不會發送9
        new BiFunction<Integer, Integer, String>() {
            @Override
            public String apply(@NonNull Integer integer, @NonNull Integer integer2) throws Exception {
                return integer+integer2+"";
            }
        }).subscribe(new Observer<String>() {
    @Override
    public void onSubscribe(@NonNull Disposable disposable) {
    }

    @Override
    public void onNext(@NonNull String s) {
        //最終接收到的=110,211,312
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
    }

    @Override
    public void onComplete() {
    }
});

一般應用於,展示的信息從多個地方獲取並且統一結合後展示。

網絡請求發送和結果的統一顯示。(Retrofit+RxJava)

combineLatest();//按事件合併,在同一個事件點上合併  兩個被觀察者對象中,任何一個先發送事件的最後一個數據和另外一個被觀察者對象的每一個數據結合。然後發送。

Observable.combineLatest(Observable.just(1L, 2L, 3L),
        //0開始,3個數,第一次延遲1s,間隔1s
        Observable.intervalRange(5,3,1,1,TimeUnit.SECONDS),
        new BiFunction<Long, Long, Long>() {
    @Override
    public Long apply(@NonNull Long integer, @NonNull Long integer2) throws Exception {
       // integer3 integer2=5;  integer=3 integer2=6;  integer=3 integer2=7;
        return integer+integer2;
    }
}).subscribe(new Observer<Long>() {
    @Override
    public void onSubscribe(@NonNull Disposable disposable) {
    }

    @Override
    public void onNext(@NonNull Long integer) {
        //結果=8,9,10
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
    }

    @Override
    public void onComplete() {
    }
});

combineLatestDelaError();//和concatDelay(),mergeDelay();用法意義都是一樣的。

reduce();//把被觀察者中的事件聚合成一個事件,併發送。

Observable.just(1,2,3,4).reduce(new BiFunction<Integer, Integer, Integer>() {
    @Override
    public Integer apply(@NonNull Integer integer, @NonNull Integer integer2) throws Exception {
        //第一次是1+2=3,返回數字3,第二次,3+3=6,用返回數加下一個數,第三次6+4=10用返回數加下一個數4.
        return integer+integer2;
    }
}).subscribe(new Consumer<Integer>() {
    @Override
    public void accept(Integer integer) throws Exception {
        //integer=3,6,10
    }
});

collect();//把被觀察者的事件數據收集到一個數據結構裏。

Observable.just(1,2,3,4).collect(
        //創建數據結構(容器),用於收集被觀察者發送的數據
        new Callable<ArrayList<Integer>>() {
    @Override
    public ArrayList<Integer> call() throws Exception {
        return new ArrayList<>();
    }
    //對發送的數據進行收集
}, new BiConsumer<ArrayList<Integer>, Integer>() {
    @Override
    public void accept(ArrayList<Integer> integers, Integer integer) throws Exception {
        integers.add(integer);//數據收集
    }
}).subscribe(new Consumer<ArrayList<Integer>>() {
    @Override
    public void accept(ArrayList<Integer> integers) throws Exception {
        //接收到的數組integers[1,2,3,4]
    }
});

startWith()/startWithArray();//發送事件前,追加發生事件。

在被觀察者在發送事件前,追加發送一個(多個)數據/一個新的Observable(被觀察者)

Observable.just(1,2,3)
        .startWith(7)//追加一個數據
        .startWithArray(8,9,10)//追加多個數據
        .startWith(Observable.just(11,12))//追加被觀察者
        .subscribe(new Observer<Integer>() {
    @Override
    public void onSubscribe(@NonNull Disposable disposable) {
    }

    @Override
    public void onNext(@NonNull Integer integer) {
    }

    @Override
    public void onError(@NonNull Throwable throwable) {
    }

    @Override
    public void onComplete() {

    }
});

count();//統計被觀察者發送事件的數量

Observable.just(1,2,3,4,5,6).count().subscribe(new Consumer<Long>() {
    @Override
    public void accept(Long aLong) throws Exception {
        //發送事件數量along=6
    }
});
爲了清晰自己的認知,盜用一張Carson_Ho大神的講解圖,超級全面!強推他的RxJava講解,https://www.jianshu.com/p/cd984dd5aae8


此爲個人學習筆記,主要參照Carson_Ho大神的簡書文章來總結出來自己習慣看的模式的樣子。要是我理解有誤的地方,麻煩各位多多指點糾正!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章