總結(jié)
其中綠色的部分與藍(lán)色可能在一個(gè)線程钉汗,也可能不在一個(gè)線程
-
初始化handler時(shí)依溯,指定了對(duì)應(yīng)的Looper以及消息隊(duì)列MessageQueue
public Handler(Callback callback, boolean async) { //可能的內(nèi)存泄露 //所以盡可能用static 的handler,用弱引用引用外部類 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()); } } //所以必須在一個(gè)調(diào)用了Looper.prepare()的線程中初始化handler //android的主線程在啟動(dòng)是就已經(jīng)調(diào)用過了 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; }
-
在主線程或工作線程中滤愕,將要傳遞的數(shù)據(jù)或者要執(zhí)行的Runable包裝成一個(gè)Message對(duì)象茎刚,然后Handler將這個(gè)Message對(duì)象加到主線程的消息隊(duì)列中
//Handler 代碼 public boolean sendMessageAtTime(Message msg, long uptimeMillis) { MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); return false; } return enqueueMessage(queue, msg, uptimeMillis); }
-
Message除了包含必要的信息外堤如,還有一個(gè)target,這個(gè)target就是這個(gè)Handler對(duì)象本身
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { //指定了消息處理者target,也就是handler本身 msg.target = this; if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }
-
Looper不斷的從消息隊(duì)列中取出消息忽媒,然后調(diào)用消息的target去分發(fā)消息争拐,也就是調(diào)用Handler去處理消息,處理完后晦雨,將Message放到Message對(duì)象池中架曹,循環(huán)使用
//Looper代碼 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(); // 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 final Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } final long traceTag = me.mTraceTag; if (traceTag != 0) { Trace.traceBegin(traceTag, msg.target.getTraceName(msg)); } try { //取出消息,然后調(diào)用target去處理消息闹瞧,實(shí)際也就是handler去處理消息 msg.target.dispatchMessage(msg); } finally { if (traceTag != 0) { Trace.traceEnd(traceTag); } } 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(); } }
-
handler處理分發(fā)消息
public void dispatchMessage(Message msg) { //如果消息的callback不為null,實(shí)際上就是這個(gè)消息是包裝了一個(gè)Runable //就去執(zhí)行這個(gè)Runable if (msg.callback != null) { handleCallback(msg); } else { //如果handler的callback不為空音瓷,并且返回true,表示處理了消息夹抗,就結(jié)束了 //否則就由自身的handleMessage函數(shù)去處理 //handler的callback主要目的是不用重載函數(shù),只用傳入一個(gè)callback對(duì)象就行 if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
-