handler消息處理機制

       Android系統的消息隊列和消息循環都是針對具體線程的,一個線程可以存在(當然也可以不存在)一個消息隊列(Message Queue)和一個消息循環(Looper)。Android中除了UI線程(主線程),創建的工作線程默認是沒有消息循環和消息隊列的。如果想讓該線程具有消息隊列和消息循環,並具有消息處理機制,就需要在線程中首先調用Looper.prepare()來創建消息隊列,然後調用Looper.loop()進入消息循環。

class LooperThread extends Thread {  

   public Handler mHandler;  

   public void run() {  

         Looper.prepare();  

         mHandler = new Handler() {  

           public void handleMessage(Message msg) {  

               // process incoming messages here

            }  

         };  

        Looper.loop();  

    }  

}

Handler可以把一個Message對象或者Runnable對象壓入到消息隊列中,進而在UI線程中獲取Message或者執行Runnable對象,所以Handler把壓入消息隊列有兩大體系,Post和sendMessage。

Post:Post允許把一個Runnable對象入隊到消息隊列中。它的方法有:post(Runnable)、      postAtTime(Runnable,long)、postDelayed(Runnable,long)。

sendMessage:sendMessage允許把一個包含消息數據的Message對象壓入到消息隊列中。它的方法有:sendEmptyMessage(int)、sendMessage(Message)、sendMessageAtTime(Message,long)、sendMessageDelayed(Message,long)。


Message:Message是一個final類,所以不可被繼承。使用Message.obtain()這個靜態的方法或者Handler.obtainMessage()獲取。Message.obtain()方法具有多個重載方法,大致可以分爲爲兩類,一類是無需傳遞Handler對象,對於這類的方法,當填充好消息後,需要調用Handler.sendMessage()方法來發送消息到消息隊列中。第二類需要傳遞一個Handler對象,這類方法可以直接使用Message.sendToTarget()方法發送消息到消息隊列中,這是因爲在Message對象中有一個私有的Handler類型的屬性Target,當時obtain方法傳遞進一個Handler對象的時候,會給Target屬性賦值,當調用sendToTarget()方法的時候,實際在它內部還是調用的Target.sendMessage()方法。


總結:一個Looper對應一個MessageQueue,一個線程對應一個Looper,一個線程可以有多個looper。


Handler handler = new Handler(){...}創建Handler。這樣創建的handler是在主線程即UI線程下的Handler,即這個Handler是與UI線程下的默認Looper綁定的。HandlerThread實際上就一個Thread,只不過它比普通的Thread多了一個Looper。創建HandlerThread時要把它啓動了,即調用start()方法。然後創建Handler時將HandlerThread中的looper對象傳入。

HandlerThread thread = new HandlerThread("MyHandlerThread");
thread.start();
mHandler = new Handler(thread.getLooper());
mHandler.post(new Runnable(){...});
那麼這個Handler對象就是與HandlerThread這個線程綁定了(這時就不再是與UI線程綁定了,這樣它處理耗時操作將不會阻塞UI)。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章