2012-12-25 33 views
4

問題是,我告訴我的線程使用mHandlerLooperLooper如何知道將消息發送給Handler?

謝謝。 我正在使用下面的代碼:

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(); 
    } 
} 
+0

就在完成所有必須在線程調用「處理程序」執行的任務之後......並執行處理程序中的線程操作之後必須執行的所有任務......! !!我是否達到了你的要求? –

回答

4

問題是,我告訴我的線程使用mHandler作爲 Looper?

你不需要明確地告訴它,因爲系統(框架)爲你做。當您實例化Handler時,它將自動獲得對當前Thread的消息隊列的訪問權限。引用您的點評:

系統知道如何將消息發送到mHandlerHandler

我會在下面詳細說明。

這是android.os.Handler構造在安卓

mLooper = Looper.myLooper(); 
    if (mLooper == null) { 
     throw new RuntimeException(
      "Can't create handler inside thread that has not called Looper.prepare()"); 
    } 
    mQueue = mLooper.mQueue; 

正如你所看到的,首先它獲得當前的ThreadLooper。的Looper.myLooper()源代碼如下:

public static final Looper myLooper() { 
    return (Looper)sThreadLocal.get(); 
} 

它獲得它從線程本地存儲。稍後,當您發送Message與此Handler時,Handler實際上將其自身設置爲Message收件人:這是Looper將知道何時在Message到達時將其分派到哪裏。具體爲:

當你調用mHandler.sendMessage(),最終運行此代碼(許多其他的代碼行中):

MessageQueue queue = mQueue; 
    boolean sent = false; 
    if (queue != null) { 
     msg.target = this; // msg is your Message instance 
     sent = queue.enqueueMessage(msg, uptimeMillis); 
    } 

正如你所看到的,它設置Handler實例爲Message的目標。所以,稍後,當調度Message時,它將包含Handler作爲其目標。這是Looper將知道應該將其分派給哪個Handler。在細節,當你調用Looper.loop(),下面會爲每個隊列您Message實例:

msg.target.dispatchMessage(msg); 

dispatchMessage()代碼如下:

public void dispatchMessage(Message msg) { 
    if (msg.callback != null) { 
     handleCallback(msg); 
    } else { 
     if (mCallback != null) { 
      if (mCallback.handleMessage(msg)) { 
       return; 
      } 
     } 
     handleMessage(msg); 
    } 
} 

通知的最後handleMessage(msg)電話 - - 這正是您的handleMessage(msg)覆蓋!

+0

非常感謝。現在我和每個人都可以理解它。 – Aminadav

+0

嗨@ThomasCalc,請你幫忙回答這個問題:http://stackoverflow.com/questions/31914966/how-to-get-the-amount-of-specified-message-which-not-handled-by-handler -in-雄 –

2

你什麼都不說。從Handler文檔:

每個處理程序實例與單個線程關聯,並且該線程的消息隊列是 。當您創建一個新的處理程序時,它將綁定到正在創建它的線程的線程/消息隊列012xx指向它時,它將向該消息傳遞消息和可運行列表 隊列,並在它們退出時執行它們消息隊列。

處理程序自動綁定到線程的消息隊列。您只執行回調,並且系統將負責處理所有事情,即分派和處理消息。其實我同意,使用兩個靜態方法,如Looper.prepare()Looper.loop()和自動推斷的東西,使圖案感覺像黑魔法:)

+0

但是,我可以chahehe mHandler,以其他名字?系統知道如何將消息發送給mHandler處理程序? – Aminadav

+0

你可以任意命名。系統知道與Handler關聯的*線程*,因爲周圍調用了'Looper'方法。但處理程序,你必須自己指定它。如果你告訴你的應用程序做什麼,我可以舉一個例子,以便更好地理解 – Raffaele

4

爲了有一個更好的瞭解,創建一個普通的Thread,並嘗試在run()方法Handler創建的線程。你會得到一個RuntimeException說法:

無法創建內螺紋處理程序尚未調用 Looper.prepare()

現在呼籲Looper.prepare()在run()方法創建Handler將創建前與調用線程相關聯的新的Looper對象。你的困惑的根源在於Looper.prepare()不以Thread作爲參數。它不需要,因爲它是一個靜態方法,它在內部獲取當前正在運行的線程的ThreadLocal。最多可以有一個Looper與任何Thread相關聯。現在

,呼籲new Handler()將通過內部調用Looper.myLooper()當前ThreadLooperHandler對象相關聯。您可以在同一個線程中創建多個Handler,每個都有自己的回調。所有處理程序將從相同的Looper的消息隊列中獲取它們的消息。

相關問題