Looper是通過調(diào)用loop方法驅(qū)動著消息循環(huán)的進(jìn)行: 從MessageQueue中阻塞式地取出一個消息艇抠,然后讓Handler處理該消息胆描,周而復(fù)始瞬雹,loop方法是個死循環(huán)方法悄晃。
那如何終止消息循環(huán)呢训唱?我們可以調(diào)用Looper的quit方法或quitSafely方法,二者稍有不同挚冤。Looper的quit方法源碼如下:
public void quit() { mQueue.quit(false);}
1
2
3
Looper的quitSafely方法源碼如下:
public void quitSafely() { mQueue.quit(true);}
1
2
3
以上兩個方法中mQueue是MessageQueue類型的對象况增,二者都調(diào)用了MessageQueue中的quit方法,MessageQueue的quit方法源碼如下:
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); }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
通過觀察以上源碼我們可以發(fā)現(xiàn):
當(dāng)我們調(diào)用Looper的quit方法時训挡,實際上執(zhí)行了MessageQueue中的removeAllMessagesLocked方法澳骤,該方法的作用是把MessageQueue消息池中所有的消息全部清空,無論是延遲消息(延遲消息是指通過sendMessageDelayed或通過postDelayed等方法發(fā)送的需要延遲執(zhí)行的消息)還是非延遲消息澜薄。
當(dāng)我們調(diào)用Looper的quitSafely方法時为肮,實際上執(zhí)行了MessageQueue中的removeAllFutureMessagesLocked方法,通過名字就可以看出肤京,該方法只會清空MessageQueue消息池中所有的延遲消息颊艳,并將消息池中所有的非延遲消息派發(fā)出去讓Handler去處理,quitSafely相比于quit方法安全之處在于清空消息之前會派發(fā)所有的非延遲消息忘分。
無論是調(diào)用了quit方法還是quitSafely方法只會棋枕,Looper就不再接收新的消息。即在調(diào)用了Looper的quit或quitSafely方法之后妒峦,消息循環(huán)就終結(jié)了重斑,這時候再通過Handler調(diào)用sendMessage或post等方法發(fā)送消息時均返回false,表示消息沒有成功放入消息隊列MessageQueue中肯骇,因為消息隊列已經(jīng)退出了窥浪。
需要注意的是Looper的quit方法從API Level 1就存在了,但是Looper的quitSafely方法從API Level 18才添加進(jìn)來笛丙。