HandlerThread: HandlerThread的理解


 

Android為了方便對Thread和Handler進行封裝,也就是HandlerThread。HandlerThread繼承自Thread,說白了就是Thread加上一個Looper。源碼:

可以看到其本身便持有一個Looper對象。

之前學習的時候有兩個疑問:

1. HandlerThread為什么start完了之后不會退出?

一般我們都是在某個方法里(如onCreate)調用start方法來啟動HandlerThread:

mWorkThread = new HandlerThread("workThread");
mWorkThread.start();

那豈不是在調用完start方法之后就退出了?那這有什么意義,如果是一個普通的線程:

Thread thread = new Thread();
thread.start();

在調用完start()方法之后肯定會退出的。

查看HandlerThread源碼:

    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

當調用完start()方法后系統會自動調用run()方法,run方法里有一個 Looper.loop(); 

 

可以看到這個looper方法里有一個死循環,它也是跑在run方法里的,所以HandlerThread在start()完了之后不會立即退出。

2. Handler里的handlerMessage()方法究竟運行於哪個線程?

handlerMessage()方法究竟運行於哪個線程,得看這個方法在哪個線程里被調用,之前分析過handlerMessage是在Looper的loop()方法里輾轉被調用的。

Looper#loop()

 

 Handler#dispatchMessage()

 

那其實可以這樣說,Looper.loop()方法跑在哪個線程,handlerMessage就跑在哪個線程。

對於自定義的Thread+Looper方式:

  class LooperThread extends Thread {
      public Handler mHandler;

      public void run() {
          Looper.prepare();

          mHandler = new Handler() {
              public void handleMessage(Message msg) {
                  // process incoming messages here
              }
          };

          Looper.loop();
      }
  }

很明顯,handlerMessage()方法跑在子線程。

對於HandlerThread方式:

HandlerThread#run()

    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

也是跑在子線程。

對於mHandler = new Handler()方式:

雖然未傳Looper, 但默認使用的是主線程的Looper, 所以此時handlerMessage跑在主線程。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM