Handler机制的源码分析
2019独角兽企业重金招聘Python工程师标准>>>
Handler,MessageQueue,Looper的关系
Looper的作用是在线程中处理消息的
MessageQueue用来存储消息的队列
Handler使用来定义具体处理消息的方式,以及发送消息;Android主线程中持有一个可以更新UI的Handler;对其他的线程,如果需要处理消息,可以自己new一个Handler在线程的 run 方法中。
ThreadLocal:MessageQueue对象,和Looper对象在每个线程中都只会有一个对象,怎么能保证它只有一个对象,就通过ThreadLocal来保存。Thread Local是一个线程内部的数据存储类,通过它可以在指定线程中存储数据,数据存储以后,只有在指定线程中可以获取到存储到数据,对于其他线程来说则无法获取到数据。
一.Looper
源码分析: Looper.prepare()方法;创建一个Looper的实例,但是该实例在一个线程中只能有一个;保存在ThreadLocal中,如果发现已经存在了Looper对象,会抛出一个异常。
public static void prepare() {prepare(true);}private static void prepare(boolean quitAllowed) {if (sThreadLocal.get() != null) {throw new RuntimeException("Only one Looper may be created per thread");}sThreadLocal.set(new Looper(quitAllowed));}
Looper.loop()方法;loop()方法中有一个无限的循环。for(;;)那一段;线程执行到loop()方法之后会一直留在loop()方法中,直到被打断终止 (源码可以看出,发送空消息就可以打断该循环,终止该线程)
public static void loop() {final Looper me = myLooper();if (me == null) {throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");}final MessageQueue queue = me.mQueue;// Make sure the identity of this thread is that of the local process,// and keep track of what that identity token actually is.Binder.clearCallingIdentity();final long ident = Binder.clearCallingIdentity();//死循环for (;;) {Message msg = queue.next(); // might blockif (msg == null) {// No message indicates that the message queue is quitting.return;}// This must be in a local variable, in case a UI event sets the loggerfinal Printer logging = me.mLogging;if (logging != null) {logging.println(">>>>> Dispatching to " + msg.target + " " +msg.callback + ": " + msg.what);}final long traceTag = me.mTraceTag;if (traceTag != 0) {Trace.traceBegin(traceTag, msg.target.getTraceName(msg));}try {msg.target.dispatchMessage(msg);} finally {if (traceTag != 0) {Trace.traceEnd(traceTag);}}if (logging != null) {logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);}// Make sure that during the course of dispatching the// identity of the thread wasn't corrupted.final long newIdent = Binder.clearCallingIdentity();if (ident != newIdent) {Log.wtf(TAG, "Thread identity changed from 0x"+ Long.toHexString(ident) + " to 0x"+ Long.toHexString(newIdent) + " while dispatching to "+ msg.target.getClass().getName() + " "+ msg.callback + " what=" + msg.what);}msg.recycleUnchecked();}}
二.Handler
重要的构造方法:
- 传入某个线程thread的Looper对象;这样这个Handler就是该thread的Handler了(和在该thread的run方法中直接new一个没有参数的Handler的效果是一样的;但是在外部定义可以使我们更好使用)
/*** Use the provided {@link Looper} instead of the default one.** @param looper The looper, must not be null.*/public Handler(Looper looper) {this(looper, null, false);}/*** Default constructor associates this handler with the {@link Looper} for the* current thread.** If this thread does not have a looper, this handler won't be able to receive messages* so an exception is thrown.*/public Handler() {this(null, false);}
三.MessageQueue
MessagerQueue是一个单向链表
HandlerThread
HandlerThread是Android系统自己实现的一个可以实现 处理异步消息 的线程。简单来说就是和UI线程是一样的原理,通过Looper和Message通信,让该线程为我们服务。
具体可以看源码就能知道他的原理(我们自己也可以写这样的线程,但是系统给我们的总是要好一点的)
@Overridepublic void run() {mTid = Process.myTid();Looper.prepare();synchronized (this) {mLooper = Looper.myLooper();notifyAll();}Process.setThreadPriority(mPriority);onLooperPrepared();Looper.loop();mTid = -1;}
HandlerThread的使用
HandlerThread workThread = new HandlerThread();
workThread.start();
Handler handler = new Handler(workThread.getLooper());
转载于:https://my.oschina.net/u/3246345/blog/1552973
Handler机制的源码分析相关推荐
- 以太坊POA共识机制Clique源码分析
以太坊中除了基于运算能力的POW(Ethash)外,还有基于权利证明的POA共识机制,Clique是以太坊的POA共识算法的实现,这里主要对POA的Clique相关源码做一个解读分析. Clique的 ...
- android 开发零起步学习笔记(二十二):ANDROID应用ACTIVITY、DIALOG、POPWINDOW、TOAST窗口添加机制及源码分析(一)
原文:http://www.cnblogs.com/shanzei/p/4654817.html 第一部分: ANDROID应用ACTIVITY.DIALOG.POPWINDOW.TOAST窗口添加机 ...
- Android应用Activity、Dialog、PopWindow、Toast窗口添加机制及源码分析
1 背景 之所以写这一篇博客的原因是因为之前有写过一篇<Android应用setContentView与LayoutInflater加载解析机制源码分析>, 然后有人在文章下面评论和微博 ...
- (转) Android应用Activity、Dialog、PopWindow、Toast窗口添加机制及源码分析
转载[工匠若水 http://blog.csdn.net/yanbober ] 1 背景 之所以写这一篇博客的原因是因为之前有写过一篇<Android应用setContentView与Layou ...
- View事件分发机制(源码分析篇)
01.Android中事件分发顺序 1.1 事件分发的对象是谁 事件分发的对象是事件.注意,事件分发是向下传递的,也就是父到子的顺序. 当用户触摸屏幕时(View或ViewGroup派生的控件),将产 ...
- Apache Storm 实时流处理系统ACK机制以及源码分析
1.ACK机制简介 Storm的可靠性是指Storm会告知用户每一个消息单元是否在一个指定的时间(timeout)内被完全处理.完全处理的意思是该MessageId绑定的源Tuple以及由该源Tupl ...
- 以太坊POA共识机制Clique源码分析 1
转载自Ryan是菜鸟 | LNMP技术栈笔记 以太坊中除了基于运算能力的POW(Ethash)外,还有基于权利证明的POA共识机制,Clique是以太坊的POA共识算法的实现,这里主要对POA的Cli ...
- android的消息处理机制(图文+源码分析)—Looper/Handler/Message[转]
from:http://www.jb51.net/article/33514.htm 作为一个大三的预备程序员,我学习android的一大乐趣是可以通过源码学习google大牛们的设计思想.andro ...
- Android Binder机制情景源码分析之Binder回调注册和反注册
我们在日常开发中,经常用到Binder来进行跨进程通信,有个比较常见的场景是向服务端注册Binder回调,比如: IActivityManager中有两个成对的方法,Client端向AMS所在的服务端 ...
最新文章
- LTE MAC PDU
- 计算机的诊断策略服务怎么打开,win7系统使用诊断策略服务提示“未运行”怎么解决...
- php 小数点 乘法,js小数点数字相乘、把小数点四舍五入保留两位小数
- Mysql-索引的基础和类型
- 《参考消息》出现大标题错别字硬伤
- 10个Python进行数据分析的小技巧
- JS的内建函数reduce
- Win10 重装系统备忘
- 全球及中国电子材料市场需求分析与十四五投资潜力预测报告2021年版
- 零跑汽车上半年表现亮眼,全域自研能力加持下业绩高速增长
- unity图片导入尺寸改变了修改方法
- java 同比数据怎么算的_如何计算同比的计算公式?
- crm系统是什么很棒ec实力_哪个CRM系统好
- [Scala基础]--Either介绍
- 【Unity】实现立体的UI
- 深度学习模型的Android部署方法
- @requestParam与@Param区别
- 研究生计算机论文怎么写,研究生计算机论文摘要怎么写 研究生计算机论文摘要范文参考...
- 字节跳动暑期实习生一面面经 大三
- 快速上手@Aspect+@Pointcut