Handler
handler是和线程MessageQueue队列关联发送和处理Message和Runnable的对象。
1.发送Runnable方法如下:
- post(Runnable)
- postAtTime(Runnable, long)
- postDelayed(Runnable, long)
2.发送Message方法如下:
- sendEmptyMessage(int)
- sendMessage(Message)
- sendMessageAtTime(Message, long)
- sendMessageDelayed(Message, long)
要注意的是handler发送Runnable对象方法实际上是调用SendMessage方法。
直接查看源码,Runnable作为入参到getPostMessage转换成Message对象,Runnable赋值给Message的callback,callback何用等会再讲。
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
3.dispatchMessage
Handler的handleMessage是通过dispatchMessage调用的,所以先讲它。handler接收Message一共通过三种方式。
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
- 若msg的callBack不为空,调用Message的Runnable的run方法<span id = "Message_Runnable"></span>
private static void handleCallback(Message message) {
message.callback.run();
}
- 若Handler的mCallback接口回调不为空
public interface Callback {
public boolean handleMessage(Message msg);
}
- 最后调用handleMessage
/**
* Subclasses must implement this to receive messages.
*/
public void handleMessage(Message msg) {
}
4.接收Message
- handleMessage(Message)
所以没有接收Runnable方法,也就知道为什么要把发送的Runnable转成Message了。
5.注意!!
在子线程中创建Handler必需它的mLooper不能为空。这点应该都比较清楚,Handler的构造函数中对mLooper是否为空做了判断,若为空则抛出一个异常。所以在子线程中创建Handler之前先调用Looper.prepare()创建Looper以及实例化Looper的MessageQueue和Thread。
Looper
Looper是用于在Thread中运行消息队列的类。Thread默认不关联Looper。
1.prepare
在线程中调用prepare方法运行loop。
sThreadLocal.get()获取Looper,若为空则去new 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));
}
2.loop
让Looper进入循环处理MessageQueue中的Meessage。loop方法很长里面主要有for(;;)做线程阻塞不断从queue中拿Message分发给Hanlder去处理。具体在msg.target.dispatchMessage(msg)。msg.target对象就Hanlder。看这
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
...省略部分代码
final long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs;
final long traceTag = me.mTraceTag;
if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {
Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
}
final long start = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
final long end;
try {
msg.target.dispatchMessage(msg);
end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
...省略部分代码
msg.recycleUnchecked();
}
3.quit
Looper调用loop方法进入死循环,那如何让Looper停止轮询MessageQueue呢。Looper提供quit和quitSafely两个方法退出Looper。
- quit
quit是非安全的,因为在Looer结束之前可能会存在一些Message还存在MessageQueue中不能被分发。*
Using this method may be unsafe because some messages may not be delivered before the looper terminates. Consider using {@link #quitSafely} instead to ensure that all pending work is completed in an orderly manner.
- quitSafely
quit不安全,所以我们使用quitSafely。保证MessageQueue中的Message被及时分发出去。然而延时的Message则不能在quit后分发出去。
Looper的退出都是调用了MessageQueue的quit。
public void quit() {
mQueue.quit(false);
}
public void quitSafely() {
mQueue.quit(true);
}
MessageQueue
现在要讲的是MessageQueue。开始之前先把Looper调用quit先讲了。MessageQueue的quit只要说safe控制的removeAllFutureMessagesLocked和removeAllMessagesLocked。
1.quit
void quit(boolean safe) {
if (!mQuitAllowed) {
throw new IllegalStateException("Main thread not allowed to quit.");
}
synchronized (this) {
if (mQuitting) {
return;
}
mQuitting = true;
if (safe) {
removeAllFutureMessagesLocked();
} else {
removeAllMessagesLocked();
}
// We can assume mPtr != 0 because mQuitting was previously false.
nativeWake(mPtr);
}
}
- 当Looper调用quit非安全退出执行removeAllMessagesLocked,循环MessageQueue将退出前队列中Message全部清空。
private void removeAllMessagesLocked() {
Message p = mMessages;
while (p != null) {
Message n = p.next;
p.recycleUnchecked();
p = n;
}
mMessages = null;
}
- 当Looper调用quitSafely执行removeAllFutureMessagesLocked,获取当前mMessages的when和SystemClock.uptimeMillis()获取的boot开始到现在的毫秒时间做比较。若Message的时间超过quit的时间则执行非安全退出的quit下的removeAllMessagesLocked。否则将进入循环将MessageQueue要执行的Message分发出去直到MessageQueue清空或者超时(when > now)。
Ps: 所以handler发送Message或者Runnable的延时时间在这里起了作用,根据传入的延时时间做列表排序。
private void removeAllFutureMessagesLocked() {
final long now = SystemClock.uptimeMillis();
Message p = mMessages;
if (p != null) {
if (p.when > now) {
removeAllMessagesLocked();
} else {
Message n;
for (;;) {
n = p.next;
if (n == null) {
return;
}
if (n.when > now) {
break;
}
p = n;
}
p.next = null;
do {
p = n;
n = p.next;
p.recycleUnchecked();
} while (n != null);
}
}
}
2.enqueueMessage
前面Handler讲过发送Message,最终都会去执行queue的enqueueMessage方法。
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
MessageQueue排列Message并不是以数组形式,MessageQueue只持有当前的mMessages。新加入到队列的Message会根据它的when判断它在队列的位置。还可以看到若Thread已经dead,则抛出非法异常并把发送的Message回收。
boolean enqueueMessage(Message msg, long when) {
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
if (msg.isInUse()) {
throw new IllegalStateException(msg + " This message is already in use.");
}
synchronized (this) {
if (mQuitting) {
IllegalStateException e = new IllegalStateException(
msg.target + " sending message to a Handler on a dead thread");
Log.w(TAG, e.getMessage(), e);
msg.recycle();
return false;
}
msg.markInUse();
msg.when = when;
Message p = mMessages;
boolean needWake;
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
// Inserted within the middle of the queue. Usually we don't have to wake
// up the event queue unless there is a barrier at the head of the queue
// and the message is the earliest asynchronous message in the queue.
needWake = mBlocked && p.target == null && msg.isAsynchronous();
Message prev;
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
// We can assume mPtr != 0 because mQuitting is false.
if (needWake) {
nativeWake(mPtr);
}
}
return true;
}
Message
<span id = "Message"></span>
最后就是Message了。Message主要成员参数有:long when、Bundle data、Handler target、Runnable callback、Message next。可以看到Message没有前驱只有一个后继Message。所以MessageQueue只存当前mMessages也能找到下一个Message。
1.Runnable
Message有成员参数Runnable。还记得Handler的Post的是Runnable然后转换成Message吗,原来入参的Runnable到这里来了。看这里若Message的Runnable不为空,Handler的dispathMessage可是会走这边的。相当于Handler是Post方法,最后接收的时候是执行Runnable的run方法。
最后
其实讲这么多就是为了摸清楚Handler、Looper、MessageQueue以及Message。整个过程下来理清了Handler作为Message的接收和发送者,将Message插入MessageQueue中。Looper则是作为一个搬运者不停地从MessageQueue中拿取Mssage然后丢给Handler。那么Handler作为Message接收和发送者为何多此一举通过又是Queue又是Looper绕一圈呢?其实其中也有Thread的参与。由于主题主要是Handler机制,所以Thread放在下次有时间单独讲。Handler就是解决进程间通信问题以及异步处理事件,创建子线程做异步操作,把希望返回的内容返回到主线程达到不阻塞UI线程的目的。
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
拿了一张比较好理解的Handler机制运行的图片来做结束。图片来源已经在本文最后附上链接
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。