RxJava2.0入門

首先,RxJava1.0和RxJava2.0的核心思想都是觀察者模式,只不過RxJava2.0在
RxJava1.0的基礎對一些方法進行了優化,方便於開發者更好地理解其編程思想,同
時又增加了一部分新的方法解決1.0存在的問題,例如背壓等。所以,如果你學習過
RxJava1.0那麼很好,你可能已經理解了什麼是觀察者模式;如果你沒有學過
RxJava1.0,當然也不必着急,因爲本文將從最基本的觀察者模式講起,讓你從最基本
最簡單的角度入手RxJava。綜上所述,不管你是不是學過RxJava1.0,都不會影響你學
習本篇文章。

觀察者模式

在學習RxJava2.0之前,我們必須要弄明白什麼是觀察者模式。按照我的慣例,先上一個百度百科的權威介紹


簡單介紹一下,A和B兩個,A是被觀察者,B是觀察者,B對A進行觀察,B並不是需要時刻盯着A,而是A如果發生了變化,會主動通知B,B會對應做一些變化。舉個例子,假設A是連載小說,B是讀者,讀者訂閱了連載小說,當小說出現了新的連載的時候,會推送給讀者。讀者不用時刻盯着小說連載,而小說有了新的連載會主動推送給讀者。這就是觀察者模式。而RxJava正是基於觀察者模式開發的。

