標籤:
我們的經常使用的系統中。程式的工作一般是有事件驅動和訊息驅動兩種方式,在Android系統中,Java應用程式是靠訊息驅動來工作的。
訊息驅動的原理就是:
1. 有一個訊息佇列。能夠往這個隊列中投遞訊息;
2. 有一個訊息迴圈。不斷從訊息佇列中取出訊息。然後進行處理。
在Android中通過Looper來封裝訊息迴圈。同一時候在當中封裝了一個訊息佇列MessageQueue。
另外Android給我們提供了一個封裝類。來運行訊息的投遞,訊息的處理。即Handler。
<!--more-->
在我們的線程中實現訊息迴圈時。須要建立Looper,如:
class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); //1.調用prepare ...... Looper.loop(); //2.進入訊息迴圈 }}
看上面的代碼。事實上就是先準備Looper,然後進入訊息迴圈。
1. 在prepare的時候。建立一個Looper,同一時候在Looper的構造方法中建立一個訊息佇列MessageQueue。同一時候將Looper儲存到TLV中(這個是關於ThreadLocal的,不太懂。以後研究了再說)
2. 調用loop進入訊息迴圈。此處事實上就是不斷到MessageQueue中取訊息Message,進行處理。
然後再看我們怎樣藉助Handler來發訊息到隊列和處理訊息
Handler的成員(非所有):
final MessageQueue mQueue; final Looper mLooper; final Callback mCallback;
Message的成員(非所有):
Handler target; Runnable callback;
能夠看到Handler的成員包括Looper,通過查看源碼,我們能夠發現這個Looper是有兩種方式獲得的。1是在建構函式傳進來。2是使用當前線程的Looper(假設當前線程無Looper。則會報錯。我們在Activity中建立Handler不須要傳Handler是由於Activity本身已經有一個Looper了),MessageQueue也就是Looper中的訊息佇列。
然後我們看怎麼向訊息佇列發送訊息,Handler有非常多方法發送隊列(這個自己能夠去查),比方我們看sendMessageDelayed(Message msg, long delayMillis)
public final boolean sendMessageDelayed(Message msg, long delayMillis) { if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); // SystemClock.uptimeMillis() 擷取開機到如今的時間 } //終於全部的訊息是通過這個發,uptimeMillis是絕對時間(從開機那一秒算起)public boolean sendMessageAtTime(Message msg, long uptimeMillis) { boolean sent = false; MessageQueue queue = mQueue; if (queue != null) { msg.target = this; sent = queue.enqueueMessage(msg, uptimeMillis); } return sent; }
看上面的的代碼。能夠看到Handler將自己設為Message的target,然後然後將msg放到隊列中。而且指定已耗用時間。
訊息處理
處理訊息,即Looper從MessageQueue中取出隊列後,調用msg.target的dispatchMessage方法進行處理。此時會依照訊息處理的優先順序來處理:
1. 若msg本身有callback。則交其處理;
2. 若Handler有全域callback,則交由其處理;
3. 以上兩種都沒有。則交給Handler子類實現的handleMessage處理,此時須要重載handleMessage。
我們通常採用第三種方式進行處理。
注意!
!!
!我們通常是採用多線程。當建立Handler時,LooperThread中可能還未完畢Looper的建立,此時。Handler中無Looper。操作會報錯。
我們能夠採用Android為我們提供的HandlerThread來解決。該類已經建立了Looper,而且通過wait/notifyAll來避免錯誤的發生,降低我們反覆造車的事情。
我們建立該對象後,調用getLooper()就可以獲得Looper(Looper未建立時會等待)。
補充
本文所屬為Android中java層的訊息迴圈機制,其在Native層還有訊息迴圈。有單獨的Looper。而且2.3以後MessageQueue的核心向Native層下移,native層java層均能夠使用。
這個我沒有過多的研究了!
哈哈
PS:本文參考《深入理解Android:卷I》
原文地址:http://blog.isming.me/blog/2014/04/02/android-message-loop-analyze/ ,轉載請註明出處。
Android訊息迴圈分析