handler流程

2018-03-27  本文已影响0人  rjay

1、Loop.prepare():创建Loop对象,初始化Loop中的MessageQueue跟当前的Thread;

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

}

2、Loop.loop():拿到当前线程Loop对象,在拿到Loop中的消息队列,for循环轮询遍历消息队列,不断调用MessageQueue的next方法,取出消息;

final Looper me = myLooper();

if (me == null) {

    throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");

}

final MessageQueue queue = me.mQueue;

for (;;) {

    Message msg = queue.next(); // might block

    if (msg == null) {

        // No message indicates that the message queue is quitting. return;

    }

    msg.target.dispatchMessage(msg);

}

3、创建handler对象:创建handler对象时,会拿到当前线程的Loop对象,除了Main线程,其他线程都得初始化Loop对象,否则会报错。通过Loop对象,把handler跟所属线程的消息队列关联起来;

public Handler(Callback callback, boolean async) {

    mQueue = mLooper.mQueue;

}

4、发送消息:实际上是把消息加到消息队列中,但在这一步之前,会把handler对象赋值给msg的target属性;

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {

    msg.target = this;

    if (mAsynchronous) {

        msg.setAsynchronous(true);

    }

    return queue.enqueueMessage(msg, uptimeMillis);

}

5、接收消息:将消息加入到了消息队列,通过Loop的轮询,就能取出当前加入到消息队列的消息。最终把消息分发给消息体的target属性(调用了Handler的dispatchMessage方法),这个target实际上就是发出消息的handler对象;

public void dispatchMessage(Message msg) {

    if (msg.callback != null) {

        handleCallback(msg);

    } else {

        if (mCallback != null) {

            if (mCallback.handleMessage(msg)) {

                return;

            }

        }

        handleMessage(msg);

    }

}

6、处理消息:最终来到了Handler的dispatchMessage方法,方法里会判断callback对象是否为空,如果为空,就调用handleMessage方法,就是我们平时创建handler时重写的handleMessage方法。

handleMessage(msg)

上一篇下一篇

猜你喜欢

热点阅读