handler是和线程MessageQueue队列关联发送和处理Message和Runnable的对象。html
1.发送Runnable方法以下:android
2.发送Message方法以下:数组
要注意的是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.dispatchMessageless
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); } }
private static void handleCallback(Message message) { message.callback.run(); }
public interface Callback { public boolean handleMessage(Message msg); }
/** * Subclasses must implement this to receive messages. */ public void handleMessage(Message msg) { }
4.接收Messageasync
因此没有接收Runnable方法,也就知道为何要把发送的Runnable转成Message了。ide
5.注意!!函数
在子线程中建立Handler必需它的mLooper不能为空。这点应该都比较清楚,Handler的构造函数中对mLooper是否为空作了判断,若为空则抛出一个异常。因此在子线程中建立Handler以前先调用Looper.prepare()建立Looper以及实例化Looper的MessageQueue和Thread。oop
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是非安全的,由于在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.
quit不安全,因此咱们使用quitSafely。保证MessageQueue中的Message被及时分发出去。然而延时的Message则不能在quit后分发出去。
Looper的退出都是调用了MessageQueue的quit。
public void quit() { mQueue.quit(false); } public void quitSafely() { mQueue.quit(true); }
如今要讲的是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); } }
private void removeAllMessagesLocked() { Message p = mMessages; while (p != null) { Message n = p.next; p.recycleUnchecked(); p = n; } mMessages = null; }
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; }
<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机制运行的图片来作结束。图片来源已经在本文最后附上连接