(深入理解Android內核設計思想)讀書筆記:Looper,Handler,Runnable,MessageQueue,ActivityThread

(深入理解Android內核設計思想)讀書筆記:Looper,Handler,Runnable,MessageQueue,ActivityThread,Looper不斷獲取MessageQueue中的一個Message,交給Handler處理。加入隊列為空,Looper進入休眠。
幾者的關系:
每個Thread隻對應一個Looper;
每個Looper隻對應一個MessageQueue;
每個MessageQueue中有N個Messsage;
每個Message最多指定一個Handler來處理事件。
Handler的功能:
1.處理Message;
handlerMessage(msg);
dispatchMessage(msg);
2.將Message壓入MessageQueue(為什麼要先壓入queue中,而不是直接處理,這體現瞭程序設計的“有序性”);
post(runnable);
sendMessage(msg);
post是將runnable轉換成message送入messageQueue中。

public final boolean post(Runnable r){  
    return sendMessageDelayed(getPostMessage(r),0);  
}  
private static Message getPostMessage(Runnable r){  
    Message m = Message.obtain();//Android系統維護的全局Message池。避免資源浪費。  
    m.callback = r;  
    return m;  
}  
public boolean sendMessageAtTime(Message msg, long uptimeMillis){  
    MessageQueue queue = mQueue;  
    msg.target = this;  
    return enqueueMessage(queue, msg, uptimeMillis);  
} 

Looper的使用:

class LooperThread extends Thread{  
    public Handler mHandler;  
    public void run(){  
        Looper.prepare();  
        mHandler = new Handler(){  
            public void handlerMessage(){  
                //TODO  
            }  
        };   
        Looper.loop();  
    }  
}

默認的線程不存在消息循環,所以不用使用Looper。

 

Looper的創建:

//Looper中的代碼  
static final ThreadLocal sThreadLocal = new ThreadLocal();  
private static void prepare(boolean quitAllowed){  
    if(sThreadLocal.get() != null){  
        throw new RuntimeException("only one Looper may be created per thread");  
    }  
    sThreadLocal.set(new Looper(quitAllowed));  
}

可見looper是在這裡new的,可是它怎麼和thread關聯上的呢,看下面的代碼:

 

//ThreadLocal.java  
public void set(T value) {  
    Thread currentThread = Thread.currentThread();  
    Values values = values(currentThread);  
    if (values == null) {  
        values = initializeValues(currentThread);  
    }  
    values.put(this, value);  
}

這裡獲取瞭當前線程,put中做瞭一系列操作,將當前線程與looper關聯瞭起來。

 

MessageQueue的創建:

MessageQueue在創建Looper對象的時候創建。

//Looper.java  
private Looper() {  
    mQueue = new MessageQueue();  
    mRun = true;  
    mThread = Thread.currentThread();  
}

 

Handler中獲取Looper:

//Handler.java  
public Handler(){  
    mLooper = Looper.myLooper();  
    mQueue = mLooper.mQueue;  
}

 

//Looper.java  
public static final Looper myLooper() {  
    return (Looper)sThreadLocal.get();  
}
//ThreadLocal.java  
public T get() {  
    Thread currentThread = Thread.currentThread();  
    Values values = values(currentThread);  
    if (values != null) {  
        Object[] table = values.table;  
        int index = hash & values.mask;  
        if (this.reference == table[index]) {  
            return (T) table[index + 1];  
        }  
    } else {  
        values = initializeValues(currentThread);  
    }  
    return (T) values.getAfterMiss(this);  
}

Handler的構造函數中最終調用sTreadLocal.get(),get()可見也是根據當前線程獲取當前的looper。

 

ActivityThread:

ActivityThread的mani()是進程的入口函數。

//ActivityThread.java  
public static final void main(String[] args) {  
    SamplingProfilerIntegration.start();  
  
    Process.setArgV0("");  
  
    Looper.prepareMainLooper();  
  
    ActivityThread thread = new ActivityThread();  
    thread.attach(false);  
  
    Looper.loop();  
  
    if (Process.supportsProcesses()) {  
        throw new RuntimeException("Main thread loop unexpectedly exited");  
    }  
  
    thread.detach();  
    String name = (thread.mInitialApplication != null)  
        ? thread.mInitialApplication.getPackageName()  
        : "";  
    Log.i(TAG, "Main thread of " + name + " is now exiting");  
 }
//Looper.java  
public static final void prepareMainLooper() {  
    prepare();  
    setMainLooper(myLooper());  
    if (Process.supportsProcesses()) {  
        myLooper().mQueue.mQuitAllowed = false;  
    }  
}

 

private synchronized static void setMainLooper(Looper looper) {  
    mMainLooper = looper;  
}

這個主線程和普通線程的區別就是多瞭個Looper.prepareMainLooper();我感覺它的作用就是為瞭創建一個mainLooper供其他線程調用。

 

Looper.loop(),apk動起來的根本原因:

public static final void loop() {  
    Looper me = myLooper();  
    MessageQueue queue = me.mQueue;  
    while (true) {  
        Message msg = queue.next();  
        if (msg != null) {  
            if (msg.target == null) {  
                return;  
            }  
            if (me.mLogging!= null) me.mLogging.println(  
                    ">>>>> Dispatching to " + msg.target + " "  
                    + msg.callback + ": " + msg.what  
                    );  
            msg.target.dispatchMessage(msg);  
            if (me.mLogging!= null) me.mLogging.println(  
                    "<<<<< Finished to    " + msg.target + " "  
                    + msg.callback);  
            msg.recycle();  
        }  
    }  
}

msg.target為將msg壓入queue的handler

Handler處理Message:

//Handler.java  
public void dispatchMessage(Message msg) {  
    if (msg.callback != null) {  
        handleCallback(msg);  
    } else {  
        if (mCallback != null) {  
            if (mCallback.handleMessage(msg)) {  
                return;  
            }  
        }  
        handleMessage(msg);  
    }  
}

 

private final void handleCallback(Message message) {  
    message.callback.run();  
}

dispatchMessage()中,判斷msg.callback不空的話,就handlerCallback(msg),此時的msg.callback即為上面post時的runnable,所以這裡走的是runnable的run()方法。

else中調用的即是重寫的handlerMessage()。

View為什麼也可以post(runnable):

public boolean post(Runnable action) {  
    Handler handler;  
    if (mAttachInfo != null) {  
        handler = mAttachInfo.mHandler;  
    } else {  
        ViewRoot.getRunQueue().post(action);  
        return true;  
    }  
  
    return handler.post(action);  
}

View中也有post()方法,裡面新建瞭個handler,做瞭post操作。

You May Also Like