徹底搞懂 RxJava — 中級篇

yangxi_001發表於2017-05-17

前言

本文獻給所有想要深入瞭解 RxJava 的人.

如果你還沒閱讀過基礎部分, 請先補習一下功課. 此外, 強烈建議你先過兩遍原始碼的主要邏輯後再讀本文.

本文帶你理解 RxJava 的實現思路, 並解釋原始碼中如何通過多級 Observable < – > Subscriber 實現 `Observable.map` 等 ‘變換’ 操作.

按照慣例, 還是先看一下用法

2

這裡比較神奇的地方是這個 `map`. 下面讓我們一步一步的解析 `create` -> `map` -> `subscribe` 所發生的故事.

第一步: 回憶程式碼 `OBSERVABLE.CREATE`

2

create 後, 我們便有了一個 Observable 物件, 該物件中, 還有 onSubscribe 子物件. 如下圖

1

第二步: `MAP` 的實現  (難度: 四星半. 等級: 重要)

(點選圖片看大圖)

這個 `map` 實際上做了兩件大事:

1)第一件事兒是 new 了一個 ‘變形函式’, 儲存在了 `OperatorMap.transform` 中

8

2)  new了一個新的 Observable. 這個 Observable 的建構函式中, 傳入了一個新的 OnSubscribe. 整個 `lift` 函式的難點就在於這個 OnSubscribe 物件中. 我們仔細看一下它做了什麼. 它其實也做了兩件大事兒:

a) OnSubscribe.call 函式中, 看一下原始碼:

`hook.onLift(operator).call(o)` 建立了一個新的 Subscriber (實際上是一個 proxy), 並在 `Subscriber.onNext` 中呼叫 `transform` 函式對引數 `t` 進行變形, 然後將變形結果轉發給 `o.onNext`. 這麼上面這些變數都是哪裡的呢? 下面的文字請先記住:

`transform` 實際上就是我們 1) 中分析的那個 ‘變形函式’.
`o` 則是我們還沒分析的 ‘第三步’ 中, `subscribe(…)` 的使用者最終的 Subscriber 物件.

b) OnSubscribe.call 做的第二件事兒是呼叫 ‘第一步’ 中 `create` 建立出來的 Observable.onSubscribe 函式! 注意, 這裡呼叫的不是 `map` 自身建立的 observable, 而是 ‘第一步’ 建立的那個. 看下面這個圖幫助你理解:

1

很簡單, 該 ‘變形函式’ 儲存在了 `OperatorMap.transform` 中.

總結一下 `map` 的行為:

  1. 建立了一個新的 Observable,
  2. 建立了一個新的 OnSubscribe: 其中的 `call` 方法是整個呼叫鏈的關鍵. 它呼叫了上一級 `Observable.onSubscribe.call`, 同時, 還將結果通過 `transform` 對 ‘第一步’ 處理後的結果進行變形, 然後將變形後的結果再轉發給 ‘第三步’ 中 `subscribe(Subscriber…)` 中的 `Subscriber` 處理. 那我們馬上看一下 ‘第三步’.

第三步: `SUBSCRIBE` 觸發整個回撥流程. 我們來看一下主要流程(圖中省略與本步驟無關的其它流程)

這一步也很簡單, 就是通過 `Observable.subscribe` 呼叫該物件的 `Observable.onSubscribe.call` 方法, 然後經過一系列呼叫, 最終由該物件內部臨時建立的 Subscriber 物件(上文中的 proxy 物件) 呼叫使用者目標 Subscriber (即程式碼中 `.subscribe(…)` 中的引數) 的方法.

整體梳理

第一步

第二步

第三步

另:

本人 ps 水平有限, 圖有些凌亂請見諒

科學無國界, 感謝 bruce 和 扔物線大神的優秀文章和從你們那裡盜來的圖

Refs:

Grokking 帶你入門
Grokking RxJava, Part 1: The Basics
Grokking RxJava, Part 2: Operator, Operator
Grokking RxJava, Part 3: Reactive with Benefits
Grokking RxJava, Part 4: Reactive Android

Bruce 大頭鬼
RxJava基本流程和lift原始碼分析

扔物線大神
給 Android 開發者的 RxJava 詳解

讀原始碼!
ReactiveX/RxJava

walfud 徹底搞懂 RxJava 系列
徹底搞懂 RxJava — 初級篇
徹底搞懂 RxJava — 中級篇
徹底搞懂 RxJava — 高階篇

學以致用:
FlowImageLoader — 基於 RxJava 實現的圖片非同步載入庫. 該庫作者即 ‘徹底搞懂 RxJava 系列` 作者

Rx 規範
ReactiveX — An API for asynchronous programming  (其中最有用的是 Contract)

其它
Awesome-RxJava
RxJava Essential CN (幫助你瞭解各種 Operator 的使用)

相關文章