RxJava

RxJava是什麼

RxJava是一種異步方式:類似於android中的AsyncTask 和Handler ,RxJava並不是一個”拿來就能用”的項目,他需要我們像學習門新語言一樣從語法–>詞彙–>用法的學習過程

作用是什麼

用於:邏輯的簡潔,並不是單純的代碼量少

RxJava 的使用

  1. 創建一個被觀察者
Observable<String> myObservable = Observable.create(  
    new Observable.OnSubscribe<String>() {  
        @Override  
        public void call(Subscriber<? super String> sub) {  
            sub.onNext("Hello, world!");  
            sub.onCompleted();  //標記完成
        }  
    }  
);

2.創建一個Subscriber來處理Observable對象發出的字符串

Subscriber<String> mySubscriber = new Subscriber<String>() {  
    @Override  
    public void onNext(String s) { System.out.println(s); }  

    @Override  
    public void onCompleted() { }  

    @Override  
    public void onError(Throwable e) { }  
};

3.通過subscribe函數就可以將我們定義的myObservable對象和mySubscriber對象關聯起來,這樣就完成了subscriber對observable的訂閱。

myObservable.subscribe(mySubscriber);//訂閱

以上代碼簡化
RxJava 提供了很多簡化創建Observable對象的方法
如:Observable.just(),用來創建只發出一個事件就結束的Observable對象

//創建Observable 簡化代碼
Observable<String> myObservable = Observable.just("Hello, world!");
//簡化Subscriber,在Subscriber中我們關注的只有onNext 一個方法,這時候就可以使用Action1 類
    Action1<String> onNextAction = new Action1<String>(){
        @Override
        public void call(String s) {
            Log.e("onCompleted", s);
        }
    };
//訂閱 subscribe方法有一個重載版本,接受三個Action1類型的參數,分別對應OnNext,OnComplete, OnError函數。
        //這裏我們並不關心onError和onComplete,所以只需要第一個參數就可以
        myObservable.subscribe(onNextAction);

再簡化

 Observable.just("Hello, world!")
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.e("call", s);
                    }
                });

錯誤處理

onComplete()和onError()函數。這兩個函數用來通知訂閱者,被觀察的對象將停止發送數據以及爲什麼停止(成功的完成或者出錯了)

RxJava 中的操作符

1. 操作符(map)

作用:操作符用於在Observable和最終的Subscriber之間修改Observable發出的事件,就是用來把把一個事件轉換爲另一個事件的

案例:在hello world中加上我的簽名,會想到要去修改被觀察者,如果加上簽名這個需求只針對於某個訂閱者,那麼去修改被觀察者顯然不行,這個時候就用到了map操作符,變換Observable對象

 Observable.just("Hello, world!")
                .map(new Func1<String, String>() {
                    @Override
                    public String call(String s) {
                        return s + " RxJava";
                    }
                })
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.e("call", s);
                    }
                });

改變數據類型的observable對象

Observable.just("Hello, world!")
                .map(new Func1<String, Integer>() {
                    @Override
                    public Integer call(String s) {
                        return s.hashCode();
                    }
                })
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {
                        Log.e("call", integer.toString());
                    }
                });

這裏出現了一個叫做 Func1 的類。它和 Action1 非常相似,也是 RxJava 的一個接口,用於包裝含有一個參數的方法。 另外,和 ActionX 一樣, FuncX 也有多個,用於不同參數個數的方法。FuncX 和 ActionX 的區別在 FuncX 包裝的是有返回值的方法。

  1. Observable和Subscriber可以做任何事情
    Observable可以是一個數據庫查詢,Subscriber用來顯示查詢結果;Observable可以是屏幕上的點擊事件,Subscriber用來響應點擊事件;Observable可以是一個網絡請求,Subscriber用來顯示請求結果。

  2. Observable和Subscriber是獨立於中間的變換過程的。
    在Observable和Subscriber中間可以增減任何數量的map。整個系統是高度可組合的,操作數據是一個很簡單的過程。

2.操作符from

