Handler用法和源码分析(一)

Handler是什么

关于这个问题,网上已经有很多人做了各种的总结和描述(不过我推荐大家要结合源码里的注释),在此就不做过多的文字描述,Handler就是用来做线程间的通信的。

Handler的基本方法

handler有很多方法。大致可以分为 sendMessage()和post()这两种。
这里写图片描述这里写图片描述
好像很多的样子,一个一个来看吧。

    //这个方法是发送一个延时的消息。不过这里的uptimeMillis要用SystemClock.uptimeMillis+delayMillis,
    //就是发送一个延时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;
        }
        //开始在queue这个消息池里面,轮询消息
        return enqueueMessage(queue, msg, uptimeMillis);
    }
//发送一个延时(delayMillis)的Message对象。
public final boolean sendMessageDelayed(Message msg, long delayMillis)
    {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        //可以看到这个地方其实调用的就是sendMessageAtTime方法。SystemClock.upTimeMillis获取的是
        //手机开机后除了睡眠的绝对时间
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }
    //这个很简答,发送一个Message对象
    public final boolean sendMessage(Message msg){
        //可以看到这里调用的是sendMessageDelayed方法,就是延时0毫秒发送一个消息,就是立即发送一个消息。
        return sendMessageDelayed(msg, 0);
    }
public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
        //传进来的what值,其实也是被赋给了一个新创建的Message对象。
        Message msg = Message.obtain();
        msg.what = what;
        //可以看到,调用的是sendMessageAtTime方法。也是延是发送一个Message对象。
        return sendMessageAtTime(msg, uptimeMillis);
    }
//可以看下Message.obtain()这个方法。其实就是android自己的一个复用机制,不用每次用到Message的时候都new一个出来,
//而是从一个全局的消息池里面返回一个Message实例。对性能是有很大的帮助的。
public static Message obtain() {
        synchronized (sPoolSync) {
            //如果sPool这个Message对象不为空,把他存的数据都清空之后,返回
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        //如果sPool这个Message对象为空,就重新new一个Message。
        return new Message();
    }
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
        //传进来的what值,其实也是被赋给了一个新创建的Message对象。
        Message msg = Message.obtain();
        msg.what = what;
         //可以看到,调用的是sendMessageDelayed方法。也是延是发送一个Message对象。
        return sendMessageDelayed(msg, delayMillis);
    }
public final boolean sendEmptyMessage(int what)
    {
        //调用sendEmptyMessageDelayed方法。延时0毫秒,立即发送一个Message对象
        return sendEmptyMessageDelayed(what, 0);
    }

post这一类的方法。有了上面的一些基本了解,下面方法中的一些问题也会迎刃而解

//在uptimeMillis这个时间发送一个Runnable的值为r的Message对象。
public final boolean postAtTime(Runnable r, long uptimeMillis)
    {
        //可以看到,这里调用的不就是上面的sendMessageAtTime嘛
        return sendMessageAtTime(getPostMessage(r), uptimeMillis);
    }
    //可以稍微看下getPostMessage方法。
private static Message getPostMessage(Runnable r) {
        //不就是新创建了一个Mesage对象(m),然后吧Runnable(r)赋给m
        Message m = Message.obtain();
        m.callback = r;
        return m;
    }
//延时delayMillis发送一个Runnable的值为r的Message对象。
public final boolean postDelayed(Runnable r, long delayMillis)
    {
        //调用的是sendMessageDelayed方法。也是用getPostMessage方法,获取一个新创建的Message对象然后把
        //Runnable对象赋给Message
        return sendMessageDelayed(getPostMessage(r), delayMillis);
    }
//延时0毫秒,发送一个Runnable的值为r的Message对象。
public final boolean post(Runnable r)
    {
        //可以看到,调用的就是sendMessageDelayed方法,延时的毫秒值为0.
       return  sendMessageDelayed(getPostMessage(r), 0);
    }
//在uptimeMillis的时间,发送一个Runnable为r,Object为token的Message对象。
public final boolean postAtTime(Runnable r, Object token, long uptimeMillis)
    {
        return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
    }
private static Message getPostMessage(Runnable r, Object token) {
        Message m = Message.obtain();
        m.obj = token;
        m.callback = r;
        return m;
    }   

通过分析和查看源码,我们发现,其实上面的那一堆方法,本质上都是调用了sendMessageAtTime这个方法。他们不过都是对msg和uptimeMillis这两个参数进行了再次封装,变向理解为“重载”吧。

public boolean sendMessageAtTime(Message msg, long 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);
    }
public final boolean postAtFrontOfQueue(Runnable r)
    {
        return sendMessageAtFrontOfQueue(getPostMessage(r));
    }    

如有错误,欢迎指正!

猜你喜欢

转载自blog.csdn.net/xy4_android/article/details/80432056
今日推荐