Android源碼分析之Message

來源:互聯網
上載者:User

  準備開始寫點東西,算是對自己閱讀源碼的一個記錄/筆記,也希望能對同樣感興趣的人有所協助,希望

能堅持下去,嘿嘿。

  在Android的開發中,我們經常用到Handler.postXXX方法,或者View.postXXX方法,用來在下一次looper

到來時執行。我是那樣的人,什麼事情最好能夠知道下內部實現機理是什麼,否則我在用它的時候可能會覺得不爽,

或者說不自然,不太願意去用。典型例子就是我始終不太願意用Android引入的SparseArray<E>,而是一直堅持

Java的HashMap<Key, Value>,直到我自己讀了SparseArray<E>的源碼,才開始放心大膽的使用。

  其實說來也巧,為什麼忽然決定寫這個,是有一天看到了類似這樣的代碼:

 Runnable mRunnable =          removeCallbacks(

第一直覺告訴我run方法裡的removeCallbacks(this);調用顯然是多餘的。通過通讀代碼發現的確是如此,因為任何Message

(即使post的是Runnable也會被封裝到Message裡)在被處理之前都已經從MessageQueue裡取出來了(delete掉了,所以用戶端

代碼大可不必有這樣的代碼)。這裡順便提下慎用View.removeCallbacks的傳回值,看源碼:

                                    (action !=               AttachInfo attachInfo =              (attachInfo !=                            Choreographer.CALLBACK_ANIMATION, action,              }                                    }

我們可以看到這個方法always返回true,所以不要基於它的傳回值做任何事情,還有它的傳回值的意義也需要格外留意下。

我在第一次看到這個方法時就自以為然的覺得傳回值肯定代表了Runnable action有沒有成功地從MessageQueue中移除,true代表成功

移除了,false代表移除失敗,呵呵,你想錯了。仔細看看方法的doc,人家說的是return true表示這個view可以讓它的Handler

去處理這件事情,並沒提及處理的結果,而且即使返回true的時候也不能說明Runnable就已經從MessageQueue中移除了,

比如說此時Runnable已經不在MessageQueue中了;其他情況都是返回false。這裡順便看眼View.postDelayed方法:

   postDelayed(Runnable action,           AttachInfo attachInfo =          (attachInfo !=                                        }

這裡不論是postDelayed還是removeCallbacks方法都首先檢查了自己的mAttachInfo,如果非空才delegate給attachInfo的Handler處理,所以

你盡量不要過早(mAttachInfo還沒初始化完畢)的調用這些方法,在早些版本的Android中runnable不會被執行,參考這個問題:

http://stackoverflow.com/questions/4083787/runnable-is-posted-successfully-but-not-run

我現在分析的是Android4.4的源碼,具體是怎樣,我現在家裡還沒法驗證,等周一到公司了驗證下,然後在update下,當然感興趣的同學可以在google中搜尋view post runnable not run或者自行驗證。不過依現在的代碼來看即使mAttachInfo是null,也會執行ViewRootImpl.getRunQueue().postDelayed(action, delayMillis); 所以可能在較新的平台上不是問題(有待考證)。目前我還沒來得及分析它的源碼(之後會寫的)。

  好了說了一大堆了,開始正題。作為開始我今天挑了一個最簡單的開始分析,嘿嘿,那就是Message.java檔案。

  其實說白了,Message就是一個資料類,持有data的。基本的資料欄位我就不介紹了,都能望文生義。看下幾個我覺得有必要的欄位:

                            Object sPoolSync =               sPoolSize = 0          MAX_POOL_SIZE = 50;

target是訊息的處理者,在以後Looper.loop()方法中Message被從MessageQueue取出來後會調用msg.target.dispatchMessage(msg);

callback是訊息要執行的動作action。這裡提前插播下Handler的dispatchMessage方法:

            (msg.callback !=           }               (mCallback !=                                                }

我們可以看到Handler在分發訊息的時候,Message自身的callback優先順序高,先被調用如果非空的話(callback的run方法直接被調用)。

next表示訊息佇列中的下一個Message,類似單鏈表的概念。

剩下的pool相關的欄位都是Message引入的重用(reuse)所要用到的變數,sPoolSync是對象鎖,因為Message.obtain方法會在任意

線程調用;sPool代表接下來要被重用的Message對象;sPoolSize表示有多少個可以被重用的對象;MAX_POOL_SIZE顯然是pool的上限,

這裡hardcode是50。這裡我要分析的就2個方法,

obtain和recycle,代碼如下:

                                      (sPool !=                  Message m =                 sPool =                 m.next =                  sPoolSize--                                                                        (sPoolSize <                 next =                 sPool =                  sPoolSize++       }

首先我們來看obtain方法,第一次調用也就是說沒有什麼東西可以重用,這時sPool是null,直接new一個Message對象返回,等到Message對象使用完畢(

在Looper.loop方法最後有msg.recycle();這樣的代碼),它的recycle會被調用,在recycle裡首先會調用clearForRecycle方法,它只是把各個欄位置空或清零。

接下來sPoolSize沒到上限,next儲存下sPool的舊值(也就是在當前Message回收利用之前上一個要被回收利用的對象),然後sPool被更新成新值,即當前Message,sPoolSize加1,表示又多了一個可以重用的Message對象。之後在等到obtain被調用的時候就不是直接return一個new Message了,因為我們已經有可以重用的Message對象了。將sPool的值設定給我們要返回的Message m對象,接著sPool被更新成上一個要被重用的Message對象(相比recycle是反向過程),最後設定m的next欄位為空白(m.next會在重新入隊列的時候被設定成合適的值),相應的sPoolSize減1,表示可重用的對象少了一個,最後返回重用的對象m。

  基於有這麼個回收再利用的機制,Android建議我們調用Message的obtain方法來獲得一個Message對象,而不是調用ctor,因為很可能會省掉分配一個新對象的開銷。

  Message類的分析就到這了,以後會陸續分析下常見於Android開發中的類。。。(由於本人水平有限,歡迎批評指正)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.