RxJava深入簡(jiǎn)出

前言

網(wǎng)絡(luò)上很多關(guān)于 RxJava 的文章都是基于「方法論」的,很少?gòu)膶?shí)現(xiàn)原理的角度去透析生兆。本文希望通過(guò)深入簡(jiǎn)出地描述 RxJava 的一些重要原理卧斟,讓讀者大概知道 RxJava 是如何 Work 的链烈。

核心對(duì)象

ReactiveX 是基于觀察者模式設(shè)計(jì)的社搅,核心對(duì)象只有 Observable 和 Observer驻债。它們最簡(jiǎn)單的代碼為:

interfaceObservable{voidsubscribe(Observerobserver);}interfaceObserver{voidonNext(Tt);}

Observable 的核心方法是 subscribe()乳规,它接收一個(gè) Observer。當(dāng)調(diào)用 subscribe() 的時(shí)候合呐,就開(kāi)始通過(guò)調(diào)用 Observer 的 onNext() 方法發(fā)射數(shù)據(jù)暮的。

上下游

以下代碼中:

ob1=Observable.create(Func1);ob2=ob1.map(Func2);ob3=ob2.subscribeOn(SchedulerA);

ob1 是 ob2 的上游,ob3 是 ob2 的下游淌实《潮纾可以看出,對(duì) Observable 進(jìn)行一次「操作」后會(huì)得到一個(gè)新的 Observable翩伪。

官方定義:Doubt about the terms Upstream vs Downstream · Issue #5022 · ReactiveX/RxJava

操作符

Rx 里的操作符微猖,例如上面的 map(Func2)谈息,其內(nèi)部實(shí)現(xiàn)是這樣(官方命名稍有不同):

ob2=newMapObservable(ob1,Func2);

所以上一小節(jié)的代碼可以寫成:

ob1=newCreateObservable(Func1);ob2=newMapObservable(ob1,Func2);ob3=newSubscribeOnObservable(ob2,SchedulerA);

可以說(shuō) Rx 里最重要的是「組合操作符缘屹,加工數(shù)據(jù)流」。

官方操作符文檔:ReactiveX - Operators

操作符的內(nèi)部實(shí)現(xiàn)的核心思想是「Wrap」侠仇,例如我們可以通過(guò)?Wrap Observable?來(lái)實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的沒(méi)有任何操作的操作符:

classNoOpObservable{Observableupstream;NoOpObservable(Observableupstream){this.upstream=upstream;}voidsubscribe(Observerdownstream){upstream.subscribe(downstream);}}

可以看到轻姿,在我們 NoOpObservable 的核心方法 subscribe() 里,我們直接通過(guò)調(diào)用上游 Observable 的 subscribe() 方法逻炊,把下游的 Observer 往上游傳互亮。這樣,我們就成功把下游和上游之間建立聯(lián)系了余素。

接下來(lái)我們?cè)黾与y度豹休,通過(guò)?Wrap Observer(注意是 Observer)來(lái)實(shí)現(xiàn)一個(gè)對(duì)數(shù)據(jù)流進(jìn)行加工的操作符。舉個(gè)例子桨吊,MapObservable 就是一個(gè)能對(duì)數(shù)據(jù)流進(jìn)行加工的操作符威根,它在構(gòu)造時(shí)傳入一個(gè) Func 參數(shù),類型為:

(T) -> U

這個(gè) Func 的作用视乐,就是把上游發(fā)射的數(shù)據(jù) T 加工成 U 然后繼續(xù)往下游傳遞洛搀。例如,我們可以使用 Func 把上游發(fā)射的數(shù)據(jù)轉(zhuǎn)換為 String 再傳遞給下游:

(T t) -> t.toString();

前面有說(shuō)到佑淀,Observable 是通過(guò)調(diào)用 onNext() 來(lái)向 Observer 發(fā)射數(shù)據(jù)的留美,為了避免 Observable 直接向最下游的 Observer 直接發(fā)射數(shù)據(jù)(因?yàn)槲覀冞€要進(jìn)行加工),所以我們需要對(duì) Observer 也進(jìn)行 Wrap伸刃,于是我們可以把 MapObservable 設(shè)計(jì)成這樣:

classMapObservable{MapObservable(Observableupstream,FuncmapFunc){/* ... */}voidsubscribe(Observerdownstream){upstream.subscribe(newWrapObserver(downstream,mapFunc));}classWrapObserver(){WrapObserver(Observerdownstream,FuncmapFunc){/* ... */}voidonNext(Tdata){UnewData=mapFunc.apply(data);downstream.onNext(newData);}}}

subscribeOn & observeOn

這是 RxJava 中最常用谎砾,但又不好理解的兩個(gè)操作符。因?yàn)樗鼈冏陨聿粚?duì)數(shù)據(jù)進(jìn)行任何加工捧颅,而是對(duì)其它操作符產(chǎn)生「副作用」景图。

為了更好地理解這兩個(gè)操作符,我制作了個(gè)動(dòng)畫來(lái)展示它們的工作流程:

