Handler , MessageQueue,Looper关系:
Message 里有一个Handler属性
Looper 里有一个MessageQueue属性
Handler 里有一个MessageQueue(就是Looper里的), Looper
创建的Handler的时候,会给Looper属性赋值,这个是从当前线程中拿出来的。ui线程里自带一个,其他线程里只能手动的
Looper.prepare() 和 Looper.loop()
Looper.prepare() 里看当前线程有没有绑定Looper,没有的话创建一个
创建Looper时候,会给MessageQueue赋值。一个 Looper 对应一个MessageQueue
一个Handler把 Message 加到MessageQueue中,Looper负责从MessageQueue里取Message,然后分发给Handler
----------------------------------------Handler发送消息到消息队列-----------------------------------------------
Handler.sendMessage();内部还是调用的sendMessageDelayed() ,只不过延时时间设为0
调用顺序是:sendMessage-->sendMessageDelayed()-->sendMessageAtTime()-->enqueueMessage()(仅仅给Message设一个target)-->queue.enqueueMessage()
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); }
可以看到最后一行, enqueueMessage()
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { msg.target = this; if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }
这个方法主要就是把Message的target设为this,将来循环从MessageQueue取Message,可以根据target,执行相应的handleMessage()。
看最后一行,Handler的enqueueMessage又调用了queue.enqueueMessage();
首先先看,enqueueMessage的方法签名: boolean enqueueMessage(Message msg, long when) 。
参数 when,就是Message被分发给handler的时间
例如:当我们调用的是handler.sendMessageDelayed(1000); 此时的when=SystemClock.uptimeMillis() + 1000
-------------------------------------Looper从MessageQueue取出Message------------------
再看handler.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 是不是为空。这个callback到底是什么呢?
handler.send(Runnable runnable).
这个方法允许传一个Runnable的对象进去,在里面调用了下面的方法,把Runnable对象包装成了Message。
private static Message getPostMessage(Runnable r) { Message m = Message.obtain(); m.callback = r; return m; }
这时Message.callback = r;
这时再看dispatchMessage里如果callback不为空, 则调用 handleCallback(msg);执行
private static void handleCallback(Message message) { message.callback.run(); }
-----------------------------------------Looper 退出------------------------------------------
Looper.quit()
public void quit() { mQueue.quit(false); }
当调用了这个方法后,再调用handler.sendMessage(Message)添加Message到MessageQueue ,就会返回false;
这个方法是不安全的,因为在Looper终止之前,可能还有一些Message没有被交付完。全部被取消了
所以推荐使用Looprt.quitSafely(),注意这要api 18 以上才可以使用
public void quitSafely() { mQueue.quit(true); }
可以看到这两个方法都是调用mQueue.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); } }
其中,当正在退出时返回,否则将mQuitting标识为true
并且根据传进来的true或者false来决定时哪种退出的策略
removeAllFutureMessagesLocked(); ///这种是先看队首,如果执行时间没到,那说明后续的都没有到。则直接调用 removeAllMessagesLocked();否则,从队首一个一个往后找,直接找到第一个时间没到的Message m,从他开始一直到最后直接删除。那么m之前的是还能分发出去的。
removeAllMessagesLocked(); ///这种是直接删除MessageQueue上所有的Message