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跑在主線程。