操作數組或者集合中每個數據,不需要使用for 來遍歷
Observable.from()方法,它接收一個集合作爲輸入,然後每次輸出一個元素給subscriber:

案例:根據輸入的字符串返回一個網站的url列表(搜索引擎)

 query("Hello, world!")
                .subscribe(new Action1<List<String>>() {
                    @Override
                    public void call(List<String> strings) {
                        for(String s:strings){
                            Log.e("call", s);
                        }
                    }
                });

使用from操作符

 query("Hello, world!")
                .subscribe(new Action1<List<String>>() {
                    @Override
                    public void call(List<String> strings) {
//                        for(String s:strings){
//                            Log.e("call", s);
//                        }

                        Observable.from(strings)
                                .subscribe(new Action1<String>() {
                                    @Override
                                    public void call(String s) {
                                        Log.e("call", s);
                                    }
                                });
                    }
                });

多個嵌套的subscription,進行修改

3.操作符(flatMap())

Observable.flatMap()接收一個Observable的輸出作爲輸入,同時輸出另外一個Observable

 query("Hello, world!")
                .flatMap(new Func1<List<String>, Observable<String>>() {
                    @Override
                    public Observable<String> call(List<String> strings) {
                        return Observable.from(strings);
                    }
                })
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.e("call", s);
                    }
                });

flatMap()可以返回任何它想返回的Observable對象。

4.操作符merge,合併觀察者對象

 ArrayList<String> list1 = new ArrayList<String>();
        ArrayList<String> list2 = new ArrayList<String>();

        list1.add("1");
        list1.add("2");
        list1.add("3");

        list2.add("a");
        list2.add("b");
        list2.add("c");

        Observable mObservable1 = Observable.from(list1);
        Observable mObservable2 = Observable.from(list2);

        //合併數據  先發送observable2的全部數據,然後發送 observable1的全部數據
        Observable mObservable3 = Observable.merge(mObservable2, mObservable1);

        mObservable3.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("call3",o.toString());
            }
        });

5. 操作符zip

zip 操作符,合併多個觀察對象的數據。並且允許 Func2()函數重新發送合併後的數據

ArrayList<String> list1 = new ArrayList<String>();
        ArrayList<String> list2 = new ArrayList<String>();

        list1.add("1");
        list1.add("2");
        list1.add("3");

        list2.add("a");
        list2.add("b");
        list2.add("c");

        Observable mObservable1 = Observable.from(list1);
        Observable mObservable2 = Observable.from(list2);

        //合併Observable數據 ,並重新發送組合後的數據
        Observable mObservable3 = Observable.zip(mObservable1, mObservable2, new Func2<String,String,String>() {

            @Override
            public String call(String s, String s2) {
                return s+s2;
            }
        });

        mObservable3.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("zip === ",o.toString());
            }
        });

6. scan累加器操作符的使用

 Observable mObservable = Observable.just(1, 2, 3, 4, 5);
        //返回相加結果
        Observable mObservableScan = mObservable.scan(new Func2<Integer, Integer, Integer>() {
            @Override
            public Integer call(Integer o, Integer o2) {
                return o + o2;
            }
        });

        mObservableScan.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("scan == ", o.toString());
            }
        });

打印結果

D/scan ==: 1
D/scan ==: 3
D/scan ==: 6
D/scan ==: 10
D/scan ==: 15

7. filter 過濾操作符的使用

滿足結果纔會發送

Observable mObservable = Observable.just(1, 2, 3, 4, 5, 6, 7);
        //過濾
        Observable mObservableFilter = mObservable.filter(new Func1<Integer,Boolean>() {
            @Override
            public Boolean call(Integer o) {
                //數據大於4的時候纔會被髮送
                return o > 4;
            }
        });

        mObservableFilter.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("filter == ", o.toString());
            }
        });

結果

D/filter ==: 5
D/filter ==: 6
D/filter ==: 7

8. 消息數量過濾操作符的使用

take :取前n個數據
takeLast:取後n個數據
first 只發送第一個數據
last 只發送最後一個數據
skip() 跳過前n個數據發送後面的數據
skipLast() 跳過最後n個數據,發送前面的數據

