Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 消息處理源碼分析(1)

Android 消息處理源碼分析(1)

編輯:關於Android編程

Android 消息處理源碼分析(1)


在Android中,通常被使用的消息隊列的代碼在目錄sourcesandroid-22androidos下,涉及到以下幾個類文件
Handler.java

Looper.java

Message.java

MessageQueue.java

 

 

Message.java
public final class Message implements Parcelable {

    public int what;    //消息種類

    public int arg1;    //低開銷的整型參數

    public int arg2;

    public Object obj;  //Object型數據

    public Messenger replyTo;  //消息處理完後通知給發送者

    /*package*/ int flags;   //消息標記:正在使用和異步等

    /*package*/ long when;   //消息創建時的時間
    
    /*package*/ Bundle data; //消息附帶的額外數據
    
    /*package*/ Handler target; //消息接受者,處理者
    
    /*package*/ Runnable callback; //優先使用回調處理來處理消息
    
    /*package*/ Message next;   //下一個消息,形成鏈表

    private static Message sPool;    //消息池中的頭消息
    

上面中的target,通常由重新實現的Handler子類的handleMessage函數來處理消息

 public static Message obtain() {     //獲取消息的函數,如果有消息的話則獲取出來m,鏈表指針移動一位,否則則返回一條空消息
        synchronized (sPoolSync) {
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }


 public void sendToTarget() {    //發送消息給處理者
        target.sendMessage(this);    //調用Handler.java中的函數
    }

}

MessageQueue.java
public final class MessageQueue {
	
	Message mMessages;    //當前要處理的消息
	
	//當需要從鏈表中獲取一個消息時,就會調用next函數,若消息隊列中沒有消息,則會阻塞等待,通過調用nativePollOnce函數來完成
	Message next() {...}
	
	boolean enqueueMessage(Message msg, long when) {     //按時間順序添加消息
        if (msg.target == null) {
            throw new IllegalArgumentException(Message must have a target.);
        }
        if (msg.isInUse()) {
            throw new IllegalStateException(msg +  This message is already in use.);
        }

        synchronized (this) {
            if (mQuitting) {
                IllegalStateException e = new IllegalStateException(
                        msg.target +  sending message to a Handler on a dead thread);
                Log.w(MessageQueue, e.getMessage(), e);
                msg.recycle();
                return false;
            }

            msg.markInUse();
            msg.when = when;
            Message p = mMessages;
            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) {
                        break;
                    }
                    if (needWake && p.isAsynchronous()) {
                        needWake = false;
                    }
                }
                msg.next = p; // invariant: p == prev.next
                prev.next = msg;
            }

            // We can assume mPtr != 0 because mQuitting is false.
            if (needWake) {      
                nativeWake(mPtr);  //調用底層喚醒函數,管道喚醒
            }
        }
        return true;
    }
   
    

 
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved