RxAndroid深入理解

注:本文的分析基于RxAndroid 1.2.1

现在项目里面大多都已经使用了rxjava, 因此对于很多rxjava的扩展库,也都可以使用在项目里了。
RxAndroid 已经成为标配了,基本只要使用了Rxjava, 你肯定能看见RxAndroid的身影。

使用场景:

Observable.just("one", "two", "three", "four", "five")
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(/* an Observer */);

很简单,就是指定到主线程上,即UI线程上,所以subscribe里的内容就会执行在主线程上。

或者其他线程的Looper

Looper backgroundLooper = // ...
Observable.just("one", "two", "three", "four", "five")
        .observeOn(AndroidSchedulers.from(backgroundLooper))
        .subscribe(/* an Observer */)

这种使用方式,就是把后台线程所绑定的Looper作为AndroidSchedulers的参数, 那么这时实际上等同于 :

...
observeOn(Scheduler.io()); 

因此这种方式下,subscribe 里的代码是执行在backgroundLooper所绑定的线程。

代码结构:

Paste_Image.png

实现分析:

既然使用的入口是AndroidScheduler 那就重这里开始分析。

首先看看AndroidScheduler的创建:

Paste_Image.png

搭眼一看,饿汉式的单例, 并且这个单例是使用AtomicReference的,原子操作,保证多线程情况下,线程获取的值都是最新的,正确的。实例化用到了RxAndroidPlugins, 看下:

Paste_Image.png

同样是AtomicReference ,同样是单例。

Paste_Image.png

又引用到RxAndroidSechedulersHook

Paste_Image.png

这是个什么鬼,搞了半天最后getMainThreadScheduler() 返回null. 再回头看看前面AndroidScheduler实例化的地方。

Paste_Image.png

soga, 空的话直接返回一个LooperScheduler, 否则直接使用。

这就是问题了,为什么要绕这么大一圈?

我觉得秘密在RxAndroidSchedulersHook里的一个方法,如下:


Paste_Image.png

那么这个方法在哪里被调用了呢? 这个问题先放着,后面会讲到。
先来看看注释,大概的意思是,该方法在把action 交给Scheduler处理之前被执行, 可以用于
包装/装饰/日志记录(翻译过来好别扭!), 默认值只是传递作用,直接返回。

如果你仔细看看Rxjava RxJavaSchedulersHook 类,你会发现如出一辙, 一模一样!!!
连注释都长一样!
.
.

这里是把UI线程的Looper作为参数创建了一个LoopScheduler.

再进去看看LooperScheduler:
Paste_Image.png

LooperScheduler 继承自Scheduler, 因此必须实现createWorker方法。

Worker是个什么东东?

Paste_Image.png

实际上是Scheduler里 的一个静态抽象类,实现了Subscription接口,因此也就有unSubscriber方法。
可以取消订阅,但是Worker并没有实现取消订阅方法,而是交给子类去实现,比如这里的HandlerWorker就实现了Worker抽象类,下面是截取的核心部分:

Paste_Image.png

HandlerWorker实现了schedule方法,一个是有延时的,一个是无延时的。 从代码看首先判断了是否被取消订阅了, 取消了则直接返回,不做任何处理,否者接着走。
哎呦喂! 哎呦喂! 这不是RxAndroidSchedulersHook 里的那个我们之前放着的方法吗?
在这里被调用了。

接着走这里又跳出来个ScheduledAction, 贴出代码!

Paste_Image.png
Paste_Image.png

从代码中不难看出, 在LooperScheduler 中创建的handler, 交给HandlerWorker后又交给了ScheduledAction。 该类实现了Runnable 接口,run方法里面调用了action.call() ;看来这里才是真正调用的地方,然后如果发生异常就调用RxjavaPlugin 触发错误处理。

ScheduledAction同样实现了Subscription接口, 取消也很简单,handler removeCallbacks(this).。

看完了ScheduledAction是不是感觉一目了然了,接着上面HandlerWorker的schedule方法讲,
后面从Message池中获取了一个Message并且把message的Callback参数设置为ScheduledAction的实例, 然后后面handler.sendMessageDelayed(message, unit.toMillis(delayTime)); 延时发送这条消息。 看到这你应该明白了,就是利用handler把消息发送到了looper所在的线程! 因此你传递进去的Looper绑定在什么线程, 我们的action(订阅者)就在哪个线程执行!

而我们平时都是使用AndroidScheduler.mainThread(); 默认传递的就是UI线程的Looper!

有的小伙伴说,不对吧,我没看到接收处理消息的地方啊! 楼主你个坑!
实际上这就是handler你了解的不够细:

                                  (Handler.java)
Paste_Image.png

看到了吗? 这里是handler接收到Looper分配的消息的处理, 先是判断了msg有没有callback, 有的话就不会调用handleMessage(msg)了,而是调用了handlerCallback(msg); 从而调用了runnable的run方法,也就是ScheduledAction的run()方法.

Paste_Image.png

.

RxAndroid中还有一个类没讲 MainThreadSubscription, 下篇文章会讲下RxBinding,里面会讲到,这里就不多说了。

http://www.jianshu.com/p/ded241051b61

说了这么多废话,希望对你有所帮助! 如果有任何你认为不对的地方,请及时反馈给我,谢谢

.

点个赞, 谢谢!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 我从去年开始使用 RxJava ,到现在一年多了。今年加入了 Flipboard 后,看到 Flipboard 的...
    Jason_andy阅读 5,382评论 7 62
  • 基本三和弦的质地: Ⅰ:晴朗而不强烈的天光,无色Ⅱm:下午黄色阳光,淡黄色灯光Ⅲm:草丛,树丛,风Ⅳ:金属光泽,尖...
    Feihei阅读 136评论 0 0
  • 暗恋:我的青春与你有个约会 日尧林夕 记得我们初次相识的那一天,也是你给我留下深刻印...
    子辛木夕阅读 379评论 2 3
  • 还记得你小时候做的记忆最深刻的梦吗? 记得初中的时候,常常梦到的一个场景就是自己一个人默默站在在学校的大门口,天空...
    MiniKay阅读 146评论 0 0