Handler的工作机制,网上介绍的文章太多了,这里我就不赘述了,想继续了解的同学可以参考下这篇文章:Handler源码分析。一句话总结就是通过Handler对象,不论是post Msg还是Runnable,最终都是构造了一个Msg对象,插入到与之对应的Looper的MessageQueue中,不同的是Running时msg对象的callback字段设成了Runnable的值。稍后这条msg会从队列中取出来并且得到执行,UI线程就是这么一个基于事件的循环。所以可以看出Handler.post相关的代码在onCreate里那一刻时就已经开始了执行(加入到了队列,下次循环到来时就会被真正执行了)。
View.post揭秘
要解释它的行为,我们就必须深入代码中去找答案了,其代码如下:
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
// 注意这个判断,这个变量时机太早的话是没值的,
// 比如在act#onCreate阶段
return attachInfo.mHandler.post(action);
}
// 仔细阅读下面这段注释!!!
// Postpone the runnable until we know on which thread it needs to run.
// Assume that the runnable will be successfully placed after attach.
getRunQueue().post(action);
return true;
}
从上面的源码,我们大概可以看出mAttachInfo
字段在这里比较关键,当其有值时,其实和普通的Handler.post
就没区别了,但有时它是没值的,比如我们上面示例代码里的onCreate阶段,那么这时执行到了getRunQueue().post(action);
这行代码,从这段注释也大概可以看出来真正的执行会被延迟(这里的Postpone
注释);我们接着往下看看getRunQu