Handler源碼淺析(一)

Handler 和他的小伙伴

  • Handler(消息發送者和接受者)
  • Looper(消息循環)
  • Message(消息)
  • MessageQueue(消息隊列)

讓我們先從Handler看起

public Handler() {
    this(null, false);
}

Handler 默認要與Looper綁定起來,否者就不能接受信息會拋出異常

public Handler(Callback callback, boolean async) {
//這段是檢測內存泄露
        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());
            }
        }

//獲取當前線程的Looper,沒有會拋出異常
        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
//獲取Looper里的消息隊列給當前Handler對象引用
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }

這個Callback是另一種構造方法,可以避免你自己實現子類Handler 重寫
public boolean handleMessage(Message msg);

public interface Callback {
    public boolean handleMessage(Message msg);
}

接下來看發送消息,在0ms以后,將一個Message消息推送到消息隊列的末尾 message將會被發送的Handler的handleMessage()方法收到。

public final boolean sendMessage(Message msg)
{
    return sendMessageDelayed(msg, 0);
}

繼續向下看延時發送Message,當前時間+延時時間最小是0ms
注意 這里返回ture,代表消息放入message queue 成功,但并不意味消息會被處理
如過消息發送在looper退出之后,就會被拋棄。

public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
    if (delayMillis < 0) {
        delayMillis = 0;
    }
    return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}

到這里我們把handler持有的隊列 也就是和當前Handler綁定Looper那里拿到的隊列
mQueue = mLooper.mQueue;
發送過去

public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
    MessageQueue queue = mQueue;
    if (queue == null) {
        RuntimeException e = new RuntimeException(
                this + " sendMessageAtTime() called with no mQueue");
        Log.w("Looper", e.getMessage(), e);
        return false;
    }
    return enqueueMessage(queue, msg, uptimeMillis);
}

** msg.target=this;**
讓我們看下Message 源碼 定義了一個 Handler target;
這樣就知道Message是由哪個Handler 發送的了。

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
    msg.target = this;
    if (mAsynchronous) {
        msg.setAsynchronous(true);
    }
    return queue.enqueueMessage(msg, uptimeMillis);
}

Post方法也是如此

public final boolean post(Runnable r)
{
   return  sendMessageDelayed(getPostMessage(r), 0);
}

從全局的message池中返回一個全新的message對象,比創建和分配新實例更有效

   public final Message obtainMessage()
    {
        return Message.obtain(this);
    }

    public static Message obtain(Handler h) {
        Message m = obtain();
        m.target = h;

        return m;
    }

既然有發送就會有接收 handleMessage(Message msg);是用來處理你接收到的消息的
dispatchMessage(Message msg) 就是分發消息的,這個方法是誰調用呢,我們會在Looper里講的

public void handleMessage(Message msg) {
    }
    
    /**
     * 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源碼淺析(二)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容