Android之Handler源码分析(第三篇:发送消息->post系列方法)

前言

    Handler用于发送消息的方法,除了send系列的方法,就是该文中的post系列方法了,前文已经分析过所有的send系列方法,本篇我们继续post系列方法的分析 

post系列的方法:6个

 

post()方法分析

 

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

用于将Runnable对象发送到MessageQueue中的方法,传入的参数为Runnable对象

1、将Runnable对象转换为Message对象

首先将传入的Runnable对象,立刻传入到getPostMessage()方法中,该方法会返回一个Message对象,这样就华丽丽的将Runnable对象转换为了Message对象

2、调用sendMessageDelayed()方法完成消息的发送(见send系列文章),并传入转换后的Message对象和一个延迟时间0

3、向调用者返回消息的发送结果,即sendMessageDelayed()方法的返回结果

true表示发送消息成功

false表示发送消息失败

 

getPostMessage()方法分析

 

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

用于将Runnable对象转换为Message对象的方法

怎么转换的呢?

1、先获取一个Message对象

调用Message的obtain()静态方法,该静态方法会返回一个Message对象

2、Message对象开始持有传入的Runnable对象

将传入的Runnable对象r赋值给Message对象的实例变量callback,这样就完成所谓的"转换",其实是Message对象持有了Runnable对象

3、向调用者返回创建的Message对象

 

postAtTime()方法分析

 

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

用于在指定时间,发送出一个Runnable对象的方法

1、先将Runnable对象转换成Message对象

调用getPostMessage()方法,getPostMessage()方法接受传入的Runnable对象后会返回一个Message对象

2、调用sendMessageAtTime()方法,同时将Message对象与指定时间uptimeMillis一并传了进去

3、向调用者返回发送结果

true表示发送Runnable成功

false表示发送Runnable失败

注意:以下均为延时1秒将Message插入到MessageQueue中
sendMessageAtTime(msg, SystemClock.uptimeMillis()+1000)
sendMessageDelayed(msg, 1000)
sendMessageAtTime()方法传入的参数uptimeMillis是相对系统开机时间的绝对时间(SystemClock.uptimeMillis()是当前开机时间)
 

postAtTime()方法分析(重载方法:3个参数)

 

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

用于在指定时间内,指定token的情况下,发送Runnable对象的方法,传入的第一个参数为Runnable对象,第二个参数为Object对象表示一个token值,第三个参数为指定时间

1、指定token值,并将Runnable转换为Message对象

先把传入的Runnable对象r、与Object对象token传入getPostMessage()方法中,getPostMessage()方法会返回一个Message对象,该Message对象不仅持有一个Runnable对象,还持有一个Object对象

2、调用sendMessageAtTime()方法,并将Message对象与具体时间都传了进去,完成消息的发送

3、向调用者返回Runnable对象的发送结果

true表示发送成功

false表示发送失败

 

getPostMessage(重载方法:2个参数)分析

 

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

用于将传入的Runnable对象转换为Message对象,并且Message对象持有一个token值可以用于标识消息!传入的第一个参数为Runnable对象,第二个参数为Object对象表示token值

1、从消息池中获取一个Message对象

先通过Message的静态方法obtain()创建一个Message对象m

2、为Message对象持有值进行赋值

接着将传入的Runnable对象、Object对象赋值给创建的Message对象m保存上,Message对象m的实例变量obj负责保存Object对象,实例变量callback负责保存Runnable对象

3、最后向调用者返回创建的Message对象m

 

postDelayed()方法分析

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

用于将Runnable对象延迟发送出去的方法,传入的第一个参数为Runnable对象,第二个参数为延迟时间

1、先将Runnable对象转换为Message对象

将Runnable对象r传入到getPostMessage()方法,该方法会返回一个Message对象

2、调用sendMessageDelayed()方法进行消息发送

将getPostMessage()方法返回的Message对象与延迟时间delayMillis一并传入到sendMessageDelayed()方法中进行发送

3、向调用者发送消息的结果

true表示成功

false表示失败

 

postDelayed()方法分析(重载:3个参数)

 

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

用于将带有Token标识的Runnable对象组成的消息发送出去

1、Runable对象转换为Message对象,并且Message会带有token值用于标识

将Runnable对象r、Object对象token传入到getPostMessage方法

2、将getPostMessage()方法返回的Message对象与延迟时间delayMillis一并传入到sendMessageDelayed()方法中完成发送工作

3、向调用者返回发送结果

 

postAtFrontOfQueue()方法分析

 

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

用于向MessageQueue插队发送Runnable对象的方法

post一个插入到消息队列头部的Message对象,先执行getPostMessage()方法,得到的Message对象传入到sendMessageAtFrontOfQueue方法完成发送工作

 

总结

1、post系列方法均依赖了send系列方法,返回值为send系列方法的返回值

2、post系列方法发送的Runnable对象,最终都会转换为Message对象,发送出去的仍然是Message对象,只不过发送的Message对象有个特点:每一个Message对象会持有要发送的Runnable对象,由Message对象的实例变量callback负责持有

3、Message对象的obj字段可以持有一个Object对象

4、uptimeMillis是相对系统开机时间的绝对时间(SystemClock.uptimeMillis()是当前开机时间),uptimeMillis不是延迟时间

5、Handler的post系列方法很方便,只要有Hander对象,随时随地可以发送Message对象出去,而定义在Runnable对象中重写的run()方法则会在Looper所属的线程中执行!!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值