2章 RxJava基本使用

Hensen發表於2019-05-13

本篇文章已授權微信公眾號 YYGeeker 獨家釋出轉載請標明出處

CSDN學院課程地址

2. RxJava基本使用

在RxJava使用之前記得在Gradle中新增依賴引入

implementation "io.reactivex.rxjava2:rxjava:2.1.12"
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
複製程式碼

2.1 事件發射

在上面的例子中,我們可以注意到被觀察者中有個Emitter(發射器),發射器的位置位於subscribe回撥引數ObservableEmitter<String> e中,通過名字我們可以知道,RxJava的事件通知就是通過它來進行傳送的,所以它是一個事件發射器,發射器能傳送的事件有onNext()onComplete()onError(),在觀察者的回撥中,分別對應著相同方法名進行回撥,這裡對觀察者的回撥方法進行簡單介紹

  • onSubscribe():當觀察者被訂閱時回撥
  • onNext():當觀察者收到onNext事件時回撥
  • onComplete():當觀察者收到onComplete事件時回撥
  • onError():當觀察者收到onError事件時回撥

2.2 鏈式呼叫

人類就喜歡酷炫的東西,炫耀自身的優點,當然RxJava也少不了人類這種心理,就是鏈式程式設計,下面這段程式碼可以完美替代例子上面的所有程式碼,其效果是和上面一樣的。這裡需要注意的是,建立Observer過程中,會將所有的接收方法都建立出來,如果此時程式發生異常,RxJava預設會將異常資訊try-catch

public static void main(String[] args) {
    //建立被觀察者
    Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        //預設在主執行緒裡執行該方法
        public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
            e.onNext("俊俊俊很帥");
            e.onNext("你值得擁有");
            e.onNext("取消關注");
            e.onNext("但還是要保持微笑");
            e.onComplete();
        }
    })
            //建立觀察者並訂閱
            .subscribe(new Observer<String>() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(String s) {
                    System.out.println("onNext=" + s);
                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onComplete() {

                }
            });
}
複製程式碼

2.3 選擇呼叫

久而久之,人類喜歡簡潔,喜歡定製服務,巧了,RxJava也給你滿足了,下面這段程式碼中,實現的方法跟上面的實現方法是對應起來的,大家看引數就知道哪個對應哪個了,你可以通過建立Consumer,不需要實現的方法你可以不寫,看上去更簡潔,這裡我為了方便大家看,都new出來了,Consumer就是消費者的意思,可以理解為消費了onNext等等等事件。這裡需要注意的是,建立Consumer過程中,如果沒有將第二個Throwable的Consumer建立出來,如果此時程式發生異常,程式將會崩潰

public static void main(String[] args) {
    Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
            e.onNext("俊俊俊很帥");
            e.onNext("你值得擁有");
            e.onNext("取消關注");
            e.onNext("但還是要保持微笑");
            e.onComplete();
        }
    }).subscribe(
            new Consumer<String>() {
                @Override
                public void accept(@NonNull String s) throws Exception {
                    //對應onNext()
                    System.out.println("accept=" + s);
                }
            }, new Consumer<Throwable>() {
                @Override
                public void accept(@NonNull Throwable throwable) throws Exception {
                    //對應onError()
                }
            }, new Action() {
                @Override
                public void run() throws Exception {
                    //對應onComplete()
                }
            }, new Consumer<Disposable>() {
                @Override
                public void accept(@NonNull Disposable disposable) throws Exception {
                    //對應onSubscribe()
                }
            });
}
複製程式碼

2.4 執行緒切換

當然Rxjava的使用不僅僅這麼簡單的事件傳送,他還能完成一些業務上的邏輯。比如註冊登入操作,正常的邏輯是通過註冊去獲取使用者的Token,然後通過Token進行登入,這個過程涉及到註冊需要在子執行緒去進行網路請求,然後在UI執行緒中更新介面提示,然後再切換到子執行緒進行登入操作,最後又得切換到UI執行緒去更新介面,這一系列的操作,也是可以通過RxJava的執行緒切換來進行實現,在RxJava中的執行緒切換特別簡單,只要下面這兩句話就能自由的在子執行緒和UI執行緒中自由切換

