Android學習筆記之訊息機制

來源:互聯網
上載者:User

標籤:

  Android的訊息機制主要是指Handler的運行機制以及Handler所附帶的MessageQueue和Looper的工作過程。 

  1.為什麼要使用Handler?

         Android規定訪問UI只能在主線程中進行,如果在子線程中訪問UI,則會拋出異常。同時Android建議不能在主線程中進行耗時的操作,不然會導致程式無法響應即ANR。因此耗時的工作只能交給子線程去做,而子線程卻不能直接存取UI,為瞭解決這個矛盾,Android提供了Handler。Handler的主要作用是將某個任務切換到某個指定的線程中去執行。例如,我們在主線程中建立Handler,在子線程執行完耗時任務後,就可以通過Handler將更新UI的操作切換到主線程中去執行。

  2.為什麼系統不允許在子線程中訪問UI?

        因為Android的UI控制項不是安全執行緒的,如果在多線程中並發訪問可能會導致UI控制項處於不可預期的狀態。

  3.Handler與MessageQueue,Looper

        Android的訊息機制主要是指Handler的運行機制,Handler的運行需要訊息佇列(MessageQueue)和訊息迴圈(Looper)的支撐。

       訊息佇列的內部儲存結構並不是真正的隊列,而是單鏈表。訊息佇列只是一個訊息的儲存單元,不能處理訊息,而Looper就是來處理訊息的。Looper會無限迴圈的去查看是否有訊息,如果有,就處理,否則一直等待。

     Handler建立時會採用當前線程的Looper來構造訊息迴圈系統,如果當前線程沒有Looper,則會報錯(有的時候,也可以通過建構函式指定一個Looper)。這個當前線程的Looper是通過ThreadLocal來擷取的。ThreadLocal並不是線程,它是線程內部的一個資料存放區類,通過它可以在指定線性中儲存資料和擷取資料。

  4.MessageQueue工作原理

         MessageQueue主要包含兩個操作:插入和讀取,分別對應enqueueMessage和next兩個方法。enQueueMessage是往訊息佇列中插入一條訊息,而next是從訊息佇列中取出一條訊息並將其從訊息佇列中刪除。前面說過,訊息佇列的內部實現是iyge單鏈表,它在插入和刪除上比較有優勢。

        這裡注意,next方法是一個無限迴圈的方法,如果訊息佇列中沒有訊息,那麼next方法會一直阻塞,當有新訊息到來時,它會返回這條訊息並將其從單鏈表中刪除。 

  5.Looper的工作原理

  (1)Looper會一直不停的從MessageQueue中查看是否有訊息,如果有,則會立刻處理,否則就一直阻塞。

     為當前信線程建立Looper的方法如下:

new Thead("Thread1"){  @override   public void run()  {    Looper.prepare();    Handler handler=new Handler();    Looper.loop();  }}

       注意,只有調用了Looper的loop方法後,訊息迴圈系統才真正起作用。

         loop方法會調用MessageQueue的next方法來擷取訊息,當沒有訊息時,next方法會阻塞,導致loop方法也會阻塞。Looper獲得訊息後,調用Handler對象的dispatchMessage方法,這個dispatchMessage方法是在建立Handler時所使用的Looper中執行的,這樣就就將代碼邏輯切換到指定的線程中去了。

         loop方法是一個死迴圈,唯一跳出迴圈的方式是MessageQueue的next方法返回null。當Looper的quit方法被調用時,它會調用MessageQueue的quit或者quitSafely方法來通知訊息隊列退出,當訊息佇列被標記為退出狀態時,其next方法就會返回null。

    (2)Looper也可以退出,主要的方法是quit和quitSafely。前者會直接退出Looper,而後者只是設定一個標記,然後把訊息佇列中的已有訊息處理完畢後才安全退出。Looper退出以後,Handler就無法再順利發送訊息了,其send方法會返回false。

    (3)在子線程中建立Looper後,當所有事情完成以後應該調用quit方法來終止訊息迴圈,否則這個子線程會一直處於等待狀態。

  6.Handler的工作原理

        Handler的主要工作是發送和接收訊息。訊息的發送通過post的方法和send的方法實現,post的方法最終是通過send的方法實現的。

        Handler發送訊息僅僅是向訊息佇列中插入一條訊息,然後MessageQueue的next方法將訊息給Looper處理,最終Looper將訊息交給Handler處理,即Handler的dispatchMessage方法被調用。

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

if(mCallback.handleMessage(msg))
{
return;
               }
}
handleMessage(msg);
}
}

     這裡msg.callback對象其實就是一個Runnable對象,就是Handler的post方法所傳遞的Runnable參數。

     mCallback對應的類實現的是Callback介面。當我們不想派生Handler的子類並重寫其handleMessage方法時,可以通過Callback來實現。

 

Android學習筆記之訊息機制

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.