很少廢話, 上圖:java
簡單來講handler流程就是handler 在消息池中獲取msg 併發送給 MQ, 再由Looper進行輪詢在MQ中獲得待處理的msg交由handler進行 handleMessage(...);c++
這裏主要涉及到了四個核心類: Message Handler MessageQueue Looper併發
那麼下面來看看源碼裏面是怎麼實現的:ide
1.
oop
Message類: 用來攜帶數據的載體ui
public int what; //標識this
public int arg1; //攜帶int類型數據spa
public int arg2; //攜帶int類型數據.net
public Object obj;//攜帶任意對象數據線程
long when; //保存要被處理的時間點
Handler target; //處理消息的handler
Runnable callback; //處理消息的回調器對象
Message next; //用來保存引用的下一個message(才能造成鏈表)
private static Message sPool; //存儲處理過的消息的池 //在須要Message對象時複用
其中還有recycle()方法 Looper輪詢過程當中中會用到
2.
Handler類: 進行消息的發送處理, 源碼裏面主要調用了以下幾個方法:
sendMessage(Message msg)
public final boolean sendMessage(Message msg) { return sendMessageDelayed(msg, 0);//那咱們再去看看另外一個方法 }
sendEmptyMessage(int what)
public final boolean sendEmptyMessage(int what) { return sendEmptyMessageDelayed(what, 0);//和上面的同樣 返回了一個延遲方法,那咱們去看看這個方法; }
sendMessageDelayed(Message msg, long delayMillis)
public final boolean sendMessageDelayed(Message msg, long delayMillis) { ... return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);//返回了atTime的方法,再繼續:
sendMessageAtTime(Message msg, long uptimeMillis)
public boolean sendMessageAtTime(Message msg, long uptimeMillis) { ... return enqueueMessage(queue, msg, uptimeMillis);//再去找這個方法 }
會發現全部的最後都是調用了這個方法:
sendMessageAtTime();//當前時間+延遲時間
而這個方法中調用了 enqueueMessage(),那麼咱們來看看這裏面到底實現了什麼東西:
//源碼
msg.target = this; if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis);
裏面是調用了MQ中的同名方法,下面就看看MessageQueue中主要的方法;
(handler中還有其餘的關鍵方法 dispatchMessage(), Looper中會用到)
3. MessageQueue:
看一看源碼中的enqueueMessage()方法;
boolean enqueueMessage(Message msg, long when) { ... msg.when = when; //將消息被處理的時間保存在msg上 //將msg對象保存到mMessages鏈表中一個合適的位置,msg會和mq中的msg的時間when進行比較, 當小於其中一個的時候會插入當前的位置; Message p = mMessages; boolean needWake; if (p == null || when == 0 || when < p.when) { msg.next = p; mMessages = msg; needWake = mBlocked; } else { needWake = mBlocked && p.target == null && msg.isAsynchronous(); Message prev; for (;;) { prev = p; p = p.next; if (p == null || when < p.when) { break; } if (needWake && p.isAsynchronous()) { needWake = false; } } msg.next = p; // invariant: p == prev.next prev.next = msg; } //調用c或c++喚醒處理等待狀態下的程序,防止阻塞 if (needWake) { nativeWake(mPtr); } } return true; }
能夠發現裏面主要作了三件事:
msg.when = when; //將消息被處理的時間保存在msg上
//將msg對象保存到mMessages鏈表中一個合適的位置
nativeWake(mPtr); //喚醒處理等待狀態下的程序
//不是經過wait()來實現的, 而是經過C/C++的代碼來實現的, 不會阻塞主線程
還有一個主要方法: next(), 很明顯就是進行查詢的,Looper中會用到
4. Looper:
其中主要有 loop()
static void loop() {
public static void loop() { final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; //拿到消息隊列 // Make sure the identity of this thread is that of the local process, // and keep track of what that identity token actually is. Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); for (;;) { Message msg = queue.next(); // 獲取到mq中的msg 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 Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } msg.target.dispatchMessage(msg); //調用msg中的target(Handler對象)的dispatch...(msg)方法 if (logging != null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); } // Make sure that during the course of dispatching the // identity of the thread wasn't corrupted. final long newIdent = Binder.clearCallingIdentity(); if (ident != newIdent) { Log.wtf(TAG, "Thread identity changed from 0x" + Long.toHexString(ident) + " to 0x" + Long.toHexString(newIdent) + " while dispatching to " + msg.target.getClass().getName() + " " + msg.callback + " what=" + msg.what); } msg.recycleUnchecked();//清除回收處理過的msg所攜帶數據和標識等,並將msg保存到消息池中 } }
能夠看到loop()裏面主要是調用了其餘三個類中的方法:
a. mq.next();從mq中獲取msg
b.handler.dispatchMessage(); handler進行分發消息 (源碼裏能夠看出 此方法中有三個優先級的回調,而咱們經常使用的是 handleMessage(). 其實第一級是msg.callBack, 第二級是 handler中的CallBack{},最後纔是handleMessage(),但通常狀況下前二者爲爲空,因此一般咱們直接處理handleMessage()方法,代碼以下
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
)
c.msg.recycleUnchecked(); 回收ms;
寫的很差,主要目的是給本身複習一下,想系統地瞭解請點擊以下連接: