Android的Handler類應該是常用到的,多用於線程間的通訊,以及子線程發送訊息通知UI線程重新整理View等等。這裡我主要總結下我對整個訊息傳遞機制,包括Handler,Looper,Message,MessageQueue類的理解。
Looper類:每一個線程都只能擁有一個Looper對象,這裡Android是通過將Looper對象設定為當前線程的線程局部變數(這裡涉及到ThreadLocal類),可以通過調用Looper.prepare()方法來使當前線程擁有一個Looper對象(主線程不用調用,因為主線程本身已經是擁有Looper對象了)。這裡貼出prepare()的源碼
prepare( (sThreadLocal.get() != RuntimeException("Only one Looper may be created per thread"); Looper(quitAllowed));
而Looper類的主要作用是進行訊息迴圈,Looper類維護了一個MesageQueue,通過不停調用loop()方法來取出MeesageQueue中的Message並進行相應的處理。
Looper me = myLooper(); (me == RuntimeException("No Looper; Looper.prepare() wasn't called on this thread." MessageQueue queue = ident = = queue.next(); (msg == Printer logging = (logging != ">>>>> Dispatching to " + msg.target + " " ++ ": " + (logging != "<<<<< Finished to " + msg.target + " " + newIdent = (ident !="Thread identity changed from 0x" + Long.toHexString(ident) + " to 0x" + Long.toHexString(newIdent) + " while dispatching to " + msg.target.getClass().getName() + " " + msg.callback + " what=" +
這個留意到loop()方法裡對Message的處理方式是調用msg.target.dispatchMessage(msg);,關於這個方法,我們瞭解完Handler後再看。
MeesageQueue:Message隊列,隊列就不詳解了,先進先出。
Handler:Handler的作用主要是分發資訊 相關方法有:
post(Runnable)
postAtTime(Runnable,long)
postDelayed(Runnable long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
sendMessageDelayed(msg, 0 sendEmptyMessage( sendEmptyMessageDelayed(what, 0 sendEmptyMessageDelayed( what, == sendEmptyMessageAtTime( what, == sendMessageDelayed(Message msg, (delayMillis < 0= 0 sendMessageAtTime(msg, SystemClock.uptimeMillis() + sendMessageAtTime(Message msg, = (queue == = + " sendMessageAtTime() called with no mQueue""Looper"
發現這些方法最後都是調用enqueueMessage(),看看這個方法的源碼
enqueueMessage(MessageQueue queue, Message msg, =
調用了MessageQueue的enqueueMessage方法,將Message對象加入了隊列中去
再看看這幾個方法
sendMessageDelayed(getPostMessage(r), 0 postAtTime(Runnable r, postAtTime(Runnable r, Object token, postDelayed(Runnable r,
發現post()系列的方法最後都是調用sendMessage系列的方法只是傳入的Message對象有所不同,我們再看看getPostMessage()
== ===
發現其實就是把Runnable對象賦給Message的callback。通過以上代碼的分析,基本上對整個訊息機制有個概念了,當我們調用Handler的sendMessage()或post()等一系列方法時,Handler會將訊息加入到MessageQueue中,這個MessageQueue為Handler對應的Looper對象所維護的queue(建立Handler時可以傳入Looper對象,無參情況下為當前線程的Looper,想具體瞭解可以看下Handler的建構函式,這裡不再贅述)然後由Looper類的loop()方法將訊息取出。並做處理。至於怎麼處理,我們就要看下msg.target.dispatchMessage(msg)這個方法了。我們知道msg的target是一個Handler對象,看下這個方法的源碼
(msg.callback != (mCallback !=
handleMessge()方法想必大家都很熟悉,這個方法是我們new一個Handler對象時常常會去重寫的,然後處理訊息時會回調這個方法。再看看handleCallback()
代碼很簡單,就是調用了callback的run()方法。這裡要特別注意的是調用的是run()而不是start(),這意味著將不會另起一個線程。而是在Looper對象所在的線程執行。至於為什麼這麼做筆者認為由於這樣做即使是多次post也不需要開啟多個線程,大大提高了程式的效能,同時,在某些情況下,我們希望能夠順序執行callback,那麼使用這個方法無疑是非常棒的。當然,如果是要並發執行作那麼就得使用其他法子了。總的來說post()方法相當於sendMessage()+handleMessage()使用方式的一種變體。