本文献给所有想要深入了解 RxJava 的人.
如果你还没阅读过基础部分, 请先补习一下功课. 此外, 强烈建议你先过两遍源码的主要逻辑后再读本文.
本文带你理解 RxJava 的实现思路, 并解释源码中如何通过多级 Observable < – > Subscriber 实现 `Observable.map` 等 ‘变换’ 操作.
这里比较神奇的地方是这个 `map`. 下面让我们一步一步的解析 `create` -> `map` -> `subscribe` 所发生的故事.
create 后, 我们便有了一个 Observable 对象, 该对象中, 还有 onSubscribe 子对象. 如下图
(点击图片看大图)
这个 `map` 实际上做了两件大事:
1)第一件事儿是 new 了一个 ‘变形函数’, 保存在了 `OperatorMap.transform` 中
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, 而是 ‘第一步’ 创建的那个. 看下面这个图帮助你理解:
很简单, 该 ‘变形函数’ 保存在了 `OperatorMap.transform` 中.
总结一下 `map` 的行为:
这一步也很简单, 就是通过 `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 的使用)