韩梦飞沙 yue31313 韩亚飞 han_meng_fei_sha 313134555@qq.com
消息队列排序
一般的像我们普通调用Handler发送消息,最后都会调用MessageQueue的enqueueMessage。
- 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);
- }
像sendMessageAtFrontOfQueue这样只是最后的时间设置为0,自然就排在队列的前面了。
- public final boolean sendMessageAtFrontOfQueue(Message msg) {
- 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, 0);
- }
- private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
- msg.target = this;//一般讲target设置为Handler
- if (mAsynchronous) {
- msg.setAsynchronous(true);
- }
- return queue.enqueueMessage(msg, uptimeMillis);
- }
最后就到MessageQueue的enqueueMessage函数中去了,该函数就是根据when把这个msg插入到合适的消息队列中。
- boolean enqueueMessage(Message msg, long when) {
- ......
- synchronized (this) {
- ......
- msg.markInUse();
- msg.when = when;
- Message p = mMessages;//当前message
- 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) { //找到一个Message,when小于该message的when break
- break;
- }
- if (needWake && p.isAsynchronous()) {
- needWake = false;
- }
- }
- msg.next = p; // invariant: p == prev.next
- prev.next = msg;//这其实就是把该message插入合适的位置
- }
- // We can assume mPtr != 0 because mQuitting is false.
- if (needWake) {
- nativeWake(mPtr);
- }
- }
- return true;
- }
最后我们再看下MessageQueue的next函数,就是消息线程循环时会不断调用MessageQueue的next来获取当前消息。
-
- Message next() {
- final long ptr = mPtr;
- if (ptr == 0) {
- return null;
- }
- int pendingIdleHandlerCount = -1; // -1 only during first iteration
- int nextPollTimeoutMillis = 0;
- for (;;) {
- if (nextPollTimeoutMillis != 0) {
- Binder.flushPendingCommands();
- }
- nativePollOnce(ptr, nextPollTimeoutMillis);//c层的epoll函数会阻塞
- synchronized (this) {
- // Try to retrieve the next message. Return if found.
- final long now = SystemClock.uptimeMillis();
- Message prevMsg = null;
- Message msg = mMessages;// 当前msg
- if (msg != null && msg.target == null) { //这里就是和异步消息有关,下节分析
- // Stalled by a barrier. Find the next asynchronous message in the queue.
- do {
- prevMsg = msg;
- msg = msg.next;
- } while (msg != null && !msg.isAsynchronous());
- }
- if (msg != null) {
- if (now < msg.when) { //当前消息还没到,后续可以处理空闲处理器等
- // Next message is not ready. Set a timeout to wake up when it is ready.
- nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
- } else {
- // Got a message.
- mBlocked = false;
- if (prevMsg != null) {
- prevMsg.next = msg.next;
- } else {
- mMessages = msg.next;.//下个消息赋值为mMessages
- }
- msg.next = null;
- if (DEBUG) Log.v(TAG, "Returning message: " + msg);
- msg.markInUse();
- return msg;
- }
- } else {
- // No more messages.
- nextPollTimeoutMillis = -1;//没有消息无限阻塞
- }
- ......