Android總結之Handler&MessageQueue&Message&Looper源碼分析


在這裏插入圖片描述

1.Handler負責消息的發送和消息的接收處理,主要包括2類方法

1.1.消息的發送sendMessage方法
public final boolean sendMessage(Message msg)
{
	return sendMessageDelayed(msg, 0);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
    msg.target = this;
    if (mAsynchronous) {
        msg.setAsynchronous(true);
    }
    return queue.enqueueMessage(msg, uptimeMillis);
}

msg經過層層調用會進入MessageQueue消息隊列中:sendMessage -> sendMessageDelayed -> sendMessageAtTime -> enqueueMessage,最終在enqueueMessage中將待發送的消息msg加入到mQueue消息隊列中。

1.2.消息的接收處理handleMessage方法

handleMessage在Handler中2個地方有定義,這也對應2種使用方式

1.2.1.Handler#handleMessage()
/**
 * Subclasses must implement this to receive messages.
 */
public void handleMessage(Message msg) {
}
1.2.2.Handler#Callback#handleMessage()
/**
 * Callback interface you can use when instantiating a Handler to avoid
 * having to implement your own subclass of Handler.
 */
public interface Callback {
    /**
     * @param msg A {@link android.os.Message Message} object
     * @return True if no further handling is desired
     */
    public boolean handleMessage(Message msg);
}

2.MessageQueue負責保存消息至消息隊列,包括消息查找,消息入隊

2.1.消息查找next()方法
Message next() {
	/* ...there are some code omitted here...*/
}

在Looper#loop()方法中會調用Message msg = queue.next();獲取下一條消息

2.2.消息入隊enqueueMessage()方法
boolean enqueueMessage(Message msg, long when) {
    /* ...there are some code omitted here...*/
    synchronized (this) {
		/* ...there are some code omitted here...*/
        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;
        }
		/* ...there are some code omitted here...*/
    }
    return true;
}

這裏運用了鏈表來保存消息msg,插入消息到消息隊列(鏈表)中

3.Message代表一條消息,每條消息可以攜帶數據,具體可參考下表所示

變量名 類型 說明 備註
what int 用戶自定義code用於辨別不同的message 公有的,可通過msg.what設置
arg1 int arg1和arg2用於保存一些integer類型的數據 公有的,可通過msg.arg1設置
arg2 int arg1和arg2用於保存一些integer類型的數據 公有的,可通過msg.arg2設置
obj Object 用於保存對象 公有的,可通過msg.obj設置
data Bundle 用於保存其它數據 非公有的,可通過setData()方法設置data

4.Looper負責取消息並派發給Handler,主要是在loop方法處理

/**
 * Run the message queue in this thread. Be sure to call
 * {@link #quit()} to end the loop.
 */
public static void loop() {
   	/* ...there are some code omitted here...*/
    for (;;) {
        Message msg = queue.next(); // might block
        if (msg == null) {
            // No message indicates that the message queue is quitting.
            return;
        }
		/* ...there are some code omitted here...*/
        try {
            msg.target.dispatchMessage(msg);
            dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
        } finally {
            if (traceTag != 0) {
                Trace.traceEnd(traceTag);
            }
        }
 	/* ...there are some code omitted here...*/
    }
}

4.1.先使用queue.next()取消息,如果消息爲空,則退出消息循環,否則轉到第4.2步
4.2.使用msg.target.dispatchMessage(msg);派發消息給Handler,其中msg.target代表發送這條消息的Handler對象。
/**
 * Handle system messages here.
 */
public void dispatchMessage(Message msg) {
    if (msg.callback != null) {
        handleCallback(msg);
    } else {
        if (mCallback != null) {
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg);
    }
}
private static void handleCallback(Message message) {
    message.callback.run();
}
4.3.dispatchMessage根據用戶定義Handler和調用不同發送消息方法可分爲3種情況
序號 條件 定義Handler和消息發送方法
case1 msg.callback != null Handler#post(Runnable r)
case2 mCallback != null Handler#Handler(Callback callback)
case3 msg.callback == null && mCallback == null Handler#sendMessage(Message msg)

5.介紹4.3中的3種情況:

case1 for Handler#post(Runnable r)
final Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg){
        Log.i(TAG, "From Handler Msg is:" + msg.obj);
    }
};

new Thread(new Runnable() {
    @Override
    public void run() {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
            }
        };
        handler.post(runnable);
    }
}).start();
case2 for Handler#Handler(Callback callback)
/* first, define a class to implement handleMessage method from Handler's inner class Callback.*/
class MyHandlerCallback implements Hander.Callback{
	public boolean handleMessage(Message msg){
		Log.i(TAG, "From Handler Msg is:" + msg.obj);
	}
}

/* then define a Handler object by using the Callback subclass object as a argument.*/
MyHanlderCallback myHandlerCallback = new MyHandlerCallback();
final Handler handler = new Handler(myHandlerCallback);
new Thread(new Runnable() {
    @Override
    public void run() {
        Message msg = new Message();
        msg.obj = "message data";
        handler.sendMessage(msg);
    }
}).start();
case3 for Handler#sendMessage(Message msg)
final Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg){
        Log.i(TAG, "From Handler Msg is:" + msg.obj);
    }
};

new Thread(new Runnable() {
    @Override
    public void run() {
        Message msg = new Message();
        msg.obj = "message data";
        handler.sendMessage(msg);
    }
}).start();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章