handler message looper機制(二)

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的任務。
}

未完待續。。。

發佈了36 篇原創文章 · 獲贊 5 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章