UITAndroid知识手机移动程序开发

Handler源码浅析(一)

2017-02-07  本文已影响35人  siyanGo

Handler 和他的小伙伴

让我们先从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源码浅析(二)

上一篇 下一篇

猜你喜欢

热点阅读