Observable mObservable = Observable.just(1, 2, 3, 4, 5, 6, 7);
        //take 發送前三個數據
        Observable mObservableTake = mObservable.take(3);

        mObservableTake.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("take == ", o.toString());
            }
        });

        //takeLast 發送後三個數據
        Observable mObservableTakeLast = mObservable.takeLast(3);
        mObservableTakeLast.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("takeLast",o.toString());
            }
        });

        //first 只發送第一個數據
        Observable mObservableFirst = mObservable.first();
        mObservableFirst.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("first === ",o.toString());
            }
        });

        //last 只發送最後一個數據
        Observable mObservableLast = mObservable.last();
        mObservableLast.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("last === ",o.toString());
            }
        });

        //skip 跳過前2個數據發送後面的數據
        Observable mObservableSkip = mObservable.skip(2);
        mObservableSkip.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("skip === ",o.toString());
            }
        });

        //skipLast 跳過最後2個數據發送後面的數據
        Observable mObservableSkipLast = mObservable.skipLast(2);
        mObservableSkipLast.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("skipLast === ",o.toString());
            }
        });

結果

D/take ==: 1
D/take ==: 2
D/take ==: 3
D/takeLast: 5
D/takeLast: 6
D/takeLast: 7
D/first ===: 1
D/last ===: 7
D/skip ===: 3
D/skip ===: 4
D/skip ===: 5
D/skip ===: 6
D/skip ===: 7
D/skipLast ===: 1
D/skipLast ===: 2
D/skipLast ===: 3
D/skipLast ===: 4
D/skipLast ===: 5

9. elementAt 、elementAtOrDefault

注意:elementAt() 發送數據序列中第n個數據 ,序列號從0開始,如果該序號大於數據序列中的最大序列號,則會拋出異常,程序崩潰,所以在用elementAt操作符的時候,要注意判斷髮送的數據序列號是否越界

Observable mObservable = Observable.just(1, 2, 3, 4, 5, 6, 7);
        Observable mObservableElementAt = mObservable.elementAt(2);
        mObservableElementAt.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("elementAt === ", o.toString());
            }
        });

//        elementAtOrDefault( int n , Object default ) 發送數據序列中第n個數據 ,序列號從0開始。
//        如果序列中沒有該序列號,則發送默認值
        Observable mObservableElementAtOrDefault = mObservable.elementAtOrDefault(8,0);
        mObservableElementAtOrDefault.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("elementAtOrDefault === ",o.toString());
            }
        });

結果

D/elementAt ===: 3
D/elementAtOrDefault ===: 0

10.startWith() 插入數據
在已有數據之前插入數據,數據類型可以是普通類型和Observable 對象

 Observable mObservable = Observable.just("aa","bb","cc");
        Observable mObservableStartWith = mObservable.startWith("11", "22");
        mObservableStartWith.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("StartWith 插入普通數據", o.toString());
            }
        });


        //插入Observable對象
        ArrayList<String> list = new ArrayList<String>();
        list.add("ww");
        list.add("tt");

        mObservable.startWith(Observable.from(list))
                .subscribe(new Action1() {
                    @Override
                    public void call(Object o) {
                        Log.d("startWith 插入Observable 對象",o.toString());
                    }
                });

結果

D/StartWith 插入普通數據: 11
D/StartWith 插入普通數據: 22
D/StartWith 插入普通數據: aa
D/StartWith 插入普通數據: bb
D/StartWith 插入普通數據: cc
D/startWith 插入Observable 對象: ww
D/startWith 插入Observable 對象: tt
D/startWith 插入Observable 對象: aa
D/startWith 插入Observable 對象: bb
D/startWith 插入Observable 對象: cc

11.delay操作符,延遲數據發送

只限制第一條數據發送的時間

Observable mObservable = Observable.just("aa","bb","cc");
        //延遲數據發射的時間,僅僅延時一次,也就是發射第一個數據前延時。發射後面的數據不延時
        Observable mObservableDelay = mObservable.delay(2, TimeUnit.SECONDS);//延遲兩秒發送
        mObservableDelay.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("delay ==", o.toString());
            }
        });