public static void main(String[] args) {
    //建立被觀察者
    Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        //預設在主執行緒裡執行該方法
        public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
            e.onNext("俊俊俊很帥");
            e.onNext("你值得擁有");
            e.onNext("取消關注");
            e.onNext("但還是要保持微笑");
            e.onComplete();
        }
    })
            //將被觀察者切換到子執行緒
            .subscribeOn(Schedulers.io())
            //將觀察者切換到主執行緒  需要在Android環境下執行
            .observeOn(AndroidSchedulers.mainThread())
            //建立觀察者並訂閱
            .subscribe(new Observer<String>() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(String s) {
                    System.out.println("onNext=" + s);
                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onComplete() {

                }
            });
}
複製程式碼

2.5 執行緒排程器

說到執行緒切換,就必須不得不說的是RxJava的執行緒排程器,其排程器就是Schedulers,在排程器中封裝了各式各樣的執行緒提供給我們使用,下面舉例其現有的排程器列表

排程器型別 效果
Schedulers.computation() 用於計算任務,如事件迴圈或和回撥處理,不要用於IO操作(IO操作請使用Schedulers.io());預設執行緒數等於處理器的數量
Schedulers.from(executor) 使用指定的Executor作為排程器
Schedulers.immediate() 在當前執行緒立即開始執行任務
Schedulers.io() 用於IO密集型任務,如非同步阻塞IO操作,這個排程器的執行緒池會根據需要增長;對於普通的計算任務,請使用Schedulers.computation();Schedulers.io()預設是一個CachedThreadScheduler,很像一個有執行緒快取的新執行緒排程器
Schedulers.newThread() 為每個任務建立一個新執行緒
Schedulers.trampoline() 當其它排隊的任務完成後,在當前執行緒排隊開始執行

2.6 事件排程器

RxJava事件發出去並不是置之不顧,要有合理的管理者來管理它們,在合適的時機要進行釋放事件,這樣才不會導致記憶體洩漏,這裡的管理者我們稱為事件排程器(或事件管理者)CompositeDisposable。Rxjava的事件流發出去後,會返回Disposable型別的物件,我們可以將該物件新增到事件排程器上,然後進行相關操作,這裡的事件排程器我們可以簡單的理解為事件的容器

public class Main {

    private static CompositeDisposable mRxEvent = new CompositeDisposable();

    public static void main(String[] args) {
        Disposable subscribe = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
                e.onNext("俊俊俊很帥");
                e.onNext("你值得擁有");
                e.onNext("取消關注");
                e.onNext("但還是要保持微笑");
                e.onComplete();
            }
        }).subscribe(
                new Consumer<String>() {
                    @Override
                    public void accept(@NonNull String s) throws Exception {
                        //對應onNext()
                        System.out.println("accept=" + s);
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(@NonNull Throwable throwable) throws Exception {
                        //對應onError()
                    }
                }, new Action() {
                    @Override
                    public void run() throws Exception {
                        //對應onComplete()
                    }
                }, new Consumer<Disposable>() {
                    @Override
                    public void accept(@NonNull Disposable disposable) throws Exception {
                        //對應onSubscribe()
                    }
                });
        
        mRxEvent.add(subscribe);
        mRxEvent.clear();
    }
}
複製程式碼

CompositeDisposable提供的方法中,都是對事件的管理

  • dispose():釋放所有事件
  • clear():釋放所有事件,實現同dispose()
  • add():增加某個事件
  • addAll():增加所有事件
  • remove():移除某個事件並釋放
  • delete():移除某個事件

2.7 "冷"與"熱"

RxJava的事件發射分為冷與熱,一個"熱"的Observable可能一建立完就開始發射資料,因此所有後續訂閱它的觀察者可能從序列中間的某個位置開始接受資料(有一些資料錯過了)。一個"冷"的Observable會一直等待,直到有觀察者訂閱它才開始發射資料,因此這個觀察者可以確保會收到整個資料序列

2.8 小結

RxJava可以簡單的歸結為三步驟

  • 建立:Rx可以建立事件流和資料流(.create的過程)
  • 組合:Rx可以通過操作符的組合變換資料流(.subscribeOn過程和.observeOn過程)
  • 監聽:Rx可以訂閱任何可觀察的資料流並執行操作(.subscribe過程)

相關文章