RxJava線程變換之observeOn與subscribeOn

目錄

1.observeOn()

2.subscribeOn()

3.其他


在藉助Observable實現請求網絡接口我們經常會發現會指定subscribeOn()和observeOn()所屬線程,那麼爲什麼要指定所屬線程呢?

 apiService.getList("api", "getList", page, model, pageId, createTime, "android", "1.3.0", TimeUtil.getCurrentSeconds(), deviceId, 1)
                .subscribeOn(Schedulers.io())//異步線程
                .observeOn(AndroidSchedulers.mainThread())//UI線程
                .subscribe(new Subscriber<Result.Data<List<Item>>>() {
                    @Override
                    public void onCompleted() {}

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                        //發生錯誤,顯示錯誤視圖
                    }

                    @Override
                    public void onNext(Result.Data<List<Item>> listData) {
                        //處理返回數據
                    }
                });

在Android開發時,經常遇到網絡請求或者其他耗時操作,通過我們會在異步線程完成響應操作,在UI線程實現UI顯示的更新,RxJava非常方便實現異步線程和UI線程的切換,通常在subscribeOn()設置異步線程和在observeOn()設置UI線程;我們接下來看看subscribeOn()和observeOn()如何設置相應的所屬線程及運行;

1.observeOn()

在observeOn()指定運行的線程1,則後面運行兩個map()方法和其他方法運行在observeOn()指定的線程,若後面有observeOn()執行新的線程,則observeOn()後面的方法運行在新的線程2,需要了解observeOn()線程運行規則;

輸出日誌:

//輸入運行在第一個ObserveOn指定的線程
I/System.out: .map()-1 => map之前的ObserveOn
I/System.out: .map()-2 => map之前的ObserveOn
//輸入運行在第二個ObserveOn指定的線程
I/System.out: .onNext => subscribe之前的ObserveOn
I/System.out: RxJava-map1-map2-onNext

2.subscribeOn()

subscribeOn()指定的線程作用於上面運行的方法,按照從下到上執行;

I/System.out: .doOnSubscribe()-3 => main
    
I/System.out: .doOnSubscribe()-2 => doOnSubscribe2之後的subscribeOn

I/System.out: .doOnSubscribe()-1 => doOnSubscribe1之後的subscribeOn

I/System.out: OnSubscribe.call() => create之後的subscribeOn
I/System.out: .onNext => create之後的subscribeOn
I/System.out: RxJava-onNext

1)通過查看日誌發現在開始運行的最下面的doOnSubscribe()方法,由於在doOnSubscribe()方法下面沒有指定運行線程,所以運行在主線程,其他doOnSubscribe()方法下面通過subscribe()指定運行線程,則運行在指定線程;

2)subscribe()方法沒有通過observeOn()執行回調運行線程則運行在最上面subscribeOn()指定的線程;

3.其他

測試公用方法

 public Scheduler getNamedScheduler(final String name){
        return Schedulers.from(Executors.newCachedThreadPool(new ThreadFactory() {
            @Override
            public Thread newThread(@NonNull Runnable r) {
                return new Thread(r, name);
            }
        }));
    }

    public void threadInfo(String caller){
        System.out.println(caller + " => " + Thread.currentThread().getName());
    }

doOnSubscribe與onStart類似,均在代碼調用時就會回調,但doOnSubscribe可以通過subscribeOn操作符改變運行的線程且越在後面運行越早。

ReactiveX 官方 observeOn圖示

ReactiveX 官方 subscribeOn圖示

參考:

https://www.jianshu.com/p/59c3d6bb6a6b

 

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