一、概述
Handler是Android系统一个重要的框架,主要用于异步更新UI,首先看下Handler的流程图
文字解读一下流程图:
1、Looper中存放着MessageQueen,MessageQueen存放着很多Message,Handler发送messages前会获取Looper;
2、Handler通过post(Runnable r)或者sendMessage(Message msg)将封装的message发送到对应Looper的MessageQueen中;
3、在Looper.loop的带动下,MessageQueen不断的获取Message并通过dispatchMessage发送给Handler;
4、Handler通过HandlerMessage来处理接受到的messages
涉及到的文件类知识点
- Handler(处理者)
- 定义:Message的主要处理者
- 作用:负责发送Message到消息队列&处理Looper分派过来的Message
- Looper(循环器)
- 定义:扮演Message Queue和Handler之间桥梁的角色
- 作用:
消息循环:循环取出Message Queue的Message
消息派发:将取出的Message交付给相应的Handler
- Message Queue(消息队列)
- 定义:采用单链表的数据结构来存储消息列表
- 作用:用来存放通过Handler发过来的Message,按照先进先出执行
- Message(消息)
- 定义:Handler接收和处理的消息对象(Bean对象)
- 作用:通信时相关信息的存放和传递
- ThreadLocal
- 定义:线程内部的数据存储类
- 作用:负责存储和获取本线程的Looper
二、通信流程及问题解析
源码解析不做介绍了,搜索一大堆,从几个问题介绍一下流程
1、post(Runnable r)和sendMessage(Message msg)的区别?
2、一个Activity有多个handler怎么接受messages,就是怎样知道handler1发送的消息不会被handler2接收,同理handler2发送的消息不会被handler1接收
3、Android中为什么主线程不会因为Looper.loop()里的死循环卡死?https://www.zhihu.com/question/34652589
解答学习的过程:
1、post(Runnable r)和sendMessage(Message msg)的区别?
sendMessage方法,
/**
* Pushes a message onto the end of the message queue after all pending messages
* before the current time. It will be received in {@link #handleMessage},
* in the thread attached to this handler.
*
* @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, 0);
}
然后封装成一个Message,发送到MessageQueen中,获得msg.target = this;
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
post方法传入的是Runnable,做的也是封装Message,
/**
* Causes the Runnable r to be added to the message queue.
* The runnable will be run on the thread to which this handler is
* attached.
*
* @param r The Runnable that will be executed.
*
* @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
区别在于getPostMessage(r)方法,m.callback = r;区别于sendMessage的msg.target = this;
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
接下来就看看dispatchMessage方法,
/**
* Handle system messages here.
*/
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
- msg的callback不为空,调用handleCallback方法(message.callback.run())
- mCallback不为空,调用mCallback.handleMessage(msg)
- 最后如果其他都为空,执行Handler自身的 handleMessage(msg) 方法
这样就解释了为啥post传入一个Runnable还可以在主线程中更新UI
2、一个Activity有多个handler怎么接受messages,就是怎样知道handler1发送的消息不会被handler2接收,同理handler2发送的消息不会被handler1接收
在上一题可以看到handler在enqueueMessage方法中,发送到MessageQueen中的messages有打上一个标记msg.target = this;
在分发messages时,Looper.loop中,有这样一行代码msg.target.dispatchMessage(msg);这样就拿到了对应标记的message分发给handler处理
3、Android中为什么主线程不会因为Looper.loop()里的死循环卡死?
这个参照一下Gityuan大神的解答,Android中为什么主线程不会因为Looper.loop()里的死循环卡死?