从源码与官方文档看之Handler篇(九)

666 阅读4分钟

我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情,希望大家多多支持,帮忙点个赞,谢谢!

前言

今天我们来详细看看Handler的post()方法吧,又有活动来了,动力又回来了,哈哈哈,继续加油吧!

正篇

看到了很多掘友们留言说Android是江河日下,可我已经在这个行业,如果不把这行做好,我哪能再有心思想别的,而且我相信就算以后不做这行,我相信去学习源码也是对我有帮助的,新人也是好不容易有一份工作的,暂时一年半载肯定不会有更多的想法的,好好加油,先把安卓学好。

多余的话就不说了,我们接着来看代码:

/**
 * Causes the Runnable r to be added to the message queue.
 * The runnable will be run on the thread to which this handler is 
 * attached. 
 *  
 * @param r The Runnable that will be executed.
 * 
 * @return Returns true if the Runnable was successfully placed in to the 
 *         message queue.  Returns false on failure, usually because the
 *         looper processing the message queue is exiting.
 */
public final boolean post(@NonNull Runnable r) {
   return  sendMessageDelayed(getPostMessage(r), 0);
}

这个是第一个post方法,它的注释大意为:
让 Runnable类型的参数 r 添加到消息队列中。 可运行的对象将会在附加此handler的线程上运行。
其中参数: r 代表将被执行的 Runnable对象
返回结果: 如果 Runnable 对象已成功放入消息队列,则返回 true,
如果失败就返回 false,这点通常是因为处理消息队列的 looper 正在退出的结束流程中。

也就是说,这个方法为我们提供了一个方式,让我们将不为空的Runnable运行,即可以在子线程里运行UI线程的处理,当然,这个方法是不做延时操作的。

延时操作的post在下面的这些方法中:

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

这两个方法是用于确定了延迟的绝对时间(使用SystemClock.uptimeMillis时基)后,到该时间后进行程序处理。 还有:

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

/** @hide */
public final boolean postDelayed(Runnable r, int what, long delayMillis) {
    return sendMessageDelayed(getPostMessage(r).setWhat(what), delayMillis);
}
public final boolean postDelayed(
        @NonNull Runnable r, @Nullable Object token, long delayMillis) {
    return sendMessageDelayed(getPostMessage(r, token), delayMillis);
}

这三个是使用参数delayMillis – 以执行 Runnable 之前的延迟(以毫秒为单位)的相对时间即多少毫秒后执行的post方法。其中,上述的方法中含有Object对象token参数的意思是用于通过removeCallbacksAndMessages取消r的实例。

而这些boolean方法的返回注释大意为:如果 Runnable 已成功放入消息队列,则返回 true。失败时返回 false,通常是因为处理消息队列的 looper 正在退出。请注意,结果为 true 并不意味着 Runnable 将被处理——如果在消息的传递时间发生之前退出 looper,则消息将被丢弃。

还有最后一个post方法:

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

方法注释的大意为向实现 Runnable 的对象发布消息,使 Runnable r 在消息队列的下一次迭代中执行。
可运行对象将在附加此处理程序的线程上运行。
而且这种方法一般只在非常特殊的情况下使用, 这是因为它很容易使消息队列饿死,导致排序问题,或者有其他意想不到的副作用。反正我没用过这个方法。 最常用的还是这两个方法:

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

/** @hide */
public final boolean postDelayed(Runnable r, int what, long delayMillis) {
    return sendMessageDelayed(getPostMessage(r).setWhat(what), delayMillis);
}

一个我常用于子线程延迟时间向主线程发消息,一个是延迟程序块运行时间

当然,最开始的: public final boolean post(@NonNull Runnable r) 方法也是蛮常用的,而我们也看到,这些方法的返回都是介于sendMessageXXX方法的,而这个方法中都定义了

MessageQueue queue = mQueue;

所以我们不需要传递消息队列进来,下一篇我们会去分析一下这些被用于post方法的return的更内部的方法。