RxJava2.0的基本使用
理解好了觀察者模式,我們開始RxJava2.0的學習。首先引入RxJava2.0相關的類庫。
compile ‘io.reactivex.rxjava2:rxjava:2.0.1’
compile ‘io.reactivex.rxjava2:rxandroid:2.0.1’
正確使用姿勢:
第一步:創建連載小說(被觀察者)`
//被觀察者

List item

    Observable novel=Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        public void subscribe(ObservableEmitter<String> emitter) throws Exception {
            emitter.onNext("連載1");
            emitter.onNext("連載2");
            emitter.onNext("連載3");
            emitter.onComplete();
        }
    });

List item

Observable中文意思就是被觀察者,通過create方法生成對象,裏面放的參數ObservableOnSubscribe,可以理解爲一個計劃表,泛型T是要操作對象的類型,重寫subscribe方法,裏面寫具體的計劃,本文的例子就是推送連載1、連載2和連載3,在subscribe中的ObservableEmitter對象的Emitter是發射器的意思。ObservableEmitter有三種發射的方法,分別是void onNext(T value)、void onError(Throwable error)、void onComplete(),onNext方法可以無限調用,Observer(觀察者)所有的都能接收到,onError和onComplete是互斥的,Observer(觀察者)只能接收到一個,OnComplete可以重複調用,但是Observer(觀察者)只會接收一次,而onError不可以重複調用,第二次調用就會報異常。
第二步:創建讀者(觀察者)

//觀察者
        Observer<String> reader=new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                mDisposable=d;
                Log.e(TAG,"onSubscribe");
            }

            @Override
            public void onNext(String value) {
                if ("2".equals(value)){
                    mDisposable.dispose();
                    return;
                }
                Log.e(TAG,"onNext:"+value);
            }

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

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

通過new創建接口,並實現其內部的方法,看方法其實就應該差不多知道幹嘛的,onNext、onError、onComplete都是跟被觀察者發射的方法一一對應的,這裏就相當於接收了。onSubscribe(Disposable d)裏面的Disposable對象要說一下,Disposable英文意思是可隨意使用的,這裏就相當於讀者和連載小說的訂閱關係,如果讀者不想再訂閱該小說了,可以調用 mDisposable.dispose()取消訂閱,此時連載小說更新的時候就不會再推送給讀者了。
第三步:讀者和連載小說建立訂閱關係
novel.subscribe(reader);//一行代碼搞定

在這裏細心的你,可能已經發現了怎麼是小說訂閱了讀者,之所以這樣,是因爲RxJava主要是想保持自己的鏈式編程,不得不把Observable(被觀察者)放在前面,這裏大家可以理解爲小說被讀者訂閱了。
這裏我們先看一下輸出效果
在這裏插入圖片描述

輸出效果

小結一下:這就是RxJava2.0最最簡單的用法,創建小說,創建讀者,建立訂閱關係,記住這三步,你就能實現一個最簡單的RxJava2.0的用法。
RxJava2.0的異步和鏈式編程
前言裏面有提到,RxJava是支持異步的,但是RxJava是如何做到的呢?這裏就需要Scheduler。Scheduler,英文名調度器,它是RxJava用來控制線程。當我們沒有設置的時候,RxJava遵循哪個線程產生就在哪個線程消費的原則,也就是說線程不會產生變化,始終在同一個。然後我們一般使用RxJava都是後臺執行,前臺調用,本着這個原則,我們需要調用observeOn(AndroidSchedulers.mainThread()),observeOn是事件回調的線程,AndroidSchedulers.mainThread()一看就知道是主線程,subscribeOn(Schedulers.io()),subscribeOn是事件執行的線程,Schedulers.io()是子線程,這裏也可以用Schedulers.newThread(),只不過io線程可以重用空閒的線程,因此多數情況下 io() 比 newThread() 更有效率。前面的代碼根據異步和鏈式編程的原則,我們可以寫成

 Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext("連載1");
                emitter.onNext("連載2");
                emitter.onNext("連載3");
                emitter.onComplete();
            }
        })
                .observeOn(AndroidSchedulers.mainThread())//回調在主線程
                .subscribeOn(Schedulers.io())//執行在io線程
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.e(TAG,"onSubscribe");
                    }

                    @Override
                    public void onNext(String value) {
                        Log.e(TAG,"onNext:"+value);
                    }

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

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

這裏就是RxJava最常用的寫法,異步+鏈式編程,還要再說一下,subscribe的方法重載,subscribe()方法裏什麼參數也不放是空實現,也就是說連載小說無論出什麼連載,讀者都不關心,推送過來了也不讀,如果讀者只關心onNext方法裏的內容,可以直接重載subscribe(Consumer<? spuer T> onNext)這個方法,會減少代碼,當然如果是初學者還是建議創建Observer對象。

在這裏插入圖片描述
subscrib的方法重載

應用場景
說了這麼多RxJava2.0的用法,你一定要問了到底在什麼情況下使用?下面先給大家介紹一下典型的場景。
一、與Retrofit聯用
Retrofit+RxJava的上網模式已經非常火了,如果有不瞭解的可以看筆者的這篇文章https://www.jianshu.com/writer#/notebooks/5118090/notes/25405151
二、Rxpermissions等類庫的使用
基於RxJava的開源類庫Rxpermissions、RxBinding以及RxBus在很多項目中已經非常常見,並且被證明了是極其好用的。
三、所有用到異步的地方
因爲RxJava就是一個支持異步的鏈式編程,所以所有的用到異步的地方,我們都可以用RxJava來完成,下面給大家舉幾個例子。
定時執行任務

 Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(123);
                sleep(3000);
                emitter.onNext(456);
            }
        }).observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.e(TAG,integer+"");
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {

                    }
                }, new Action() {
                    @Override
                    public void run() throws Exception {

                    }
                });

看完上面的代碼你肯定在想,這麼多代碼,幹嘛不直接new Handler().postDelayed()。如果你的程序線程裏面做的操作很簡單,那麼你用new Handler().postDelayed()無所謂,但是如果你的操作很複雜,那麼這時候就體現出了RxJava的好處了,借用扔物線大神的一句話就是"隨着程序邏輯變得越來越複雜,RxJava依然能夠保持簡潔"。
下面來說一個複雜的操作,比如我們要依次加載10張圖片(加載圖片是耗時過程),其中第六張我們延時3秒加載,第7張我們複製到sd卡里,第8張我們要上網絡,那麼請問你要怎麼做,如果用Handler,必然是各種嵌套,各種邏輯複雜得讓你再看一眼都難受,但是如果使用RxJava呢?

Observable.create(new ObservableOnSubscribe<Drawable>() {
            @Override
            public void subscribe(ObservableEmitter<Drawable> emitter) throws Exception {
                for (int i=0;i<drawableRes.length;i++){
                    Drawable drawable=getResources().getDrawable(drawableRes[i]);
                    //第6個圖片延時3秒後架子
                    if (i==5){
                        sleep(3000);
                    }
                    //複製第7張圖片到sd卡
                    if (i==6){
                        Bitmap bitmap=((BitmapDrawable)drawable).getBitmap();
                        saveBitmap(bitmap,"test.png", Bitmap.CompressFormat.PNG);
                    }
                    //上傳到網絡
                    if (i==7){
                        updateIcon(drawable);
                    }
                    emitter.onNext(drawable);
                }
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Drawable>() {
                    @Override
                    public void accept(Drawable drawable) throws Exception {
                           //回調後在UI界面上展示出來
                    }
                });

沒有任何嵌套,邏輯依然簡潔,這就是RxJava的好處。
總結
RxJava2.0是非常好用的一個異步鏈式庫,遵循觀察者模式。理解觀察者模式可以根據連載小說和讀者的關係,被觀察者是連載小說,觀察者是讀者,讀者訂閱小說,當小說有了新的連載推送給讀者,這就是觀察者模式;創建RxJava最簡單的步驟,一、創建被觀察者對象,二、創建觀者對象,三創建訂閱關係;RxJava2.0的應用場景,只要記得一句話就是所有的異步都可以用RxJava來做就可以了,尤其是複雜的場景,越是複雜的場景越能體現RxJava的好處。

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