Handler
Handler機制是子執行緒和主執行緒、子執行緒和子執行緒通信的一種方法,其中包括Looper、MessageQueue、Message、Handler,Handler將Message發送到MessageQueue中,Looper不停的輪詢從MessageQueue中取出Message交給Handler處理,
先看一下Handler的基本用法
Handler uiHandler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
//處理發送過來的訊息
}
};
Message message = new Message();
message.what = 1;
uiHandler.sendMessage(message);
Handler的創建
使用Android Studio點開Handler的構造方法,如下所示:

從原始碼中可以看到,在Handler的構造方法中,會呼叫Looper.myLooper()方法獲取Looper,如果Looper為空,則會拋出例外,這也是我們在使用Handler之前一定要創建Looper的原因,也就是必須呼叫Looper.prepare()方法,而上述示例代碼中卻沒有呼叫該方法,也能正常執行,是因為當行程啟動時,ActivityThread的main()方法中已經呼叫了,我們再次呼叫反而會報錯,

Looper創建時做了什么?
我們打開Looper.java,找到prepare()方法,可以看到,首先會通過ThreadLocal獲取該執行緒系結的Looper,如果已經存在,則拋出例外:Only one Looper may be created per thread(每個執行緒只能創建一個Looper),獲取不到Looper,則呼叫Looper的構造方法創建一個Looper并放到ThreadLocal中,使這個創建的Looper和當前執行緒系結,

接下來看看Looper的構造方法中做了什么?

Looper的構造方法是一個私有方法,這也就意味著我們不能通過new的方式直接創建Looper物件,在構造方法中初始化了MessageQueue,這個MessageQueue會在創建Handler的時候賦值給Handler的mQueue:
//Handler.java 構造方法
mQueue = mLooper.mQueue;
MessageQueue是怎么存放Message的?
MessageQueue是用來存放Message的,它的名字雖然有Queue(佇列),其實它里面維護的是一個鏈表,結點就是Message,我們通過sendMessage()或post()方法是怎么存到MessageQueue中的,一起來看下:

從上面的代碼可以看到,不管是使用sendMessage()還是post(),最終都會走到enqueueMessage()中,在enqueueMessage中將Handler自身傳給了Message的target,這里的target其實就是Handler:
//Message.java 成員變數
Handler target;
這個target是Looper決定交給哪個Handler處理的關鍵!
接下來繼續看enqueueMessage()方法,它是怎么添加Message的:

如果Message的target為null,則會拋出例外Message must have a target,這里也告訴我們必須要有target,如果這個Message已經使用了,則會拋出The message is already in use,因此,同一個Message不能使用兩次!接下來會取出表頭的Message是否為慷訓者延遲時間when來判斷是放到表頭的位置還是放到鏈表中間的位置,到此,sendMessage的流程就結束了,
接下來看看Looper是怎么從MessageQueue中取出訊息交給Handler處理的?
Looper的loop()做了什么?

loop()方法中首先還是檢查了該執行緒系結的Looper是否為空,可見prepare()是真的真的不能少啊,檢查了Looper后,就獲取該Looper中的MessageQueue,然后開啟一個死回圈一直輪詢從MessageQueue中取Message,如果Message存在,則呼叫其target的dispatchMessage()方法,上文中已經提到這個target就是Handler,這也是為什么Looper知道交給哪個Handler處理的原因,繼續進入到dispatchMessage()方法中:

在dispatchMessage()方法中分成了兩種情況,一種是msg.callback不為null的情況:

這種情況是通過post()方式,會直接執行Runnable的run()方法,和執行緒Thread沒有關系,
另外一種是msg.callback為null的情況:這種一般為sendMessage()方式,會呼叫了handleMessage()方法,這也正是我們創建Handler時需要重寫的方法,這也是Handler的sendMessage()和post()的區別,
Looper的loop()執行了死回圈為什么不會導致主執行緒阻塞?

原因寫在注釋中了,想要了解nativePollOnce方法可以看看nativePollOnce
Handler的分析到此就結束了,總結?不存在的,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/265425.html
標籤:其他
上一篇:C++入門
