Handler老是依附於建立時所在的線程,好比咱們的Handler是在主線程中建立的,而在子線程中又沒法直接對UI進行操做,因而咱們就經過一系列的發送消息、入隊、出隊等環節,最後調用到了Handler的handleMessage()方法中,這時的handleMessage()方法已是在主線程中運行的,於是咱們固然能夠在這裏進行UI操做了。整個異步消息處理流程的示意圖以下圖所示:android
這即是咱們平時直接使用的主角。繼承Handler
重寫其handleMessage()
方法來處理消息,在須要的時候調用sendMessage()
來發消息,剩下的就不用管了。如今來看看「咱們不用管」的這部分都幹了點啥。bash
全部的構造方法最終會會調用兩個實現,若是制定了Looper,則會調用三個參數的重載,不然會調用兩個參數的重載。然後者則會調用Lopper.myLooper()
來獲取looper。兩個構造方法除了給mLooper
賦值外,還給mQueue
賦值爲mLooper.mQueue
;給mCallback
賦值爲指定的callback或null;給mAsynchronous
賦值爲指定的boolean或false。 在兩個參數的構造方法中,給上述四個成員賦值前有段if(FIND_POTENTIAL_LEAKS){}
包裹的代碼段,該變量定義爲private static final boolean FIND_POTENTIAL_LEAKS = false;
所以推斷這部分是開發時調試用的,此處不作理會。微信
根據源碼能夠看出,全部該方法的重載都調用了Message.obtain()
對應的重載,能夠看Message.obtain()的前因後果來了解,此處再也不贅述。須要注意的是,每一個重載都傳入了this
參數並賦值給了message的target
。這裏先記着就行,後面會介紹如何經過target
調用dispatchMessage()
處理消息。app
全部的sendEmptyMessage()
重載與sendMessageXXX()
以及postXXX()
最終都會調用enqueueMessage()
方法,該方法則調用queue.enqueueMessage()
方法將消息添加到消息隊列。關於消息隊列如何管理消息能夠看MessageQueue的隊列管理一文。異步
全部的removeMessages()
重載與removeCallbacks()
重載最終都是調用mQueue.removeMessages()
方法,即經過MessageQueue來實現該操做。詳細分析能夠看MessageQueue的隊列管理一文。ide
消息處理最開始被調用的不是handleXXX()
方法,而是dispatchMessage()
方法。該方法會根據消息是否有callback
來判斷該交給handleCallback()
仍是handleMessage()
。前者直接調用參數中message
的message.calback.run()
解決問題,後者則是空方法體,須要咱們開發者本身重寫。oop
handler能夠分發Message對象和Runnable對象到主線程中, 每一個Handler實例,都會綁定到建立他的線程中(通常是位於主線程),它有兩個做用:post
子類須要繼承Hendler類,並重寫handleMessage(Message msg) 方法, 用於接受線程數據。ui
如下爲一個實例,它實現的功能爲:經過線程修改界面Button的內容this
public class MyHandlerActivity extends Activity {
Button button;
MyHandler myHandler;
protected void onCreate(Bundle savedInstanceState) {
super。onCreate(savedInstanceState);
setContentView(R。layout。handlertest);
button = (Button) findViewById(R。id。button);
myHandler = new MyHandler();
// 當建立一個新的Handler實例時, 它會綁定到當前線程和消息的隊列中,開始分發數據
// Handler有兩個做用, (1) : 定時執行Message和Runnalbe 對象
// (2): 讓一個動做,在不一樣的線程中執行。
// 它安排消息,用如下方法
// post(Runnable)
// postAtTime(Runnable,long)
// postDelayed(Runnable,long)
// sendEmptyMessage(int)
// sendMessage(Message);
// sendMessageAtTime(Message,long)
// sendMessageDelayed(Message,long)
// 以上方法以 post開頭的容許你處理Runnable對象
//sendMessage()容許你處理Message對象(Message裏能夠包含數據,)
MyThread m = new MyThread();
new Thread(m)。start();
}
/**
* 接受消息,處理消息 ,此Handler會與當前主線程一塊運行
* */
class MyHandler extends Handler {
public MyHandler() {
}
public MyHandler(Looper L) {
super(L);
}
// 子類必須重寫此方法,接受數據
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
Log。d("MyHandler", "handleMessage。。。。。。");
super。handleMessage(msg);
// 此處能夠更新UI
Bundle b = msg。getData();
String color = b。getString("color");
MyHandlerActivity。this。button。append(color);
}
}
class MyThread implements Runnable {
public void run() {
try {
Thread。sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e。printStackTrace();
}
Log。d("thread。。。。。。。", "mThread。。。。。。。。");
Message msg = new Message();
Bundle b = new Bundle();// 存放數據
b。putString("color", "個人");
msg。setData(b);
MyHandlerActivity。this。myHandler。sendMessage(msg); // 向Handler發送消息,更新UI
}
}
}複製代碼
若是你覺
得此文對您有所幫助,歡迎入羣 QQ交流羣 :232203809
微信公衆號:終端研發部