Handler Looper源碼解析(Android訊息傳遞機制)

來源:互聯網
上載者:User

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()使用方式的一種變體。

聯繫我們

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