RxJava(五、Scheduler 下)

目錄

一、Is what 是什么
二、Concept 概念
三、Basic realization 基本實(shí)現(xiàn)
四、Scheduler 線程控制(上)
五、Scheduler 線程控制(下)
六、變換

因個(gè)人學(xué)習(xí)需要,故文章內(nèi)容均為網(wǎng)上摘抄整理,感謝創(chuàng)作者的辛勤,源文章地址請(qǐng)看文末。

API(二)

通過subscribeOn()observeOn()控制線程,讓事件的產(chǎn)生和消費(fèi)發(fā)生在不同的線程。同樣,在使用變換的方法(map()、flatMap())時(shí),可以多次切換線程。

線程多次切換

observeOn() 指定的是Subscriber的線程,而這個(gè)Subscriber并不是(嚴(yán)格說應(yīng)為『不一定是』)subscriber()參數(shù)中的Subscriber,而是observeOn()執(zhí)行時(shí)的當(dāng)前Observable所對(duì)應(yīng)的Subscriber,即它的直接下級(jí)Subscriber。換句話說,observeOn()指定的是它之后的操作所在的線程。因此如果有多次切換線程的需求,只要在每個(gè)切換線程的位置調(diào)用一次observeOn()即可,示例如下:

Observable.just(1, 2, 3, 4) // IO 線程,由 subscribeOn() 指定
    .subscribeOn(Schedulers.io())
    .observeOn(Schedulers.newThread())
    .map(mapOperator) // 新線程,由 observeOn() 指定
    .observeOn(Schedulers.io())
    .map(mapOperator2) // IO 線程,由 observeOn() 指定
    .observeOn(AndroidSchedulers.mainThread) 
    .subscribe(subscriber);  // Android 主線程,由 observeOn() 指定

不同于observeOn(),subscribeOn()的位置放在哪里都可以,只被調(diào)用一次。
含多個(gè)subscribeOn()時(shí),只有第一個(gè)會(huì)起作用。

Scheduler 的原理(二)

subscribeOn()observeOn()的內(nèi)部實(shí)現(xiàn),是用lift()

subscribeOn()示意圖:

subscribeOn()

observeOn()示意圖:

observeOn()

相同點(diǎn):subscribeOn()observeOn()都做了線程切換的操作(圖中"schedule..."部分)。
不同點(diǎn):

  • subscribeOn()的線程切換發(fā)生在OnSubscribe中,即在它通知上一級(jí)OnSubscribe時(shí),此時(shí)事件還沒有開始發(fā)送,因此subscribeOn()的線程控制可以從事件發(fā)出的開端就造成影響;
  • observaOn()的線程切換發(fā)生在它內(nèi)建的Subscriber中,即發(fā)生在它即將給下級(jí)Subscriber發(fā)送事件時(shí),因此observeOn()控制的是它后面的線程。

下面用一張圖來解釋當(dāng)多個(gè) subscribeOn()observeOn() 混合使用時(shí),線程調(diào)度是怎么發(fā)生的:

多個(gè)混合使用

圖中含 5 處對(duì)事件的操作:
①和②兩處受第一個(gè) subscribeOn() 影響,運(yùn)行在紅色線程;
③和④處受第一個(gè) observeOn() 影響,運(yùn)行在綠色線程;
⑤處受第二個(gè) observeOn() 影響,運(yùn)行在紫色線程;
第二個(gè) subscribeOn() ,由于在通知過程中線程就被第一個(gè) subscribeOn() 截?cái)啵虼藢?duì)整個(gè)流程并沒有任何影響。

doOnSubscribe()

雖然超過一個(gè)的subscribeOn()對(duì)事件處理的流程沒有影響,但在流程之前卻可以利用。

因?yàn)?code>Subscriber的onStart()可以用作流程開始前的初始化,而onStart()subscribe()發(fā)生時(shí)就被調(diào)用了,因此不能指定線程,只能執(zhí)行在subscribe()被調(diào)用時(shí)的線程。試想,如果onStart()中含有對(duì)線程有要求的代碼(例:在界面顯示ProgressBar,必須在主線程執(zhí)行),將會(huì)有線程非法的風(fēng)險(xiǎn),因?yàn)橛袝r(shí)無法預(yù)測(cè)subscribe()將會(huì)在什么線程執(zhí)行。

Subscriber.onStart()相對(duì)應(yīng)的方法Observable.doOnSubscribe()。和Subscriber.onStart()同樣是在sbscribe()調(diào)用后且事件發(fā)送前執(zhí)行,區(qū)別在于可以指定線程。

  1. 默認(rèn)情況:doOnSubscribe()執(zhí)行在subscribe()發(fā)生的線程;
  2. doOnSubscribe()后有subscribeOn()時(shí),將執(zhí)行在離他最近的subscribeOn()所指定的線程。

示例:

Observable.create(onSubscribe)
    .subscribeOn(Schedulers.io())
    .doOnSubscribe(new Action0() {
        @Override
        public void call() {
            progressBar.setVisibility(View.VISIBLE); // 需要在主線程執(zhí)行
        }
    })
    .subscribeOn(AndroidSchedulers.mainThread()) // 指定主線程
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(subscriber);

參考
給 Android 開發(fā)者的 RxJava 詳解

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容