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机制的源码分析相关推荐

  1. 以太坊POA共识机制Clique源码分析

    以太坊中除了基于运算能力的POW(Ethash)外,还有基于权利证明的POA共识机制,Clique是以太坊的POA共识算法的实现,这里主要对POA的Clique相关源码做一个解读分析. Clique的 ...

  2. android 开发零起步学习笔记(二十二):ANDROID应用ACTIVITY、DIALOG、POPWINDOW、TOAST窗口添加机制及源码分析(一)

    原文:http://www.cnblogs.com/shanzei/p/4654817.html 第一部分: ANDROID应用ACTIVITY.DIALOG.POPWINDOW.TOAST窗口添加机 ...

  3. Android应用Activity、Dialog、PopWindow、Toast窗口添加机制及源码分析

    1  背景 之所以写这一篇博客的原因是因为之前有写过一篇<Android应用setContentView与LayoutInflater加载解析机制源码分析>, 然后有人在文章下面评论和微博 ...

  4. (转) Android应用Activity、Dialog、PopWindow、Toast窗口添加机制及源码分析

    转载[工匠若水 http://blog.csdn.net/yanbober ] 1 背景 之所以写这一篇博客的原因是因为之前有写过一篇<Android应用setContentView与Layou ...

  5. View事件分发机制(源码分析篇)

    01.Android中事件分发顺序 1.1 事件分发的对象是谁 事件分发的对象是事件.注意,事件分发是向下传递的,也就是父到子的顺序. 当用户触摸屏幕时(View或ViewGroup派生的控件),将产 ...

  6. Apache Storm 实时流处理系统ACK机制以及源码分析

    1.ACK机制简介 Storm的可靠性是指Storm会告知用户每一个消息单元是否在一个指定的时间(timeout)内被完全处理.完全处理的意思是该MessageId绑定的源Tuple以及由该源Tupl ...

  7. 以太坊POA共识机制Clique源码分析 1

    转载自Ryan是菜鸟 | LNMP技术栈笔记 以太坊中除了基于运算能力的POW(Ethash)外,还有基于权利证明的POA共识机制,Clique是以太坊的POA共识算法的实现,这里主要对POA的Cli ...

  8. android的消息处理机制(图文+源码分析)—Looper/Handler/Message[转]

    from:http://www.jb51.net/article/33514.htm 作为一个大三的预备程序员,我学习android的一大乐趣是可以通过源码学习google大牛们的设计思想.andro ...

  9. Android Binder机制情景源码分析之Binder回调注册和反注册

    我们在日常开发中,经常用到Binder来进行跨进程通信,有个比较常见的场景是向服务端注册Binder回调,比如: IActivityManager中有两个成对的方法,Client端向AMS所在的服务端 ...

最新文章

  1. LTE MAC PDU
  2. 计算机的诊断策略服务怎么打开,win7系统使用诊断策略服务提示“未运行”怎么解决...
  3. php 小数点 乘法,js小数点数字相乘、把小数点四舍五入保留两位小数
  4. Mysql-索引的基础和类型
  5. 《参考消息》出现大标题错别字硬伤
  6. 10个Python进行数据分析的小技巧
  7. JS的内建函数reduce
  8. Win10 重装系统备忘
  9. 全球及中国电子材料市场需求分析与十四五投资潜力预测报告2021年版
  10. 零跑汽车上半年表现亮眼,全域自研能力加持下业绩高速增长
  11. unity图片导入尺寸改变了修改方法
  12. java 同比数据怎么算的_如何计算同比的计算公式?
  13. crm系统是什么很棒ec实力_哪个CRM系统好
  14. [Scala基础]--Either介绍
  15. 【Unity】实现立体的UI
  16. 深度学习模型的Android部署方法
  17. @requestParam与@Param区别
  18. 研究生计算机论文怎么写,研究生计算机论文摘要怎么写 研究生计算机论文摘要范文参考...
  19. 字节跳动暑期实习生一面面经 大三
  20. 快速上手@Aspect+@Pointcut

热门文章

  1. 国内IT出版社的四大软肋
  2. 区块链将重新定义世界
  3. 阿里开源分布式事务解决方案 Fescar 全解析
  4. Fiddler可以支持Websocket抓包了
  5. [译] 新一代 JavaScript 的开发图谱(2017)
  6. Error:(23, 25) 错误: 程序包R不存在
  7. VisualSVN Server2.5服务器迁移
  8. 【看完请推荐】记国庆前的一次码农受骗记
  9. oracle惯用缩写的含义
  10. 如何有效地提升 JavaScript 水平?