前言
經過前幾篇的介紹,對RxJava對模式有了一定的理解:由Observable發起事件,經過中間的處理后由Observer消費。(對RxJava還不了解的可以出門左拐)
之前的代碼中,事件的發起和消費都是在同一個線程中執行,也就是說之前我們使用的RxJava是同步的~~~
觀察者模式本身的目的不就是后臺處理,將處理結果回調給前臺?這同步的是要哪樣?所以,這篇為大家介紹RxJava的重要的概念——Scheduler
參考:給 Android 開發者的 RxJava 詳解
(本文部分內容引用自該博客)
介紹
RxJava在不指定線程的情況下,發起時間和消費時間默認使用當前線程。所以之前的做法
Observable.just(student1, student2, student2)//使用map進行轉換,參數1:轉換前的類型,參數2:轉換后的類型.map(new Func1<Student, String>() {@Overridepublic String call(Student i) {String name = i.getName();//獲取Student對象中的namereturn name;//返回name}}).subscribe(new Action1<String>() {@Overridepublic void call(String s) {nameList.add(s);}});
因為是在主線程中發起的,所以不管中間map的處理還是Action1的執行都是在主線程中進行的。若是map中有耗時的操作,這樣會導致主線程擁塞,這并不是我們想看到的。
Scheduler
Scheduler:線程控制器,可以指定每一段代碼在什么樣的線程中執行。
模擬一個需求:新的線程發起事件,在主線程中消費
private void rxJavaTest3() {Observable.just("Hello", "Word").subscribeOn(Schedulers.newThread())//指定 subscribe() 發生在新的線程.observeOn(AndroidSchedulers.mainThread())// 指定 Subscriber 的回調發生在主線程.subscribe(new Action1<String>() {@Overridepublic void call(String s) {Log.i(TAG, s);}});
上面用到了subscribeOn(),和observeOn()方法來指定發生的線程和消費的線程。
- 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線程,最后的消費在主線程中。
Observable.just("Hello", "Wrold").subscribeOn(Schedulers.newThread())//指定:在新的線程中發起.observeOn(Schedulers.io()) //指定:在io線程中處理.map(new Func1<String, String>() {@Overridepublic String call(String s) {return handleString(s); //處理數據}}).observeOn(AndroidSchedulers.mainThread())//指定:在主線程中處理.subscribe(new Action1<String>() {@Overridepublic 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的使用十分靈活,想要對其熟悉使用只有一個辦法,那就是多用啦,熟能生巧。
以上有錯誤之處感謝指出
參考:給 Android 開發者的 RxJava 詳解
(本文部分內容引用自該博客)