Android源碼分析之Handler

來源:互聯網
上載者:User

  接上一篇分析,正如Android doc所說,Handler主要有2方面用處:

1. delay執行同一線程中的某個操作,也就是schedule message、runnable在未來的某一時刻執行;

2. 給另外一個線程發送message、runnable,讓某個操作在另一個線程中執行。比如A線程只要能拿到B線程的

handler就能通過此handler在A線程中通過post message、runnable,讓這些訊息的處理髮生在B線程中,從而實現

線程間的通訊。AsyncTask就是通過在background線程中通過關聯UI線程的handler來向UI線程發送訊息的。為了看的

更清楚些,這裡摘抄下Looper.java開頭處給的一個典型例子:

LooperThread = View Code

在這裡,別的線程可以通過LooperThread.mHandler來實現和它的通訊。

  接下來一點點分析源碼,先看幾個相關的:

(msg.callback != (mCallback != View Code

這個Callback介面裡只有一個handleMessage方法返回boolean值,在後面Handler的ctor會用到,一般情況下都是null。這個介面的存在

沒什麼特殊的含義,只是為了讓你不extends Handler就能處理訊息而已(正如此方法的doc所說),類似Thread和Runnable介面的關係。

接下來是dispatchMessage方法,我們已經在上一篇分析Message的時候大概提到了。它的處理是如果message自身設定了callback,則

直接調用callback.run()方法,否則Callback介面的作用就顯現了;如果我們傳遞了Callback介面的實現,即mCallback非空,則調用它處理

message,如果處理了(consumed)則直接返回,否則接著調用Handler自己的handleMessage方法,其預設實現是do nothing,如果你

是extends Handler,那麼你應該在你的子類中為handleMessage提供自己的實現。

  接下來我們首先看看Handler都有哪些關鍵的欄位,源碼如下:

  mAsynchronous;

mQueue來自mLooper,mLooper要麼是在ctor中顯式指定的要麼是預設當前線程的,Handler關於Message、Runnable的所有處理都delegate給了mQueue;mCallback是使用者提供的Callback實現,預設是null;mAsynchronous表示Handler是否是非同步,預設是同步的。

  接下來我們來看各種各樣的Handler的ctor(構造器):

(, (callback, (looper, , (looper, callback, Handler(( Handler(Callback callback, Class<? Handler> klass = ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&& Modifier.STATIC) == 0"The following Handler class should be static or leaks might occur: " += (mLooper == "Can't create handler inside thread that has not called Looper.prepare()"=== Handler(Looper looper, Callback callback, ====View Code

我們來看3個參數的版本,即Looper,Callback,boolean,預設looper是關聯的當前線程的,callback是null,async是false。當然你願意也可以分別指定這3個值。關於ctor不需要贅述,看doc、comment就可以很容易理解。

  接下來是一堆Handler的obtainMessage函數,其實現都是直接調用Message的靜態函數obtain,但相應的message的target欄位都自動被設定成了當前的Handler對象。由於Message的源碼已在上一篇中分析過了,這裡一帶而過。

  getPostMessage(Runnable r)之類的也很簡單,就是將runnable封裝成一個Message,其callback欄位被設定成了runnable。

  接下來的一堆postxxx、sendxxx,最終會調用下面這個方法:

  enqueueMessage(MessageQueue queue, Message msg, = 

在這裡,message的target被設定成當前的Handler,如果是非同步Handler,則設定message也為非同步,然後入隊,uptimeMillis表示絕對時間戳記。這裡需要提一下的是xxxAtFrontOfQueue方法,這個方法因為每次是將後來的message插在隊列的前頭,所以可能導致隊列中的其他訊息沒機會得到處理(即饑餓),或得不到及時處理,所以說插隊是不好的,慎用。正如其方法doc中所說,其實在我們的工作學習中,我也強烈推薦大家仔細看看相關類、方法的doc。我知道我們這類人都不喜歡寫doc,所以既然能有doc那說明真的是必不可少的,挺重要的。

  接下來是removeCallbacks相關的,源碼:

      , r,       

其實現也都是delegate給了mQueue,有一點需要注意下就是這些方法會remove掉所有的Runnable r,而不是第一個匹配的

(注意方法名中的s,是複數而不是單數),也就是說一次remove調用可以remove掉之前好多次post的同一個runnable,

如果之前post的runnable還在隊列中的話。

  removeMessages、hasMessages之類的方法挺簡單不過多解釋。

  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.