12. interval 輪詢操作符,循環發送數據,數據從0開始遞增

private Subscription mSubscription;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //參數一:延遲時間  參數二:間隔時間  參數三:時間顆粒度 MILLISECONDS 每秒一次
        Observable mObservable = Observable.interval(3000, 1000, TimeUnit.MILLISECONDS);
        mSubscription= mObservable.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("interval == ", o.toString());
            }
        });
    }
    //銷燬的時候停止輪詢
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(mSubscription !=null){
            mSubscription.unsubscribe();
        }
    }

結果

D/interval ==: 0
D/interval ==: 1
D/interval ==: 2
D/interval ==: 3
D/interval ==: 4
D/interval ==: 5
D/interval ==: 6
D/interval ==: 7
D/interval ==: 8
I/[Gralloc]: gralloc_unregister_buffer line 259 size3686400 base0x603ef000 phys_addr0 share_fd55 usage0x900 ion_hnd_debug0x2
I/[Gralloc]: gralloc_unregister_buffer line 259 size3686400 base0x614d4000 phys_addr0 share_fd60 usage0x900 ion_hnd_debug0x7
D/interval ==: 9

13.doOnNext() 操作符,在每次 OnNext() 方法被調用前執行

Observable mObservable = Observable.just("1", "2", "3", "4");
        mObservable.doOnNext(new Action1() {
            @Override
            public void call(Object o) {
                Log.d("doOnNext  call",o.toString());
            }
        }).subscribe(new Observer() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Object o) {
                Log.d("onNext",o.toString());
            }
        });

結果

D/doOnNext  call: 1
D/onNext: 1
D/doOnNext  call: 2
D/onNext: 2
D/doOnNext  call: 3
D/onNext: 3
D/doOnNext  call: 4
D/onNext: 4

14. throttleFirst 操作符

在一段時間內,只取第一個事件,然後其他事件都丟棄。

使用場景:1、button按鈕防抖操作,防連續點擊 2、百度關鍵詞聯想,在一段時間內只聯想一次,防止頻繁請求服務器

Subscription mSubscription;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        //使用interval 達到每秒發送一個,在3秒內只取一個事件,其他的丟失
        mSubscription = Observable.interval(1, TimeUnit.SECONDS)
                .throttleFirst(3, TimeUnit.SECONDS)
                .subscribe(new Action1<Long>() {
                    @Override
                    public void call(Long aLong) {
                        Log.d("throttleFirst == ", aLong.toString());
                    }
                });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mSubscription != null) {
            mSubscription.unsubscribe();
        }
    }

結果

D/throttleFirst ==: 0
D/throttleFirst ==: 4
D/throttleFirst ==: 7
D/throttleFirst ==: 10
D/throttleFirst ==: 13
D/throttleFirst ==: 16
D/throttleFirst ==: 19
D/throttleFirst ==: 22
D/throttleFirst ==: 25

15.distinct 過濾重複的數據

 ArrayList<String> list = new ArrayList<String>();
        list.add("1");
        list.add("2");
        list.add("1");
        list.add("3");
        list.add("4");
        list.add("2");
        list.add("2");
        list.add("1");

        Observable.from(list)
                .distinct()
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.d("distinct == ", s);
                    }
                });

結果

D/distinct ==: 1
D/distinct ==: 2
D/distinct ==: 3
D/distinct ==: 4

16. distinctUntilChanged() 過濾連續重複的數據

ArrayList<String> list = new ArrayList<String>();
        list.add("1");
        list.add("2");
        list.add("1");
        list.add("3");
        list.add("4");
        list.add("2");
        list.add("2");
        list.add("1");

        Observable.from(list)
                .distinct()
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.d("distinct == ", s);
                    }
                });

        Observable.from(list)
                .distinctUntilChanged()//過濾連續重複的數據
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.d("distinctUntilChange == ", s);
                    }
                });

結果

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