Handler原理淺析

來源:互聯網
上載者:User

標籤:android   handler   looper   threadlocal   

    理解Handler的原理首先要搞清楚什麼是Looper,在我的上一篇博文中對此有專門的介紹。Looper的作用是開啟一個訊息迴圈,從MessageQueue(Message隊列,是Looper的成員變數)中迴圈取出訊息處理。一個線程要使用Handler來處理來自其它線程的訊息,這個線程必須有且僅有一個Looper對象與之綁定,也可以說一個Looper對象是是與一個線程一一對應的。

    Hander有一個Looper類型的成員,在Handler的建構函式(new Handler()或者new Handler(CallBack))中會執行個體化這個Handler的Looper成員,Handler()建構函式的源碼如下:

public Handler() {        //獲得當前線程在 ThreadLocal 中所對應的 Looper        mLooper = Looper.myLooper();        if (mLooper == null) {            throw new RuntimeException(                "Can‘t create handler inside thread that has not called Looper.prepare()"               );        }        mQueue = mLooper.mQueue;        mCallback = null;}

 在Handler建構函式中執行個體化的Looper不是通過new關鍵字來執行個體化的,而是從Looper.myLooper()這個靜態方法中取得的。而Looper.myLooper()又是從哪來取得的Looper對象呢?這就涉及到另外一個類ThreadLocal。Looper有一個靜態變數是ThreadLocal類型的:

static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); 

 這個變數就是儲存每一個線程和這個線程對應的Looper。這樣設計的作用是保證每一個線程的Looper是唯一的。

每一個線程在new Handler()之前必須為這個線程建立Looper對象,使用Looper.prepare()方法建立。

Looper.prepare的源碼如下:

public static void prepare() {        //調用此方法的線程是否在 全域變數 sThreadLocal(即Map<Thread,Looper>)中存有一組以此線程為鍵的索引值對        if (sThreadLocal.get() != null) {            throw new RuntimeException("Only one Looper may be created per thread");        }        //如果在Map<Thread,Looper>中沒有存放當前線程對應的索引值對當存入        // 一個 set 操作,其實就是在 Map 中插入了一組 <Thread,Looper>值,即 <調用此方法的線程,new Looper()>        // new Looper() 時,Looper的建構函式就會執行個體化一個 MessageQueue       &nbsp;sThreadLocal.set(new Looper());

關鍵是sThreadLocal.set(new Looper());這條語句,它會把new 出來的Looper儲存到ThreadLocal這個全域變數中。

有一個問題,就是為什麼我們在主線程中new Handler(){...}之前不需要使用Looper.prepare()呢?因為在主線程執行之前,android虛擬機器已經幫我們執行了這段代碼,因此在主線程中建立Handler對象不需要再建立Looper對象。建立了Handler之後,還要使用Looper.loop()開啟訊息迴圈來取訊息。主線程也不需要這句代碼。

總結:

Looper負責開啟訊息迴圈,從MessageQueue中讀取Message,由Handler負責處理讀出來的Message。

Looper和它的MessageQueue與某一個線程是一一對應的。

使用Handler之前需要使用Looper.prepare()為當前線程建立Looper對象。

使用Looper.loop()開啟訊息迴圈。

本文出自 “Focus_000” 部落格,請務必保留此出處http://120806872.blog.51cto.com/8289253/1432137

相關文章

聯繫我們

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