Handler原理淺析

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

10年積累的網(wǎng)站建設、網(wǎng)站設計經(jīng)驗,可以快速應對客戶對網(wǎng)站的新想法和需求。提供各種問題對應的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡服務。我雖然不認識你,你也不認識我。但先網(wǎng)站設計后付款的網(wǎng)站建設流程,更有鹽邊免費網(wǎng)站建設讓你可以放心的選擇與我們合作。

    Hander有一個Looper類型的成員,在Handler的構造函數(shù)(new Handler()或者new Handler(CallBack))中會實例化這個Handler的Looper成員,Handler()構造函數(shù)的源碼如下:

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構造函數(shù)中實例化的Looper不是通過new關鍵字來實例化的,而是從Looper.myLooper()這個靜態(tài)方法中取得的。而Looper.myLooper()又是從哪來取得的Looper對象呢?這就涉及到另外一個類ThreadLocal。Looper有一個靜態(tài)變量是ThreadLocal類型的:

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

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

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

Looper.prepare的源碼如下:

public static void prepare() {

        //調(diào)用此方法的線程是否在 全局變量 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>值,即 <調(diào)用此方法的線程,new Looper()>

        // new Looper() 時,Looper的構造函數(shù)就會實例化一個 MessageQueue

       &nbsp;sThreadLocal.set(new Looper());

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

有一個問題,就是為什么我們在主線程中new Handler(){...}之前不需要使用Looper.prepare()呢?因為在主線程執(zhí)行之前,android虛擬機已經(jīng)幫我們執(zhí)行了這段代碼,因此在主線程中創(chuàng)建Handler對象不需要再新建Looper對象。創(chuàng)建了Handler之后,還要使用Looper.loop()開啟消息循環(huán)來取消息。主線程也不需要這句代碼。

總結:

Looper負責開啟消息循環(huán),從MessageQueue中讀取Message,由Handler負責處理讀出來的Message。

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

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

使用Looper.loop()開啟消息循環(huán)。

網(wǎng)頁題目:Handler原理淺析
文章源于:http://bm7419.com/article30/gejeso.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供微信公眾號關鍵詞優(yōu)化標簽優(yōu)化、Google、虛擬主機網(wǎng)站設計公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設網(wǎng)站維護公司