HandlerThread 是一個封裝好的looper線程類。
從源碼看看
public class HandlerThread extends Thread {
int mPriority; // 線程優先級
int mTid = -1; // 修改線程優先級、調度策略時用來做線程唯一標識
Looper mLooper; // 與線程關聯的Looper
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT; // 設置默認優先級0
}
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority; // 主動設置優先級
}
protected void onLooperPrepared() { //回調方法,looper開始前執行
}
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare(); // 初始化一個Looper對象,然后存入到ThreadLocal中,將Looper和當前線成進行綁定,一一對應.
synchronized (this) { // 進入同步塊
mLooper = Looper.myLooper(); //得到當前線程的looper對象
notifyAll();//通知其他線程
}
Process.setThreadPriority(mPriority); // 設置線程優先級
onLooperPrepared(); // 回調重寫
Looper.loop(); // 一個死循環,不斷從MessageQueue取出消息,如有消息就處理,沒有就阻塞
mTid = -1; // 因為Looper.loop()是個死循環啊,執行到mTid = -1的時候,就是looper退出的時候
}
public Looper getLooper() {
if (!isAlive()) { // 如果線程不是在存活狀態則直接返回null。
return null;
}
synchronized (this) {
while (isAlive() && mLooper == null) { // 進入同步塊,當條件不滿足時無限等待,
try { // 直到mLooper被設置成有效值了才退出等待
wait(); // run方法里的notifyAll就是用來喚醒這里的
} catch (InterruptedException e) { // 中斷異常
}
}
}
return mLooper; // 最后返回mLooper
}
public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
}
public boolean quitSafely() {
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
}
void quit(boolean safe) {
if (!mQuitAllowed) {
throw new IllegalStateException("Main thread not allowed to quit.");
}
synchronized (this) {
if (mQuitting) {
return;
}
mQuitting = true;
if (safe) {
removeAllFutureMessagesLocked();
} else {
removeAllMessagesLocked();
}
// We can assume mPtr != 0 because mQuitting was previously false.
nativeWake(mPtr);
}
}
quit()和 quitSafely()的區別:
removeAllMessagesLocked()是把MessageQueue消息池中所有的消息全部清空,無論延遲與否
removeAllFutureMessagesLocked()是只清空延遲消息,非延遲消息派發出去讓Handler去處理。
異步handler的創建方式
Thread newThread = new Thread(new Runnable()
{
@Override
public void run() {
Looper.prepare();
Looper.loop();
}
});
newThread.start();
Handler handler = new Handler(newThread.getLooper());
當執行到Handler handler = new Handler(newThread.getLooper());的時候,newThread的looper可能還沒有創建好,會有線程同步的
問題。
總結:
1.不管調用哪個,Looper就不再接收新的消息,再通過Handler調用sendMessage發消息都只會返回false,Looper的quit方法從API Level 1就存在了,但是Looper的quitSafely方法從API Level 18才添加進來
2.HandlerThread本質是一個Thread,區別在于他在run()之后創建了一個含有消息隊列的Looper,這樣我們在子線程中創建Handler時候只需指定使用HandlerThread中的Looper,不用再調用Looper.prepare(),looper.loop(),并且做了同步的處理,簡化了操作。
3.另外Handler與Activity在同一個線程中,不能做耗時操作。HandlerThread是新的線程,可做耗時操作
舉例:
public class MainActivity extends Activity {
private Handler handlerthread;
private HandlerThread thread;
//創建主線程中的handler
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
Message message = new Message();
handlerthread.sendMessageDelayed(message, 1000);
Log.d("wuc", "主線程");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt_test = (Button)findViewById(R.id.bt_test);
bt_test.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handlerthread.sendEmptyMessage(1);
}
});
thread = new HandlerThread("threadHandler");
thread.start();
handlerthread = new Handler(thread.getLooper()){
@Override
public void handleMessage(Message msg) {
Message message = new Message();
//handler每隔1秒向主線程發送一次消息。
Log.d("wuc", "子線程");
handler.sendMessageDelayed(message, 1000);
}
};
}
}
04-26 16:49:26.822 7349-7385/com.example.lyf.androidtext D/wuc: 子線程
04-26 16:49:27.822 7349-7349/com.example.lyf.androidtext D/wuc: 主線程
04-26 16:49:28.823 7349-7385/com.example.lyf.androidtext D/wuc: 子線程
04-26 16:49:29.826 7349-7349/com.example.lyf.androidtext D/wuc: 主線程
04-26 16:49:30.826 7349-7385/com.example.lyf.androidtext D/wuc: 子線程
04-26 16:49:31.827 7349-7349/com.example.lyf.androidtext D/wuc: 主線程
04-26 16:49:32.828 7349-7385/com.example.lyf.androidtext D/wuc: 子線程