一般我們使用Hanlder是在子線程和UI線程(主線程)之間傳遞消息,當Hanlder在UI線程中new出來時候,如果沒有顯示指定looper的話,會自動綁定當前所在線程即UI線程的Looper,looper管理了一個MessageQueue。其他子線程就可以通過持有該Hanlder的引用,傳遞消息message,message被放到MessageQueue里面,并被相應handler所綁定線程的looper取出來,在handler的handleMessage()方法里執(zhí)行相應的處理。handleMessage()所執(zhí)行的線程就是handler綁定的looper所在的線程。
UI線程創(chuàng)建時候會自動初始化looper的相關操作,而為子線程創(chuàng)建對應handler則必須手動執(zhí)行這些步驟。如下:
Handler mHandler;
private void createManualThreadWithHandler() {
new Thread() {
@Override
public void run() {
super.run();
Looper.prepare();//生成looper
mHandler = new Handler(Looper.myLooper()) {//顯式持有子線程的looper
@Override
public void handleMessage(Message msg) {
//實際的耗時處理任務,在子線程中運行
};
Looper.loop();//不斷查詢是否有消息進來,此處是死循環(huán)
}
}.start();
}
子線程收到消息后實際任務處理在handleMessage中執(zhí)行。
HandlerThread實際就是一個Thread,為了方便我們?yōu)槠鋭?chuàng)建handler,就在run方法里做了Looper的相應初始化操作,源碼如下:
//調用 start() 后就會執(zhí)行的 run()
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare(); //幫我們創(chuàng)建了 Looepr
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll(); //Looper 已經創(chuàng)建,喚醒阻塞在獲取 Looper 的線程
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop(); //開始循環(huán)
mTid = -1;
}
對HandlerThread我們就可以這樣為其創(chuàng)建handler,省去了looper的準備工作:
HandlerThread handlerThread = new HandlerThread("name");
handlerThread.start();
Handler threadHanler = new Handler(handlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//do something
//此處代碼實際運行在子線程:handlerThread
}
};
當然,也可以通過在重新的onLooperPrepared()方法來創(chuàng)建handler:
class MyHandlerThread extends HandlerThread {
Handler mHandlerThreadHandler;
public MyHandlerThread(String name) {
super(name);
}
@Override
protected void onLooperPrepared() {
super.onLooperPrepared();
mHandlerThreadHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
SystemClock.sleep(2000);//模擬耗時操作
Toast.makeText(MainActivity.this, "handlerThread:" + msg.obj, Toast.LENGTH_SHORT).show();
super.handleMessage(msg);
}
};
}
}
參考:
http://blog.csdn.net/u011240877/article/details/72905631
http://droidyue.com/blog/2015/11/08/make-use-of-handlerthread/index.html