android handler、looper、message、messageQueue、

來源:互聯網
上載者:User

標籤:android   style   color   ar   使用   strong   sp   資料   on   

一:handler,looper,message,messagequeue,thread

handler: 訊息處理著,負責Message訊息的發送(handler.sendMessage(....))以及處理訊息,對於handler處理訊息則需要實現handlerMessage(Message msg)該方法,通過該方法處理特定的訊息,例如ui的更細

looper:訊息泵,用來從messageQueue中抽取訊息,所以一個looper對應一個messageQueue;

message:訊息,message中含有該訊息的ID以及訊息處理對象或者處理的資料,通過messageQueue訊息佇列同一處理。

messageQueue,訊息佇列,messageQueue中儲存 通過handler發送來的訊息,當然該儲存不是真正意義上儲存,而是以鏈式結構將訊息連結起來。等待looper的抽取

thread:線程,負的調度整個訊息迴圈,即訊息迴圈的場所執行

 

二:handler、looper、messageQueue之間的關係

      looper與messageQueue是一一對應的關係,及建立一個looper的同時建立一個messageQueue,handler與它們只是簡單的彙總關係,handler中會引用當前線程中的looper與messageQueue,從這裡可以看出對個handler 能夠同時處理一個looper與messageQueue,前提是這些handler都在同一個線程中

 

三:簡單一實例:

     訊息的產生:

  Message msg=Handler.obtiainMessage();

  msg.what=what;

  msg.sendToTarget();

   訊息發送:    

  

   
  MessageQueue queue=looper.myQueue();

//通過該對象找到與之對應的訊息佇列messageQueue

if(queue!=null){
  msg.target=this  

     sent = queue.enqueueMessage(msg, uptimeMillis);

}

註:在handler的sendMessageAtTme(Message msg,long time)中可以看出handler 找到自己線程中的MessageQueue中的message 然後將message的target設定為handler自己,目的是message能夠找到正確的handler

 

 三:抽取

 //得到handler所線上程中的looper對象;
   Looper looper=handler1.getLooper();

//通過該對象找到與之對應的訊息佇列messageQueue
  MessageQueue queue=looper.myQueue();

   while (true) {

            Message msg = queue.next();   //不斷的從訊息佇列中擷取訊息 

            if (msg != null) {

                if (msg.target == null) {

                    return;

                }

                msg.target.dispatchMessage(msg);

                msg.recycle();

            }

        }

從這裡我們可以看出 不斷的從訊息佇列中擷取訊息,然後通過message的target中攜帶的資訊去,尋找正確的handler  用來處理該訊息

四:處理:

 

  handler = new Handler(){

     複寫handlerMessage(Message msg);

     }  

至此,我們看到,一個Message經由Handler的發送,MessageQueue的入隊,Looper的抽取,又再一次地回到Handler的懷抱。而繞的這一圈,也正好協助我們將同步操作變成了非同步作業。

 

 小執行個體:跟新UI

首先在主線程中如果我們使用handler不建立looper對象,則系統會預設使用主線程中已經建立好的looper對象,然而在非ui線程中我們使用handler而不傳入looper對象,則這個handler不能接受訊息。

通常的做法是:

  Thread thread = new Thread() {

   @Override
   public void run() {

//建立handler之前我們需要首先準備一個looper


    Looper.prepare();
    Handler handler = new Handler() {

     @Override
     public void handleMessage(Message msg) {
      // TODO Auto-generated method stub
      super.handleMessage(msg);
     }

    };
    super.run();
   }

  };

//將該looper啟動(跑起來)這樣就能夠從messageQueue中抽取message   這樣handler才能正常運行
  Looper.loop();
  thread.start();

 }

 

註:handler 處理訊息總是在建立該handler的線程中運行,而我們的訊息處理中,不乏更新UI的操作,不正確的線程直接更新UI將引發異常,因此我們需要即時注意handler所在的線程。

 

小結:

  • handler 的處理運行是在建立該handler的線程中運行
  • 一個looper對應一個messageQueue
  • 一個線程對應一個looper
  • 一個looper可以對應多個handler(這些handler在同一個線程中) 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

     

android handler、looper、message、messageQueue、

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.