圖中分別有 A B C 三個(gè)不同的 Scheduler,它們會(huì)把 Runnable/Func 扔到不同的線程上去執(zhí)行,而上圖中不同的顏色代表被不同的 Scheduler 執(zhí)行袁翁。

可以看到卤恳,subscribeOn() 其實(shí)影響的是上游操作符中的 subscribe() 操作程梦,而 observeOn() 影響的是下游操作符中的 onNext() 操作(這里是泛指窃判,當(dāng)然還包括 onComplete()斜姥、onError() 等)惑惶。

所以设塔,想要確定操作符上的某個(gè) Func 是在哪個(gè) Scheduler 上工作時(shí)凄吏,先要確定這個(gè) Func 是在操作符上的 subscribe() 還是 onNext() 上執(zhí)行的。例如 Create 操作符傳入的 Func 是在 subscribe() 上執(zhí)行的闰蛔,所以它優(yōu)先受下游最近的 subscribeOn() 調(diào)度痕钢。而 Map 操作符傳入的 Func 是在 onNext() 上執(zhí)行的,所以它優(yōu)先受上游最近的 observeOn() 調(diào)度序六。

再例如 Collect 操作符:

.collect(()->V func1, (T)->U func2)

傳入的 func1 是在 subscribe() 上執(zhí)行的任连,而 func2 是在 onNext() 上執(zhí)行,所以 func1 和 func2 可能被兩個(gè)不同的 Scheduler 調(diào)度例诀。

附《Android核心知識(shí)筆記2020》分享

前段時(shí)間我和圈子里的幾位架構(gòu)師朋友一起閑聊時(shí)的突發(fā)奇想随抠,我們?cè)趯W(xué)習(xí)Android開(kāi)發(fā)的時(shí)候或多或少也受到了一些前輩的指導(dǎo),所以想把這份情懷延續(xù)下去繁涂。三個(gè)月后拱她,這套資料就出來(lái)了,需要這份資料的朋友加Android學(xué)習(xí)交流群1049273031即可獲取扔罪。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末秉沼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子矿酵,更是在濱河造成了極大的恐慌唬复,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坏瘩,死亡現(xiàn)場(chǎng)離奇詭異盅抚,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)倔矾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門妄均,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人哪自,你說(shuō)我怎么就攤上這事丰包。” “怎么了壤巷?”我有些...
    開(kāi)封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵邑彪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我胧华,道長(zhǎng)寄症,這世上最難降的妖魔是什么宙彪? 我笑而不...
    開(kāi)封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮有巧,結(jié)果婚禮上释漆,老公的妹妹穿的比我還像新娘。我一直安慰自己篮迎,他們只是感情好男图,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著甜橱,像睡著了一般逊笆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上岂傲,一...
    開(kāi)封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天难裆,我揣著相機(jī)與錄音,去河邊找鬼譬胎。 笑死差牛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的堰乔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼脐恩,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼镐侯!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起驶冒,我...
    開(kāi)封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤苟翻,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后骗污,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體崇猫,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年需忿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了诅炉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡屋厘,死狀恐怖涕烧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情汗洒,我是刑警寧澤议纯,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站溢谤,受9級(jí)特大地震影響瞻凤,放射性物質(zhì)發(fā)生泄漏憨攒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一阀参、第九天 我趴在偏房一處隱蔽的房頂上張望浓恶。 院中可真熱鬧,春花似錦结笨、人聲如沸包晰。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)伐憾。三九已至,卻和暖如春赫模,著一層夾襖步出監(jiān)牢的瞬間树肃,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工瀑罗, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留胸嘴,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓斩祭,卻偏偏與公主長(zhǎng)得像劣像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子摧玫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載自:https://xiaobailong24.me/2017/03/18/Android-RxJava2.x...
    Young1657閱讀 2,022評(píng)論 1 9
  • 怎么如此平靜, 感覺(jué)像是走錯(cuò)了片場(chǎng).為什么呢, 因?yàn)樯舷掠喂ぷ髟谕粋€(gè)線程呀騷年們! 這個(gè)時(shí)候上游每次調(diào)用emit...
    Young1657閱讀 1,472評(píng)論 2 1
  • 一耳奕、RxJava操作符概述 RxJava中的操作符就是為了提供函數(shù)式的特性,函數(shù)式最大的好處就是使得數(shù)據(jù)處理簡(jiǎn)潔易...
    BrotherChen閱讀 1,620評(píng)論 0 10
  • 一诬像、RxJava操作符概述 RxJava中的操作符就是為了提供函數(shù)式的特性屋群,函數(shù)式最大的好處就是使得數(shù)據(jù)處理簡(jiǎn)潔易...
    無(wú)求_95dd閱讀 3,092評(píng)論 0 21
  • 一、RxJava操作符概述 RxJava中的操作符就是為了提供函數(shù)式的特性坏挠,函數(shù)式最大的好處就是使得數(shù)據(jù)處理簡(jiǎn)潔易...
    測(cè)天測(cè)地測(cè)空氣閱讀 636評(píng)論 0 1