Handler訊息機制及handler原理(Handler,Looper,MessageQueue),自定義Handler

desaco發表於2016-02-27

Handler/Message/Looper/MessageQueue

-- 安卓為什麼要設計Looper阻塞?
Android的應用程式和Windows應用程式一樣,都是由訊息驅動的。在Android作業系統中,谷歌也實現了訊息迴圈處理機制。
1.Looper依賴於MessageQueue和Thread,每個Thread只對應一個Looper,每個Looper只對應一個MessageQueue(一對一)。
2.MessageQueue依賴於Message,每個MessageQueue中有N個待處理訊息(一對N)。
3.Message依賴於Handler來進行處理,每個Message有且僅有一個對應的Handler。(一對一)
4.Handler中持有Looper和MessageQueue的引用,可直接對其進行操作。
5.Handler機制,即訊息處理的機制,封裝了一套訊息建立、傳遞、處理機制。
-- handler 的原理是什麼?()

從原始碼深入理解Android Handler非同步訊息處理機制- https://blog.csdn.net/wdmzszly/article/details/81941116

Android訊息機制原始碼解析(Handler)- https://blog.csdn.net/Awenyini/article/details/78593139

首先是Handler/Message/Looper/MessageQueue這些物件的初始化,然後才是使用這些物件進行訊息處理。
1、handler封裝訊息的傳送(主要包括訊息傳送給誰);
2、Looper——訊息封裝的載體。(1)內部包含一個MessageQueue,所有的Handler傳送的訊息都走向這個訊息佇列;(2)Looper.Looper方法,就是一個死迴圈,不斷地從MessageQueue取訊息,如果有訊息就處理訊息,沒有訊息就阻塞;
3、MessageQueue,一個訊息佇列,新增訊息,處理訊息;
4、handler內部與Looper關聯,handler->Looper->MessageQueue,handler傳送訊息就是向MessageQueue佇列傳送訊息。
總結:handler負責傳送訊息,Looper負責接收handler傳送的訊息,並把訊息回傳給handler自己。MessageQueue儲存訊息的容器。

private Handler handler;
public void sendMsg() {//
    //方法1
    Message msg = new Message();
    msg.what = 1;
    msg.arg1 = 2;
    msg.arg2 = 3;
    msg.obj = "demo";
    handler.sendMessage(msg);
    //方法2
    Message msg2 = handler.obtainMessage();
    //obtainMessage();
    //obtainMessage(what);
    //obtainMessage(int what,Object obj); 
    //obtainMessage(int what,int arg1,int arg2);
    //obtainMessage(int what,int arg1,int arg2,Object obj );
    msg2.what = 1;
    msg2.arg1 = 2;
    msg2.arg2 = 3;
    msg2.obj = "demo";
    msg2.sendToTarget();
    //方法3
    Message msg3 = Message.obtain();
    msg3.sendToTarget();
}

> Handler 訊息機制
1. 在Looper.loop()方法執行開始後,迴圈地按照接收順序取出Message Queue裡面的非NULL的Message。
2. 一開始Message Queue裡面的Message都是NULL的。當Handler.sendMessage(Message)到Message Queue,該函式裡面設定了那個Message物件的target屬性是當前的Handler物件。隨後Looper取出了那個Message,則呼叫該Message的target指向的Hander的dispatchMessage函式對Message進行處理。
    在dispatchMessage方法裡,如何處理Message則由使用者指定,三個判斷,優先順序從高到低:
    1) Message裡面的Callback,一個實現了Runnable介面的物件,其中run函式做處理工作;
    2) Handler裡面的mCallback指向的一個實現了Callback介面的物件,由其handleMessage進行處理;
    3) 處理訊息Handler物件對應的類繼承並實現了其中handleMessage函式,通過這個實現的handleMessage函式處理訊息。
    由此可見,我們實現的handleMessage方法是優先順序最低的!

> Handler的機制與原始碼分析,及自定義Handler
Android Handler原始碼級分析及自定義Handler實現- https://blog.csdn.net/liurenyou/article/details/72805916
Android訊息機制Handler解析(原始碼+Demo)-- http://m.blog.csdn.net/article/details?id=51031331
Handler 原始碼分析-- http://blog.csdn.net/miraclemin/article/details/6556620
Android】從原始碼中探討Handler機制-- http://blog.csdn.net/rongxinhua/article/details/20576185
   假如在同一個Activity中,有多個執行緒同時更新UI,且沒有加鎖,那會導致什麼問題呢?UI更新混亂。假如加鎖呢?會導致效能下降。使用Handler機制,我們不用去考慮多執行緒的問題,所有更新UI的操作,都是在 主執行緒訊息佇列中輪詢去處理的。]

> Handler 訊息傳遞機制
message.sendToTarget();
/*1、message由handler建立,可直接向handler傳送訊息。msg.sendToTarget()*/
            Message msg = handler.obtainMessage();
            msg.arg1 = i;
            msg.sendToTarget();

/*2、message通過new的方式建立,可用handler.sendMessage(msg)來傳送訊息*/
            Message msg=new Message();
            msg.arg1=i;
            handler.sendMessage(msg);
            //直接呼叫 handler 的傳送訊息方法傳送訊息。

/* 3、message通過Message.obtain的方式建立,可用sendMessage(msg)來傳送訊息 */
           Message msg= Message.obtain();
           msg.arg1=i;
           handler.sendMessage(msg);

> Looper.getMainLooper()與Looper.myLooper();Looper.myLooper().quit(); Looper.getMainLooper().quit();
-- getMainLooper()
  Returns the application's main looper, which lives in the main thread of the application.
-- myLooper()
  Return the Looper object associated with the current thread. Returns null if the calling thread is not associated with a Looper.

boolean isUiThread = Looper.getMainLooper().getThread() == Thread.currentThread();
boolean isUiThread = Looper.getMainLooper().isCurrentThread();
 

相關文章