博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
安卓 消息队列 优先级 顺序
阅读量:7113 次
发布时间:2019-06-28

本文共 3453 字,大约阅读时间需要 11 分钟。

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

 

消息队列排序

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

[cpp]   
 
  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]   
 
  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]   
 
  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]   
 
    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.             ......  

 

转载于:https://www.cnblogs.com/yue31313/p/7397348.html

你可能感兴趣的文章
2014年辛星解读Javascript之DOM之事件及其绑定
查看>>
企业管理 把公司做小,把客户做大
查看>>
tiff和geotiff格式分析
查看>>
R语言低级绘图函数-arrows
查看>>
C#接口,类,集成
查看>>
js省市联动
查看>>
bzoj 4868: [Shoi2017]期末考试
查看>>
django(一)--- 安装django
查看>>
assetBundle打包脚本与LUA
查看>>
运用python抓取博客园首页的所有数据,而且定时持续抓取新公布的内容存入mongodb中...
查看>>
转 Python Selenium设计模式-POM
查看>>
vue.js应用开发笔记
查看>>
学习开淘宝网店
查看>>
计算机网络之物理层笔记
查看>>
Spring的Hello World工程
查看>>
linux可视化桌面安装
查看>>
Redis学习之路(002)- Ubuntu下redis开放端口
查看>>
本地调用jni之VC++无法导入问题
查看>>
C语言实现---学生成绩管理系统
查看>>
Handling PnP Paging Request
查看>>