今天有点时间了,写个小知识分享。 感觉说废话浪费大家的时间,直接粘代码,相信大家能看懂的
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;
}
方法执行两条路:View被添加到窗口上了执行①,否则执行②,接下来我们分别看看①和②
final static class AttachInfo {
...
final Handler mHandler;
...
}
如果执行了①,最终会调用Handler的post方法,至于Handler的执行流程就不在这里说了,大家可能有个疑问:mHandler从哪来的,后面写View的创建过程文章的时候会讲到,耐心等待一下
private HandlerActionQueue getRunQueue() {
if (mRunQueue == null) {
mRunQueue = new HandlerActionQueue();
}
③
return mRunQueue;
}
接下来是执行②的流程,获取了一个HandlerActionQueue对象,然后执行post->postDelayed
public class HandlerActionQueue {
private HandlerAction[] mActions;
private int mCount;
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++;
}
}
④
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;
}
}
....
}
postDelayed方法是给消息存储到mActions里面,至于这个GrowingArrayUtils.append方法是一个系统工具类,里面有数组扩容逻辑,感兴趣的可以自行查看,到此发现View.post的方法还没有执行,那我们看一下③在哪做了使用,发现只有一处使用,如下
void dispatchAttachedToWindow(AttachInfo info, int visibility) {
...
if (mRunQueue != null) {
mRunQueue.executeActions(info.mHandler);
mRunQueue = null;
}
...
}
在View被add之后会调用dispatchAttachedToWindow方法,然后调用mRunQueue.executeActions,接下来我们看看executeActions方法④,最终还是调用了AttachInfo的mHandler执行action,至此View.post的大体流程就梳理完了。