Handler原理讲解及源码分析

不用多说先上一张图
这里写图片描述
一,发送消息
首先我们每次会创建一个Handler会调用源码
这里写图片描述
如果looper对象为空的话会执行Looper.prepare()将一个新的Looper放入ThreadLocal中。
这里写图片描述
最终都会执行Looper.mylooper()的方法
这里写图片描述
然后调用Looper.mQuene()的方法生成MessageQuene对象
这里写图片描述
到此为止这就生成了MessageQuene对象了。这就使得handler创建对象的时候创建了MessageQuene对象了
二,创建消息
在此过程会调用
这里写图片描述
然后据需看源码会发现中途回调用
这里写图片描述
通过message.obtain()创建消息
这里写图片描述
可以看源码知道,当消息池中有消息的时候就用消息池中的消息,没有的话就直接new一个新的消息
到此消息创建就完成了
三,处理消息
继续看源码
这里写图片描述
我们可以看到MessageQuene.enqueueMessage(msg, uptimeMillis)将消息放入消息对列中
这里写图片描述
我们可以看到如果有消息的话会通过handmessage(Message msg)来进行自己的业务逻辑
没有消息:死循环监听消息,looper线程会堵塞。知道有消息
Looper—— 我们知道一个线程是一段可执行的代码,当可执行代码执行完成后,线程生命周期便会终止,线程就会退出,那么做为App的主线程,如果代码段执行完了会怎样?,那么就会出现App启动后执行一段代码后就自动退出了,这是很不合理的。所以为了防止代码段被执行完,只能在代码中插入一个死循环,那么代码就不会被执行完,然后自动退出,怎么在在代码中插入一个死循环呢?那么Looper出现了,在主线程中调用Looper.prepare()…Looper.loop()就会变当前线程变成Looper线程(可以先简单理解:无限循环不退出的线程),Looper.loop()方法里面有一段死循环的代码,所以主线程会进入while(true){…}的代码段跳不出来,但是主线程也不能什么都不做吧?其实所有做的事情都在while(true){…}里面做了,主线程会在死循环中不断等其他线程给它发消息(消息包括:Activity启动,生命周期,更新UI,控件事件等),一有消息就根据消息做相应的处理,Looper的另外一部分工作就是在循环代码中会不断从消息队列挨个拿出消息给主线程处理。
MessageQueue—— 存在的原因很简单,就是同一线程在同一时间只能处理一个消息,同一线程代码执行是不具有并发性,所以需要队列来保存消息和安排每个消息的处理顺序。多个其他线程往UI线程发送消息,UI线程必须把这些消息保持到一个列表(它同一时间不能处理那么多任务),然后挨个拿出来处理,这种设计很简单,我们平时写代码其实也经常这么做。每一个Looper线程都会维护这样一个队列,而且仅此一个,这个队列的消息只能由该线程处理。
Handler—— 简单说Handler用于同一个进程的线程间通信。Looper让主线程无限循环地从自己的MessageQueue拿出消息处理,既然这样我们就知道处理消息肯定是在主线程中处理的,那么怎样在其他的线程往主线程的队列里放入消息呢?其实很简单,我们知道在同一进程中线程和线程之间资源是共享的,也就是对于任何变量在任何线程都是可以访问和修改的,只要考虑并发性做好同步就行了,那么只要拿到MessageQueue 的实例,就可以往主线程的MessageQueue放入消息,主线程在轮询的时候就会在主线程处理这个消息。那么怎么拿到主线程 MessageQueue的实例,是可以拿到的(在主线程下mLooper = Looper.myLooper();mQueue = mLooper.mQueue;),但是Google 为了统一添加消息和消息的回调处理,又专门构建了Handler类,你只要在主线程构建Handler类,那么这个Handler实例就获取主线程MessageQueue实例的引用(获取方式mLooper = Looper.myLooper();mQueue = mLooper.mQueue;),Handler 在sendMessage的时候就通过这个引用往消息队列里插入新消息。Handler 的另外一个作用,就是能统一处理消息的回调。这样一个Handler发出消息又确保消息处理也是自己来做,这样的设计非常的赞。具体做法就是在队列里面的Message持有Handler的引用(哪个handler 把它放到队列里,message就持有了这个handler的引用),然后等到主线程轮询到这个message的时候,就来回调我们经常重写的Handler的handleMessage(Message msg)方法。
Message——很简单了,你想让主线程做什么事,总要告诉它吧,总要传递点数据给它吧,Message就是这个载体。

作者:Kelin
链接:https://www.zhihu.com/question/19703357/answer/119024815
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

感谢: handler机制的原理:http://blog.csdn.net/itachi85/article/details/8035333

发布了3 篇原创文章 · 获赞 0 · 访问量 532
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览