Handler消息機制徹底解析Handler解析

Handler

Handler老是依附於建立時所在的線程,好比咱們的Handler是在主線程中建立的,而在子線程中又沒法直接對UI進行操做,因而咱們就經過一系列的發送消息、入隊、出隊等環節,最後調用到了Handler的handleMessage()方法中,這時的handleMessage()方法已是在主線程中運行的,於是咱們固然能夠在這裏進行UI操做了。整個異步消息處理流程的示意圖以下圖所示:android

異步消息處理流程
異步消息處理流程

Handler

這即是咱們平時直接使用的主角。繼承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;
所以推斷這部分是開發時調試用的,此處不作理會。微信

建立消息obtainMessage()

根據源碼能夠看出,全部該方法的重載都調用了Message.obtain()
對應的重載,能夠看Message.obtain()的前因後果來了解,此處再也不贅述。須要注意的是,每一個重載都傳入了this
參數並賦值給了message的target
。這裏先記着就行,後面會介紹如何經過target
調用dispatchMessage()
處理消息。app

發送消息sendMessage()

全部的sendEmptyMessage()
重載與sendMessageXXX()
以及postXXX()
最終都會調用enqueueMessage()
方法,該方法則調用queue.enqueueMessage()
方法將消息添加到消息隊列。關於消息隊列如何管理消息能夠看MessageQueue的隊列管理一文。異步

移除消息removeMessage()

全部的removeMessages()
重載與removeCallbacks()
重載最終都是調用mQueue.removeMessages()
方法,即經過MessageQueue來實現該操做。詳細分析能夠看MessageQueue的隊列管理一文。ide

處理消息dispatchMessage()

消息處理最開始被調用的不是handleXXX()
方法,而是dispatchMessage()
方法。該方法會根據消息是否有callback
來判斷該交給handleCallback()
仍是handleMessage()
。前者直接調用參數中message
的message.calback.run()
解決問題,後者則是空方法體,須要咱們開發者本身重寫。oop

Handler一些特色

  • handler能夠分發Message對象和Runnable對象到主線程中, 每一個Handler實例,都會綁定到建立他的線程中(通常是位於主線程),它有兩個做用:post

    • (1)安排消息或Runnable 在某個主線程中某個地方執行;
    • (2)安排一個動做在不一樣的線程中執行。

Handler實例

  • 子類須要繼承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
    微信公衆號:終端研發部

技術+職場
技術+職場
相關文章
相關標籤/搜索