handler dispatchMessage && sendmessage 線程轉換

以前一直以爲用handler的一個好處是能夠在其他thread發送消息到指定的thread 如UI thread中進行處理, 

但用時不經意用到了handler的dispatchMessage(msg),才發現處理handlemessage時並沒有在UI thread中。 

翻看dipatchMessage源碼才發現, 

    /**
     * Handle system messages here.
     */
    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);////直接調用到了handler實現的handleMessage函數。 並沒有用MessageQuene來達到線程的轉換。
        }
    }


但sendMessage就不一樣了,

   public final boolean sendMessage(Message msg)
    {
        return sendMessageDelayed(msg, 0);
    }
    public final boolean sendMessageDelayed(Message msg, long delayMillis)
    {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }
    public boolean sendMessageAtTime(Message msg, long uptimeMillis)
    {
        boolean sent = false;
        MessageQueue queue = mQueue;
        if (queue != null) {
            msg.target = this;
            sent = queue.enqueueMessage(msg, uptimeMillis);//通過MessageQuene發送到對應thread 的Looper進行處理
        }
        else {
            RuntimeException e = new RuntimeException(
                this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
        }
        return sent;
    }

所以以後用handler時記得最好還是用sendMessage 或者post系列函數,因爲post函數最終也會走到sendMessageAtTime()


在一個Activity中new handler時 

handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {


 這時handler就已經 把當前的 UI thread信息attach到一起了。 

 public Handler() {
        if (FIND_POTENTIAL_LEAKS) {
            final Class<? extends Handler> klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }


        mLooper = Looper.myLooper();//當前thread looper
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;//當前thread quene, sendmessage時也就是往這個quene裏發了。
        mCallback = null;
    }


 



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