系列目录: Handler机制原理
Handler使用介绍
- 可实例化并通过它来发送消息
- 重构里面的handleMessage()可实现接口回调
主要代码分析
1.send发送消息--sendMessage()
public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, 0);
}
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
上面的代码大体就是普通消息
转化为延时消息
,然后延时消息
转化为定时消息
,然后把定时消息
存入MessageQueue
。
当然里面有七种send发送消息的方法,基本上都能归到这三种消息上。只要一种比较特殊
sendMessageAtFrontOfQueue()
,发送到表头上,最先取出并执行的消息。
2. post发送消息--post()
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
public final boolean postDelayed(Runnable r, long delayMillis)
{
return sendMessageDelayed(getPostMessage(r), delayMillis);
}
public final boolean postAtTime(Runnable r, long uptimeMillis)
{
return sendMessageAtTime(getPostMessage(r), uptimeMillis);
}
- 从上面的代码可以看出post最终也都调用到上述
send()
那三个基本方法上了。- post(Runnable r),对于Runnable到底是怎么执行的,是开了单独的线程还是别的什么方法我们下面单独分析
3. 消息分发 --dispatchMessage()
Looper中我们已经分析到取出新的消息后会调用dispatchMessage()方法来分发消息。
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
//当Message存在回调方法,回调msg.callback.run()方法;
handleCallback(msg);
} else {
if (mCallback != null) {
//当Handler存在Callback成员变量时,回调方法handleMessage();
if (mCallback.handleMessage(msg)) {
return;
}
}
//Handler自身的回调方法handleMessage()
handleMessage(msg);
}
}
这个方法很简单就是二个条件,三种情况
情况1:如果msg.callback 不为空,则执行handleCallback(Message),而handleCallback(Message)的内部最终调用的是message.callback.run();,所以最终是msg.callback.run()。
情况2:如果msg.callback 为空,且mCallback不为空,则执行mCallback.handleMessage(msg)。
情况3:如果msg.callback 为空,且mCallback也为空,则执行handleMessage()方法
分发消息时三个方法的优先级分别如下:
- Message的回调方法优先级最高,即message.callback.run();
- Handler的回调方法优先级次之,即Handler.mCallback.handleMessage(msg);
- Handler的默认方法优先级最低,即Handler.handleMessage(msg)。
4. Post(Runnable)怎么执行
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
上面方法里调用了
getPostMessage ()
方法来生成Message,我们看一下此方法源码
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
上面方法生成了一个Message,并将Runnable赋给成员变量
callback
。
继续看一下消息分发的操作
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
通过消息分发的解析我们可以知道这里会执行
handleCallback()
方法。
private static void handleCallback(Message message) {
message.callback.run();
}
可以看到这里最终调用了
Runnable#run()
方法,所以没有开启新的线程,只是在源线程上执行的。
网友评论