handler message looper機制(二)
在handler message looper一文中,我們已經大概瞭解了這三者之間的關係。本篇文章在此基礎上詳細介紹Looper循環的流程以及post()和sendMessage()之間的區別。
目錄
Looper循環之loop()方法
我們知道,對於線程的Looper,需要嚴格執行prepare()–>looper()流程。
對於主線程,線程執行之初,Looper就已經自己生成了一個Looper。我們可以在ActivityThread.java中的main方法中找到
Looper.prepareMainLooper();
...
Looper.loop();
裏面所執行的代碼就是
//Initialize the current thread as a looper
public static void prepareMainLooper(){
prepare(false);
synchronized(Looper.class){
if(mMainLooper != null)
...
sMainLooper = myLooper();
}
}
在Looper.java的loop()中就會去不斷地讀取消息隊列。
對於非主線程,就需要我們自己手動地創造looper以及執行loop()方法
//子線程的Handler,Looper
Looper.prepare();
handler.sendMessage();
Looper.loop();
post()以及sendMessage()系列方法的區別
從代碼中我們可以看到,兩者最終都會調用到sendMessageAtTime(Message msg ,long time);
兩者的區別在於,在post方法中,有一個Runnable對象r,而這個對象r就是消息message.callback屬性,這在後面的loop中將會用作判斷條件。
public final boolean post(Runnble r){
return sendMessageDelayed(getPostMessage(r),0);
}
private static Message getPostMessage(Runnable r){
Message m = Massage.obtain();
m.callback = r;
return m;
}
在loop()中,所有消息最後都會被dispatchMessage(Mesage msg)方法來處理
public void dispatchMesasage(Message msg){
if(msg.callback != null){//post方法發出的消息 第一種情況
handleCallbck(msg);
}else{ //sendMessage發出的消息 第二種情況
if(mCallback != null){
if(mCallback.handeMessage(msg)){
return;
}
}
handleMessage(msg);//我們熟悉的回調方法
}
}
其中,第二種情況又分爲兩種,mCallback是否爲0。mCallback是在Hander構建的時候賦值的。
public Handler(Callback callback,boolean async){
...
mCallback = callback;
mAsynchronous = async;
...
}
public Handler(){
Hander(null,false);
}
明白了吧。我們平時用的無參的構造函數默認沒有回調。所以直接走handleMessage。否則走mCallback.handeMessage(msg)。
而對於post發送的message,會走handleCallbck()流程
private static void handleCallback(Message message){
message.callback.run();//這裏就會執行最開始我們post(Runnable r)中r的任務。
}
未完待續。。。