Android異步消息處理架構,其實沒那麼複雜。簡單來講就是looper
對象擁有messagequeue
,而且負責從messagequeue
中取出消息給handler
來處理。同時handler
又負責發送message
給looper
,由looper
把message
添加到messagequeue
尾部。就一個圈兒。下面給出圖解:android
因此很明顯handler
和looper
是來聯繫在一塊兒的。須要說明的是,多個message
能夠指向同一個handler
,多個handler
也能夠指向同一個looper
。還有一點很重要,普通的線程是沒有looper
的,若是須要looper
對象,那麼必需要先調用Looper.prepare()
方法,並且一個線程只能有一個looper
。調用完之後,此線程就成爲了所謂的LooperThread
,若在當前LooperThread
中建立Handler
對象,那麼此Handler
會自動關聯到當前線程的looper
對象,也就是擁有looper
的引用。網絡
Looper
就是一個管理messagequeue
的類。下面是這個類的源碼。架構
public class Looper { ...... private static final ThreadLocal sThreadLocal = new ThreadLocal(); final MessageQueue mQueue;//擁有的消息隊列 ...... /** * Initialize the current thread as a looper. * This gives you a chance to create handlers that then reference * this looper, before actually starting the loop. Be sure to call * {@link #loop()} after calling this method, and end it by calling * {@link #quit()}. */ //建立新的looper對象,並設置到當前線程中 public static final void prepare() { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper()); } ····· /** * Return the Looper object associated with the current thread. Returns * null if the calling thread is not associated with a Looper. */ //獲取當前線程的looper對象 public static final Looper myLooper() { return (Looper) sThreadLocal.get(); } private Looper() { mQueue = new MessageQueue(); mRun = true; mThread = Thread.currentThread(); } ...... }
調用完Looper.prepare()
以後,在當前的線程建立的Handler
才能擁有當前線程的looper
。而後調用loop()
來開啓循環,處理message
。下面是Looper類下的loop方法部分源碼:less
public static void loop() { final Looper me = myLooper();//獲取looper對象 if (me == null) { //若爲空則說明當前線程不是LooperThread,拋出異常 throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; 獲取消息隊列 ..... for (; ; ) { //死循環不斷取出消息 Message msg = queue.next(); // might block (可能會阻塞) if (msg == null) { // No message indicates that the message queue is quitting. //沒有消息代表消息隊列退出了 return; } // This must be in a local variable, in case a UI event sets the logger //打印log,說明開始處理message。msg.target就是Handler對象 Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } //重點!!!開始處理message,msg.target就是Handler對象 msg.target.dispatchMessage(msg);//dispatchMessage:發送消息 //打印log,處理message結束 if (logging != null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); } ..... } }
是一個大的循環,不斷從消息隊列出取出消息。而後調用一個很關鍵的方法msg.target.dispatchMessage(msg)
開始處理消息。msg.target
就是message
對應的handler
。looper
對象管理MessageQueue
,從中取出message
分配給對應的handler
來處理。異步
Message
就是一些須要處理的事件,好比訪問網絡、下載圖片、更新ui界面什麼的。Message
擁有幾個比較重要的屬性。async
public int what 標識符,用來識別message
ide
public int arg1,arg2 能夠用來傳遞一些輕量型數據如int之類的函數
public Object obj Message
自帶的Object類字段,用來傳遞對象oop
Handler target 指代此message
對象對應的Handler
post
若是攜帶比價複雜性的數據,建議用Bundle
封裝,值得注意的地方是,雖然Message
的構造方法是公有的,可是不建議使用。最好的方法是使用Message.obtain()
或者Handler.obtainMessage()
能更好的利用循環池中的對象。通常不用手動設置target
,調用Handler.obtainMessage()
方法會自動的設置Message
的target
爲當前的Handler
。獲得Message
以後能夠調用sendToTarget()
,發送消息給Handler
,Handler
再把消息放到messagequeue
的尾部。這個方法的源碼以下:
/** * Sends this Message to the Handler specified by {@link #getTarget}. * Throws a null pointer exception if this field has not been set. */ public void sendToTarget() { target.sendMessage(this);//此處的target是message對應的Handler. }
它的構造函數以下:
/** * Default constructor associates this handler with the {@link Looper} for the * current thread. * * If this thread does not have a looper, this handler won't be able to receive messages * so an exception is thrown. */ public Handler() { this(null, false); } /** * Constructor associates this handler with the {@link Looper} for the * current thread and takes a callback interface in which you can handle * messages. * * If this thread does not have a looper, this handler won't be able to receive messages * so an exception is thrown. * * @param callback The callback interface in which to handle messages, or null. */ public Handler(Callback callback) { this(callback, false); } /** * Use the provided {@link Looper} instead of the default one. * * @param looper The looper, must not be null. */ public Handler(Looper looper) { this(looper, null, false); } /** * Use the provided {@link Looper} instead of the default one and take a callback * interface in which to handle messages. * * @param looper The looper, must not be null. * @param callback The callback interface in which to handle messages, or null. */ public Handler(Looper looper, Callback callback) { this(looper, callback, false); } /** * Use the {@link Looper} for the current thread * and set whether the handler should be asynchronous. * * Handlers are synchronous by default unless this constructor is used to make * one that is strictly asynchronous. * * Asynchronous messages represent interrupts or events that do not require global ordering * with respect to synchronous messages. Asynchronous messages are not subject to * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}. * * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for * each {@link Message} that is sent to it or {@link Runnable} that is posted to it. * * @hide */ public Handler(boolean async) { this(null, async); } /** * Use the {@link Looper} for the current thread with the specified callback interface * and set whether the handler should be asynchronous. * * Handlers are synchronous by default unless this constructor is used to make * one that is strictly asynchronous. * * Asynchronous messages represent interrupts or events that do not require global ordering * with respect to synchronous messages. Asynchronous messages are not subject to * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}. * * @param callback The callback interface in which to handle messages, or null. * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for * each {@link Message} that is sent to it or {@link Runnable} that is posted to it. * * @hide */ public Handler(Callback callback, boolean async) { if (FIND_POTENTIAL_LEAKS) { final Class<? extends Handler> klass = getClass(); if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && (klass.getModifiers() & Modifier.STATIC) == 0) { Log.w(TAG, "The following Handler class should be static or leaks might occur: " + klass.getCanonicalName()); } } mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; } /** * Use the provided {@link Looper} instead of the default one and take a callback * interface in which to handle messages. Also set whether the handler * should be asynchronous. * * Handlers are synchronous by default unless this constructor is used to make * one that is strictly asynchronous. * * Asynchronous messages represent interrupts or events that do not require global ordering * with respect to synchronous messages. Asynchronous messages are not subject to * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}. * * @param looper The looper, must not be null. * @param callback The callback interface in which to handle messages, or null. * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for * each {@link Message} that is sent to it or {@link Runnable} that is posted to it. * * @hide */ public Handler(Looper looper, Callback callback, boolean async) { mLooper = looper; //由此可知,它擁有對象,以及的 mQueue = looper.mQueue; mCallback = callback; mAsynchronous = async; }looperloopermessagequeue
要經過Handler
來處理事件,能夠重寫handleMessage(Message msg)
,也能夠直接經過post(Runnable r)
來處理。這兩個方法都會在looper循環中被調用。
loop循環中處理信息的msg.target.dispatchMessage(msg)
方法源碼:
public void dispatchMessage(Message msg) { //注意!這裏先判斷message的callback是否爲空,不然就直接處理message的回調函數if (msg.callback!= null) { //這裏的callback就是上面的Runnable handleCallback(msg); } else { if (mCallback != null) { //正是在這調用咱們日常重寫handleMessage if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
首先判斷是否用的是handler的post方法,若是是就執行r裏面run()方法的代碼,不然就判斷handler的構造函數是否初始化了CallBack,是的話就會執行這個接口裏面handleMessage(msg)方法,;若是放回的是false,最後就會調用handleMessage(msg)(創建handler時重寫的方法,若是沒有重寫,就什麼都不會執行)。下面是handler的post方法的源碼:
/**
* Causes the Runnable r to be added to the message queue.
* The runnable will be run on the thread to which this handler is
* attached.
*
* @param r The Runnable that will be executed.
*
* @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);//發送消息
}
上面源碼中getPostMessage(r)方法的源碼:
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r; //就是上面的msg.callback,若是調用了handler的post方法,它就會不爲空。
return m;
}
上面的 if (msg.callback!= null) { //這裏的callback就是上面的Runnable handleCallback(msg); }的handleCallback(msg)源碼:(就是運行run方法裏面的代碼)
private static void handleCallback(Message message) {
message.callback.run();
}
而 if (mCallback.handleMessage(msg)) { return; }中的handleMessage(msg)源碼以下:
/**
* Callback interface you can use when instantiating a Handler to avoid
* having to implement your own subclass of Handler.
*
* @param msg A {@link android.os.Message Message} object
* @return True if no further handling is desired
*/
public interface Callback {
public boolean handleMessage(Message msg);
}
因此如今知道loop循環中處理信息的msg.target.dispatchMessage(msg)
方法裏面的代碼了吧。