您的位置:首页 > 其它

安卓 消息队列 优先级 顺序

2017-08-19 23:53 495 查看
韩梦飞沙 yue31313 韩亚飞 han_meng_fei_sha 313134555@qq.com

 


消息队列排序

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

[cpp] view plain copy
 

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,自然就排在队列的前面了。

 

[cpp] view plain copy
 

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插入到合适的消息队列中。

 

 

[cpp] view plain copy
 

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来获取当前消息。

[cpp] view plain copy
 

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;//没有消息无限阻塞  
            }  
            ......  
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: