【Android】RxJava的使用(四)線程控制 —— Scheduler

並無關係的圖

前言

通過前幾篇的介紹,對RxJava對模式有了必定的理解:由Observable發起事件,通過中間的處理後由Observer消費。(對RxJava還不瞭解的能夠出門左拐)
以前的代碼中,事件的發起和消費都是在同一個線程中執行,也就是說以前咱們使用的RxJava是同步的~~~
觀察者模式自己的目的不就是後臺處理,將處理結果回調給前臺?這同步的是要哪樣?因此,這篇爲你們介紹RxJava的重要的概念——Schedulerjava

參考: 給 Android 開發者的 RxJava 詳解
(本文部份內容引用自該博客)

介紹

RxJava在不指定線程的狀況下,發起時間和消費時間默認使用當前線程。因此以前的作法數據庫

Observable.just(student1, student2, student2)
                //使用map進行轉換,參數1:轉換前的類型,參數2:轉換後的類型
                .map(new Func1<Student, String>() {
                    @Override
                    public String call(Student i) {
                        String name = i.getName();//獲取Student對象中的name
                        return name;//返回name
                    }
                })
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        nameList.add(s);
                    }
                });

由於是在主線程中發起的,因此無論中間map的處理仍是Action1的執行都是在主線程中進行的。如果map中有耗時的操做,這樣會致使主線程擁塞,這並非咱們想看到的。網絡

Scheduler

Scheduler:線程控制器,能夠指定每一段代碼在什麼樣的線程中執行。
模擬一個需求:新的線程發起事件,在主線程中消費ide

private void rxJavaTest3() {
        Observable.just("Hello", "Word")
                .subscribeOn(Schedulers.newThread())//指定 subscribe() 發生在新的線程
                .observeOn(AndroidSchedulers.mainThread())// 指定 Subscriber 的回調發生在主線程
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.i(TAG, s);
                    }
                });

上面用到了subscribeOn(),和observeOn()方法來指定發生的線程和消費的線程。post

  • subscribeOn():指定subscribe() 所發生的線程,即 Observable.OnSubscribe 被激活時所處的線程。或者叫作事件產生的線程。
  • observeOn():指定Subscriber 所運行在的線程。或者叫作事件消費的線程。

以及參數Scheduler,RxJava已經爲咱們提供了一下幾個Scheduler性能

  • Schedulers.immediate():直接在當前線程運行,至關於不指定線程。這是默認的 Scheduler。
  • Schedulers.newThread():老是啓用新線程,並在新線程執行操做。
  • Schedulers.io(): I/O 操做(讀寫文件、讀寫數據庫、網絡信息交互等)所使用的 Scheduler。行爲模式和 newThread() 差很少,區別在於 io() 的內部實現是是用一個無數量上限的線程池,能夠重用空閒的線程,所以多數狀況下 io() 比 newThread() 更有效率。不要把計算工做放在 io() 中,能夠避免建立沒必要要的線程。
  • Schedulers.computation():計算所使用的 Scheduler。這個計算指的是 CPU 密集型計算,即不會被 I/O 等操做限制性能的操做,例如圖形的計算。這個 Scheduler 使用的固定的線程池,大小爲 CPU 核數。不要把 I/O 操做放在 computation() 中,不然 I/O 操做的等待時間會浪費 CPU。
  •  AndroidSchedulers.mainThread():它指定的操做將在 Android 主線程運行。

屢次切換線程

看完上面的介紹想必對RxJava線程的切換有了一些理解,上面只是對事件的發起和消費制定了線程。若是中間有map之類的操做呢?是否能夠實現發起的線程在新線程中,map的處理在IO線程,最後的消費在主線程中。spa

Observable.just("Hello", "Wrold")
                .subscribeOn(Schedulers.newThread())//指定:在新的線程中發起
                .observeOn(Schedulers.io())         //指定:在io線程中處理
                .map(new Func1<String, String>() {
                    @Override
                    public String call(String s) {
                        return handleString(s);       //處理數據
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())//指定:在主線程中處理
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        show(s);                       //消費事件
                    }
                });

能夠看到observeOn()被調用了兩次,分別指定了map的處理的現場和消費事件show(s)的線程。線程

若將observeOn(AndroidSchedulers.mainThread())去掉會怎麼樣?不爲消費事件show(s)指定線程後,show(s)會在那裏執行?
其實,observeOn() 指定的是它以後的操做所在的線程。也就是說,map的處理和最後的消費事件show(s)都會在io線程中執行。
observeOn()能夠屢次使用,能夠隨意變換線程

小結

學會線程控制後纔算是真正學會了使用RxJava。RxJava的使用十分靈活,想要對其熟悉使用只有一個辦法,那就是多用啦,熟能生巧。code

以上有錯誤之處感謝指出

參考:給 Android 開發者的 RxJava 詳解
(本文部份內容引用自該博客)server

相關文章
相關標籤/搜索