安卓 消息队列 优先级 顺序

来源:互联网 发布:手机淘宝联系天猫客服 编辑:程序博客网 时间:2024/06/14 17:28

韩梦飞沙 yue31313 韩亚飞 han_meng_fei_sha 313134555@qq.com

 

消息队列排序

一般的像我们普通调用Handler发送消息,最后都会调用MessageQueue的enqueueMessage。

[cpp] view plain copy
 
  1. public boolean sendMessageAtTime(Message msg, long uptimeMillis) {  
  2.     MessageQueue queue = mQueue;  
  3.     if (queue == null) {  
  4.         RuntimeException e = new RuntimeException(  
  5.                 this + " sendMessageAtTime() called with no mQueue");  
  6.         Log.w("Looper", e.getMessage(), e);  
  7.         return false;  
  8.     }  
  9.     return enqueueMessage(queue, msg, uptimeMillis);  
  10. }  

像sendMessageAtFrontOfQueue这样只是最后的时间设置为0,自然就排在队列的前面了。

 

[cpp] view plain copy
 
  1. public final boolean sendMessageAtFrontOfQueue(Message msg) {  
  2.     MessageQueue queue = mQueue;  
  3.     if (queue == null) {  
  4.         RuntimeException e = new RuntimeException(  
  5.             this + " sendMessageAtTime() called with no mQueue");  
  6.         Log.w("Looper", e.getMessage(), e);  
  7.         return false;  
  8.     }  
  9.     return enqueueMessage(queue, msg, 0);  
  10. }  
  11.   
  12. private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {  
  13.     msg.target = this;//一般讲target设置为Handler  
  14.     if (mAsynchronous) {  
  15.         msg.setAsynchronous(true);  
  16.     }  
  17.     return queue.enqueueMessage(msg, uptimeMillis);  
  18. }  

最后就到MessageQueue的enqueueMessage函数中去了,该函数就是根据when把这个msg插入到合适的消息队列中。

 

 

[cpp] view plain copy
 
  1. boolean enqueueMessage(Message msg, long when) {  
  2.     ......  
  3.   
  4.     synchronized (this) {  
  5.         ......  
  6.   
  7.         msg.markInUse();  
  8.         msg.when = when;  
  9.         Message p = mMessages;//当前message  
  10.         boolean needWake;  
  11.         if (p == null || when == 0 || when < p.when) {  
  12.             // New head, wake up the event queue if blocked.  
  13.             msg.next = p;  
  14.             mMessages = msg;  
  15.             needWake = mBlocked;  
  16.         } else {  
  17.             // Inserted within the middle of the queue.  Usually we don't have to wake  
  18.             // up the event queue unless there is a barrier at the head of the queue  
  19.             // and the message is the earliest asynchronous message in the queue.  
  20.             needWake = mBlocked && p.target == null && msg.isAsynchronous();  
  21.             Message prev;  
  22.             for (;;) {  
  23.                 prev = p;  
  24.                 p = p.next;  
  25.                 if (p == null || when < p.when) {//找到一个Message,when小于该message的when break  
  26.                     break;  
  27.                 }  
  28.                 if (needWake && p.isAsynchronous()) {  
  29.                     needWake = false;  
  30.                 }  
  31.             }  
  32.             msg.next = p; // invariant: p == prev.next  
  33.             prev.next = msg;//这其实就是把该message插入合适的位置  
  34.         }  
  35.   
  36.         // We can assume mPtr != 0 because mQuitting is false.  
  37.         if (needWake) {  
  38.             nativeWake(mPtr);  
  39.         }  
  40.     }  
  41.     return true;  
  42. }  

最后我们再看下MessageQueue的next函数,就是消息线程循环时会不断调用MessageQueue的next来获取当前消息。

[cpp] view plain copy
 
  1. Message next() {  
  2.     final long ptr = mPtr;  
  3.     if (ptr == 0) {  
  4.         return null;  
  5.     }  
  6.   
  7.     int pendingIdleHandlerCount = -1; // -1 only during first iteration  
  8.     int nextPollTimeoutMillis = 0;  
  9.     for (;;) {  
  10.         if (nextPollTimeoutMillis != 0) {  
  11.             Binder.flushPendingCommands();  
  12.         }  
  13.   
  14.         nativePollOnce(ptr, nextPollTimeoutMillis);//c层的epoll函数会阻塞  
  15.   
  16.         synchronized (this) {  
  17.             // Try to retrieve the next message.  Return if found.  
  18.             final long now = SystemClock.uptimeMillis();  
  19.             Message prevMsg = null;  
  20.             Message msg = mMessages;// 当前msg  
  21.             if (msg != null && msg.target == null) {//这里就是和异步消息有关,下节分析  
  22.                 // Stalled by a barrier.  Find the next asynchronous message in the queue.  
  23.                 do {  
  24.                     prevMsg = msg;  
  25.                     msg = msg.next;  
  26.                 } while (msg != null && !msg.isAsynchronous());  
  27.             }  
  28.             if (msg != null) {  
  29.                 if (now < msg.when) {//当前消息还没到,后续可以处理空闲处理器等  
  30.                     // Next message is not ready.  Set a timeout to wake up when it is ready.  
  31.                     nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);  
  32.                 } else {  
  33.                     // Got a message.  
  34.                     mBlocked = false;  
  35.                     if (prevMsg != null) {  
  36.                         prevMsg.next = msg.next;  
  37.                     } else {  
  38.                         mMessages = msg.next;.//下个消息赋值为mMessages  
  39.                     }  
  40.                     msg.next = null;  
  41.                     if (DEBUG) Log.v(TAG, "Returning message: " + msg);  
  42.                     msg.markInUse();  
  43.                     return msg;  
  44.                 }  
  45.             } else {  
  46.                 // No more messages.  
  47.                 nextPollTimeoutMillis = -1;//没有消息无限阻塞  
  48.             }  
  49.             ......  

 

原创粉丝点击