handler機制

1.先來看sdk中的介紹:git

A Handler allows you to send and process {@link Message} and Runnable objects associated with a thread's {@link MessageQueue}. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread /message queue of the thread that is creating it -- from that point on,it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.github

翻譯:一個Handler能夠發送或處理和一個線程相關的任務對象。每一個Handler實例都關聯一個單線程及其消息隊列。每當你創造一個新的Handler,它必然對應產生一個線程/消息隊列,今後刻開始,它將發送消息和任務到消息隊列而且當它們從消息隊列出來時去處理它們。windows

There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.app

翻譯:Handler有兩個主要用途:(1)預先排隊將要處理的線程(2)將一個動做異步優先處理異步

When posting or sending to a Handler, you can either allow the item to be processed as soon as the message queue is ready to do so, or specify a delay before it gets processed or absolute time for it to be processed. The latter two allow you to implement timeouts, ticks, and other timing-based behavior.async

翻譯:這句講Handler既能夠馬上處理,也能夠延時處理ide

When a process is created for your application, its main thread is dedicated to running a message queue that takes care of managing the top-level application objects (activities, broadcast receivers, etc) and any windows they create. You can create your own threads, and communicate back with the main application thread through a Handler. This is done by calling the same <em>post</em> or <em>sendMessage</em> methods as before, but from your new thread. The given Runnable or Message will then be scheduled in the Handler's message queue and processed when appropriate.函數

翻譯:這句講的是經過sendMessage方法實現異步線程和主線程的通訊oop

2.Handler構造函數post

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

public Handler(Callback callback) {
    this(callback, false);
}

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

public Handler(Looper looper, Callback callback) {
    this(looper, callback, false);
}

public Handler(boolean async) {
    this(null, async);
}

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());
        }
    }

    mLooper = Looper.myLooper();
    if (mLooper == null) {
        throw new RuntimeException(
            "Can't create handler inside thread that has not called Looper.prepare()");
    }
    mQueue = mLooper.mQueue;
    mCallback = callback;
    mAsynchronous = async;
}

public Handler(Looper looper, Callback callback, boolean async) {
    mLooper = looper;
    mQueue = looper.mQueue;
    mCallback = callback;
    mAsynchronous = async;
}

這幾個構造函數最終要作的都是這幾句

mLooper = looper;
//或Looper.myLooper()
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;

3.Looper

Looper構造函數

private Looper(boolean quitAllowed) {
    mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); }

建立了一個MessageQueue對象。

這裏有個須要注意的地方:

ActivityThread的主線程中執行了以下方法:

public static void main(String[] args) {
    ...
    Looper.prepareMainLooper();
    ...
    Looper.loop();
    ...
}

來看Looper執行了哪些:

prepareMainLooper()

public static void prepareMainLooper() {
    prepare(false);
    synchronized (Looper.class) {
        if (sMainLooper != null) {
            throw new IllegalStateException("The main Looper has already been prepared.");
        }
        sMainLooper = myLooper();
    }
}

其中prepare()向sThreadLocal中塞了一個Looper對象(一個線程中只能有一個Looper

public static void prepare() {
    prepare(true);
}

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));
}

前面Handler的構造函數中執行Looper.myLooper()

public static @Nullable Looper myLooper() {
    return sThreadLocal.get();
}

這樣就能獲取當前線程保存的Looper實例。並且在Handler構造函數中執行了下面這句

mQueue = looper.mQueue;

這樣就保證了handler的實例與咱們Looper實例中MessageQueue關聯上了。

執行loop()

public static void loop() {
    final Looper me = myLooper();
    final MessageQueue queue = me.mQueue;
   ...
    for (;;) {
        Message msg = queue.next(); // might block
        if (msg == null) {
            return;
        }
        ...
        msg.target.dispatchMessage(msg);
... msg.recycleUnchecked(); } }

msg.target就是Handler自身

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

由於再往回看,發現咱們一開始msg.callback實際上是null,因此最終執行的是handleMessage(msg);

public void handleMessage(Message msg) {
    }

方法體是空的,因此須要去複寫處理Message

4.Message

構造函數

public Message() {
}

獲取Message

public static Message obtain() {
    synchronized (sPoolSync) {
        if (sPool != null) {
            Message m = sPool;
            sPool = m.next;
            m.next = null;
            m.flags = 0; // clear in-use flag
            sPoolSize--;
            return m;
        }
    }
    return new Message();
}

public static Message obtain(Message orig) {
    Message m = obtain();
    m.what = orig.what;
    m.arg1 = orig.arg1;
    m.arg2 = orig.arg2;
    m.obj = orig.obj;
    m.replyTo = orig.replyTo;
    m.sendingUid = orig.sendingUid;
    if (orig.data != null) {
        m.data = new Bundle(orig.data);
    }
    m.target = orig.target;
    m.callback = orig.callback;

    return m;
}

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

    return m;
}

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

    return m;
}

