你们都知道每一个View都有一个post()和postDelayed()方法,那么这两个方法是作什么用呢?何时须要用呢?android
咱们带着这两个问题来分析一下:缓存
首先咱们看下这两个方法的源码,首先看post():app
/**
*<p>Causes the Runnable to be added to the message queue.
* The runnable will be run on the user interface thread.</p>
*
*@paramactionThe Runnable that will be executed.
*
*@returnReturns 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.
*
*@see#postDelayed
*@see#removeCallbacks
*/
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
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;
}oop
从源码中咱们很清楚的看到,两种状况:post
1.当mAttachInfo != null 时,post方法最终是由attachInfo中的mHandler调用post来处理,从而保证在ui线程中执行,因此从根本上来以后的整个流程仍是Handler 的整个处理机制流程(Handler的处理机制流程,这里不作分析),那么mAttachInfo又是何时赋值的呢?搜索一下源码看到:ui
/**
*@paraminfothe {@linkandroid.view.View.AttachInfo} to associated with
* this view
*/
void dispatchAttachedToWindow(AttachInfo info, int visibility) {
mAttachInfo = info;
if (mOverlay != null) {
mOverlay.getOverlayView().dispatchAttachedToWindow(info, visibility);
}this
能够看到mAttachInfo是在,dispatchAttachedToWindow中调用的,而dispatchAttachedToWindow 是在 ViewRootImpl 类的performTraversals 调用的,而这个方法在view初始化的时候会被调用。spa
2.mAttachInfo==null时,调用getRunQueue().post(action),咱们来看下这个getRunQueue()的源码:线程
/**
* Returns the queue of runnable for this view.
*
*@returnthe queue of runnables for this view
*/
private HandlerActionQueue getRunQueue() {
if (mRunQueue == null) {
mRunQueue = new HandlerActionQueue();
}
return mRunQueue;
}orm
这里看到最终调用的是HandlerActionQueue的post()方法:
public void post(Runnable action) {
postDelayed(action, 0);
}
public void postDelayed(Runnable action, long delayMillis) {
final HandlerAction handlerAction = new HandlerAction(action, delayMillis);
synchronized (this) {
if (mActions == null) {
mActions = new HandlerAction[4];
}
mActions = GrowingArrayUtils.append(mActions, mCount, handlerAction);
mCount++;
}
}
这里咱们看到基本上就是经过HandlerActionQueue缓存起来,缓存起来何时执行呢?咱们找下HandlerActionQueue的源码里:
public void executeActions(Handler handler) {
synchronized (this) {
final HandlerAction[] actions = mActions;
for (int i = 0, count = mCount; i < count; i++) {
final HandlerAction handlerAction = actions[i];
handler.postDelayed(handlerAction.action, handlerAction.delay);
}
mActions = null;
mCount = 0;
}
}
缓存起来的runnable最终仍是经过handler来执行,直接找到执行的代码:
仍是经过dispatchAttachedToWindow来执行。
这两个方法:
当打开一个activity时若是调用post方法时尚未开始执行dispatchAttachedToWindow就先调用getRunQueue().post(action)缓存起来,当执行到dispatchAttachedToWindow时再执行handler的post,若是到达就直接执行handler.post。
总结:post()和postDelayed()用来更新ui,postDelayed能够设置延时。