Handler是Android 线程间通讯工具类。ide
通常用于子线程向主线程发送消息,将子线程中执行结果通知主线程,从而在主线程中执行UI更新操做。工具
Handler负责发送(sendMessage)和处理消息(handleMessage)oop
1)Message:消息载体,包含消息id(what)、消息处理对象(obj)、Runnable接口等。Handler发送一条消息后,会将该消息加入到MessageQueue统一消息处理队列中。学习
2)MessageQueue:消息队列。用来存放Handler发送的消息的队列,单链表实现ui
3)Looper:消息泵,经过Looper.loop( )建立一个死循环,不断地从MessageQueue中抽取Message,Message经过绑定的内部target(handler类型),msg.target.dispatchMessage(msg)将该消息传给对应的Handler接收。在dispatchMessage方法内调用handleCallback或handleMessage方法spa
建立Handler对象时,须要先为这个Handler建立Looper.prepara( )新建一个looper对象。一个线程中只会有一个looper。由于looper使用ThreadLocal.set方法。在set方法中,会对应着当前Thread,将Looper存储在其成员变量ThreadLocalMap中。其中key是ThreadLocal,value是looper。所以looper-threadLocal-Thread是一一对应关系。线程
实际上ThreadLocal的值是放入了当前线程的一个ThreadLocalMap实例中,因此只能在本线程中访问,其余线程没法访问。code
在Java中,栈内存归属于单个线程,每一个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即栈内存能够理解成线程的私有内存。而堆内存中的对象对全部线程可见。堆内存中的对象能够被全部线程访问。对象
###Handler发送和处理消息过程分析接口
Handler发送消息:Handler.sendMessage(Message message)
Handler处理信息:
new Handler(){ // 经过复写handlerMessage()从而肯定更新UI的操做 @Override public void handleMessage(Message msg) { ...// 需执行的UI操做 } };
sendMessage方法将message 入队messageQueue(单链表实现)在ActivityThread中会调用Looper.prepareMainLooper()生成looper,looper中会建立MessageQueue 。Looper.loop( )中有个死循环,不断从messageQueue中取message。
public static void main(String[] args) { Looper.prepareMainLooper(); long startSeq = 0; if (args != null) { for (int i = args.length - 1; i >= 0; --i) { if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) { startSeq = Long.parseLong( args[i].substring(PROC_START_SEQ_IDENT.length())); } } } ActivityThread thread = new ActivityThread(); thread.attach(false, startSeq); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
Looper类
private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); }
public static void loop() { ...// 仅贴出关键代码 // 1. 获取当前Looper的消息队列 final Looper me = myLooper(); final MessageQueue queue = me.mQueue; for (;;) { Message msg = queue.next(); if (msg == null) { return; } // next():取出消息队列里的消息 // 若取出的消息为空,则线程阻塞 // 2.2 派发消息到对应的Handler msg.target.dispatchMessage(msg); // 把消息Message派发给消息对象msg的target属性 // target属性实际是1个handler对象 // 3. 释放消息占据的资源 msg.recycle(); } }
Handler中的dispatchMessage方法
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
今年金九银十我花一个月的时间收录整理了一套知识体系,若是有想法深刻的系统化的去学习的,能够点击传送门,我会把我收录整理的资料都送给你们,帮助你们更快的进阶。