Android開發實踐:由new Handler()說開去

來源:互聯網
上載者:User

標籤: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()說開去

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.