標籤:thread android handler looper 訊息迴圈
最近面試一些Android開發的應聘者,除了基本的Activity生命週期等基礎問題以外,我一般還會問如下兩個問題:
(1) Service與Thread有什麼區別?
(2) 在Activity裡new Handler()和在自己建立的Thread中new Handler()有什麼區別?
第一個問題其實是一個偽命令,因為Service是Android四大組件之一,而Thread只是Java提供的一個封裝了線程管理的工具類,無論是Activity還是Service,都可以通過Thread來建立一個背景工作執行緒,但是很多新手會搞不清楚它們之間的區別,藉此可以試探一下面試者到底有沒有很清楚地理解Android的Service到底是做什麼的。關於這個問題的答案,可以參考我的文章《Android開發實踐:使用Service還是Thread》。
第二個問題,涉及到Android開發必須掌握的知識點:Handler,本文就來從這個問題開始,說說我對Handler的理解。
當Android應用啟動後,系統會預設建立一個主線程(Main thread)。這個主線程啟動後,首先完成UI的繪製,然後會進入一個訊息迴圈(Loop),等待和執行各種來自系統的訊息和事件、各種使用者點擊/觸摸事件、其他線程發送的訊息事件等等。這是線程工作的一種常見的模式,即進入一種“等待命令”->“執行命令/訊息”->“等待命令/訊息”的迴圈。
那麼,其他非UI線程如何與進入了訊息迴圈的主線程互動呢?這就得靠Handler了。
Handler是Android系統為背景工作執行緒提供的一種可以與外界互動的介面,通過Handler提供的sendMessage()方法,外界可以發送各種訊息事件給背景工作執行緒。Handler通過建構函式完成與指定線程的綁定,其建構函式定義如下:
public Handler() { this(null, false);}public Handler(Looper looper) { this(looper, null, false);}public Handler(Looper looper, Callback callback) { this(looper, callback, false);}public interface Callback { public boolean handleMessage(Message msg);}
其中,Looper就是線程內部負責實現訊息迴圈的對象,普通的Java.Thread線程內部是沒有這樣一個訊息迴圈對象的,Android專門提供了HandlerThread封裝這種帶訊息迴圈機制的線程。Handler通過與線程的Looper對象綁定,來完成與該Thread的綁定。
Callback則是由背景工作執行緒內部傳出接收到的訊息的回調介面,其他線程通過Handler的sendMessage發送訊息給背景工作執行緒後,背景工作執行緒就會通過Callback將接收到的訊息通知給監聽者。
注意:預設情況下,如果new Handler()的時候,沒有傳入某個線程的Looper對象(或傳入null),系統就會預設綁定到建立Handler()對象的線程中。
那麼,現在可以回答第二個問題了,在Activity裡new Handler()和在自己建立的Thread中new Handler()有什麼區別?
答案:
Activiy預設是工作在主線程中的,所以在Activity中new Handler()後,該Handler對象預設綁定了主線程的Looper對象,因此該Handler.sendMessage訊息發送給了主線程,而且通過傳入Callback對象得到的handleMessage()回調也是工作在主線程,這就是為什麼可以通過在Activity裡使用如下方式更新UI而不會導致ANR了:
new Handler( new Handler.Callback() { @Override public boolean handleMessage(Message msg) { UpdateUI(); return false; }});
同理,如果在自訂線程中 new Handler(),則預設情況該Handler()綁定了該線程的Looper對象,因此該Handler.sendMessage訊息則是發送給了這個線程,而且通過傳入Callback對象得到的handleMessage()回調也是工作在這個線程,因此,這種情況下的handleMessage()函數中就不能進行UI更新操作了,否則會導致ANR了。
到此為止,這個問題算是回答清楚了,但是關於Handler的解釋還不夠盡興,比如線程的Looper到底是怎麼工作的?下一篇文章,我將用Java的Thread類,實現一個類似Looper的訊息迴圈,以便更好地顯示Android的訊息迴圈機制。本文有任何疑問或者不清楚的地方,歡迎留言或者來信[email protected]交流。
本文出自 “對影成三人” 部落格,請務必保留此出處http://ticktick.blog.51cto.com/823160/1564550
Android開發實踐:由new Handler()說開去