public static Message obtain(Handler h, int what, Object obj) {
    Message m = obtain();
    m.target = h;
    m.what = what;
    m.obj = obj;

    return m;
}

public static Message obtain(Handler h, int what, int arg1, int arg2) {
    Message m = obtain();
    m.target = h;
    m.what = what;
    m.arg1 = arg1;
    m.arg2 = arg2;

    return m;
}

public static Message obtain(Handler h, int what, 
        int arg1, int arg2, Object obj) {
    Message m = obtain();
    m.target = h;
    m.what = what;
    m.arg1 = arg1;
    m.arg2 = arg2;
    m.obj = obj;

    return m;
}

其中obtain()最重要

Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;

顯而易見,是一個鏈表結構,分析以下:

 

這樣,就能從sPool中獲得一個Message,體現了重複回收利用的特色。

可能有人會問,獲得Message不是經過Handler.obtainMessage方法嗎,其實緣由很簡單,Handler.obtainMessage調用的就是Message.obtain

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

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

public final Message obtainMessage(int what, Object obj){
    return Message.obtain(this, what, obj);
}

public final Message obtainMessage(int what, int arg1, int arg2){
    return Message.obtain(this, what, arg1, arg2);
}

public final Message obtainMessage(int what, int arg1, int arg2, Object obj){
    return Message.obtain(this, what, arg1, arg2, obj);
}

前面Looper中調用了msg.recycleUnchecked()

void recycleUnchecked() {
    // Mark the message as in use while it remains in the recycled object pool.
    // Clear out all other details.
    flags = FLAG_IN_USE;
    what = 0;
    arg1 = 0;
    arg2 = 0;
    obj = null;
    replyTo = null;
    sendingUid = -1;
    when = 0;
    target = null;
    callback = null;
    data = null;

    synchronized (sPoolSync) {
        if (sPoolSize < MAX_POOL_SIZE) {
            next = sPool;
            sPool = this;
            sPoolSize++;
        }
    }
}

即回收Message

5.發送消息

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

public final boolean sendEmptyMessage(int what){
    return sendEmptyMessageDelayed(what, 0);
}

public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
    Message msg = Message.obtain();
    msg.what = what;
    return sendMessageDelayed(msg, delayMillis);
}

public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
    Message msg = Message.obtain();
    msg.what = what;
    return sendMessageAtTime(msg, uptimeMillis);
}

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) {
    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);
}

public final boolean sendMessageAtFrontOfQueue(Message msg) {
    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, 0);
}

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

方法這麼多,最後執行的都是enqueueMessage

queue.enqueueMessage(msg, uptimeMillis);

6.MessageQueue.enqueueMessage()

boolean enqueueMessage(Message msg, long when) {
    ...
    synchronized (this) {
        ...
        msg.markInUse();
        msg.when = when;
        Message p = mMessages;
        boolean needWake;
        if (p == null || when == 0 || when < p.when) {
            msg.next = p;
            mMessages = msg;
            needWake = mBlocked;
        } else {
            ...
            Message prev;
            for (;;) {
                prev = p;
                p = p.next;
                ...
            }
            msg.next = p; // invariant: p == prev.next
            prev.next = msg;
        }
        ...
    }
    return true;
}

MessageQueue也是一個鏈表,msg會插入到p的前面

發送消息還有另外一種方式post,但其實最終調用的都是sendMessageXXX

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

public final boolean postAtTime(Runnable r, long uptimeMillis){
    return sendMessageAtTime(getPostMessage(r), uptimeMillis);
}

public final boolean postAtTime(Runnable r, Object token, long uptimeMillis){
    return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
}

public final boolean postDelayed(Runnable r, long delayMillis){
    return sendMessageDelayed(getPostMessage(r), delayMillis);
}

 public final boolean postAtFrontOfQueue(Runnable r){
    return sendMessageAtFrontOfQueue(getPostMessage(r));
}

不同的是,須要傳一個參數Runnable,而且須要getPostMessage(runnable)

private static Message getPostMessage(Runnable r) {
    Message m = Message.obtain();
    m.callback = r;
    return m;
}

總結:

一、首先Looper.prepare()在本線程中保存一個Looper實例,而後該實例中保存一個MessageQueue對象;由於Looper.prepare()在一個線程中只能調用一次,因此MessageQueue在一個線程中只會存在一個。

二、Looper.loop()會讓當前線程進入一個無限循環,不端從MessageQueue的實例中讀取消息,而後回調msg.target.dispatchMessage(msg)方法。

三、Handler的構造方法,會首先獲得當前線程中保存的Looper實例,進而與Looper實例中的MessageQueue想關聯。

四、Handler的sendMessage方法,會給msg的target賦值爲handler自身,而後加入MessageQueue中。

五、在構造Handler實例時,咱們會重寫handleMessage方法,也就是msg.target.dispatchMessage(msg)最終調用的方法。

ps:純原創,參考文章以下

https://github.com/maoruibin/HandlerAnalysis

http://blog.csdn.net/lmj623565791/article/details/38377229

相關文章
相關標籤/搜索