1. 程式人生 > >Android 多執行緒-----Handler、Thread、HandlerThread的區別和使用

Android 多執行緒-----Handler、Thread、HandlerThread的區別和使用

一、他們的區別


      ①Handler:在android中負責傳送和處理訊息,通過它可以實現其他支線執行緒與主執行緒之間的訊息通訊。

      ②Thread:Java程序中執行運算的最小單位,亦即執行處理機排程的基本單位。某一程序中一路單獨執行的程式。

      ③HandlerThread:一個繼承自Thread的類HandlerThread,Android中沒有對Java中的Thread進行任何封裝,而是提供了一個繼承自Thread的類HandlerThread類,這個類對Java的Thread做了很多便利的封裝

      A:那麼HandlerThread到底有什麼作用,所謂的便利封裝又體現在哪裡?

      B:HandlerThread物件start後可以獲得其Looper物件,並且使用這個Looper物件例項Handler,之後Handler就可以執行在其他執行緒中了。     

      C:Andriod提供了 Handler  和  Looper  來滿足執行緒間的通訊。 Handler 先進先出原則。 Looper 類用來管理特定執行緒內物件之間的訊息交換 (MessageExchange) 。 

  D:HandlerThread最大的優勢在於引入MessageQueue概念,可以進行多工佇列管理。

  E:HandlerThread背後只有一個執行緒,所以任務是序列依次執行的。序列相對於並行來說更安全,各任務之間不會存在多執行緒安全問題。

  F:HandlerThread所產生的執行緒會一直存活,Looper會在該執行緒中持續的檢查MessageQueue,並開啟訊息處理的迴圈。這一點和Thread(),AsyncTask都不同,thread例項的重用可以避免執行緒相關的物件的頻繁重建和銷燬。 getLooper().quit();來退出這個執行緒,其實原理很簡單,就是改變在訊息迴圈裡面標誌位,退出整個while迴圈,使執行緒執行完畢。

1)Looper:   是android為執行緒間非同步訊息通訊提供的一種機制,利用Looper機制可以方便我們實現多執行緒程式設計時執行緒間的相互溝通。如果不用Looper而採用其它的執行緒間通訊方式(像管道,共享記憶體,訊息佇列等)也是一樣的。Looper的實現是利用訊息佇列的方式,為使用者封裝了一層API,使用者不需要考慮互斥加鎖的問題,方便使用者的使用。一個執行緒可以產生一個 Looper 物件,由它來管理此執行緒裡的 MessageQueue( 訊息佇列 ) 和對訊息進行迴圈。 

2)Handler:  你可以構造 Handler 物件來與 Looper 溝通,以便 push 新訊息到 MessageQueue 裡 ; 或者接收 Looper 從 Message Queue 取出 所送來的訊息。 

3) Message Queue( 訊息佇列 ): 用來存放執行緒放入的訊息。 

4) Message:是執行緒間通訊的訊息載體。兩個碼頭之間運輸貨物,Message充當集裝箱的功能,裡面可以存放任何你想傳遞的訊息。

      看到這裡就明白了為什麼:如果一個執行緒要處理訊息,那麼它必須擁有自己的Looper,並不是Handler在哪裡建立,就可以在哪裡處理訊息。

注:對應關係Thread(1):Looper(1):MessageQueen(1):Handler(n).

二、HandlerThread的使用


      正如前面所說,執行緒間通訊的時候,比如Android中常見的更新UI,涉及到的是子執行緒和主執行緒之間的通訊,實現方式就是Handler+Looper,但是要自己手動操作Looper,不推薦,所以谷歌封裝了HandlerThread類(類似於AsyncTask類)。

上程式碼,具體實現:

①首先新建HandlerThread並且執行start()

private HandlerThread mHandlerThread;

......

mHandlerThread = new HandlerThread("HandlerThread");

handlerThread.start();

②建立Handler,使用mHandlerThread.getLooper()生成Looper:

final Handler handler = new Handler(mHandlerThread.getLooper()){

            @Override

            public void handleMessage(Message msg) {

                System.out.println("收到訊息");

            }

        };

③mHandlerThread.getLooper().quit();

從上面程式碼可以看出,HandlerThread繼承於Thread,所以它本質就是個Thread。與普通Thread的差別就在於,然後在內部直接實現了Looper的實現,這是Handler訊息機制必不可少的。有了自己的looper,可以讓我們在自己的執行緒中分發和處理訊息。如果不用HandlerThread的話,需要手動去呼叫Looper.prepare()和Looper.loop()這些方法。