view.post
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;
}
getHandler().post
public Handler getHandler() {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler;
}
return null;
}
其实都是使用的是mAttachInfo里的handler
void dispatchAttachedToWindow(AttachInfo info, int visibility) {
mAttachInfo = info;
if (mOverlay != null) {
mOverlay.getOverlayView().dispatchAttachedToWindow(info, visibility);
}
mWindowAttachCount++;
// We will need to evaluate the drawable state at least once.
mPrivateFlags |= PFLAG_DRAWABLE_STATE_DIRTY;
if (mFloatingTreeObserver != null) {
info.mTreeObserver.merge(mFloatingTreeObserver);
mFloatingTreeObserver = null;
}
registerPendingFrameMetricsObservers();
if ((mPrivateFlags&PFLAG_SCROLL_CONTAINER) != 0) {
mAttachInfo.mScrollContainers.add(this);
mPrivateFlags |= PFLAG_SCROLL_CONTAINER_ADDED;
}
// Transfer all pending runnables.
if (mRunQueue != null) {
mRunQueue.executeActions(info.mHandler);
mRunQueue = null;
}
performCollectViewAttributes(mAttachInfo, visibility);
onAttachedToWindow();
ListenerInfo li = mListenerInfo;
final CopyOnWriteArrayList<OnAttachStateChangeListener> listeners =
li != null ? li.mOnAttachStateChangeListeners : null;
if (listeners != null && listeners.size() > 0) {
// NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
// perform the dispatching. The iterator is a safe guard against listeners that
// could mutate the list by calling the various add/remove methods. This prevents
// the array from being modified while we iterate it.
for (OnAttachStateChangeListener listener : listeners) {
listener.onViewAttachedToWindow(this);
}
}
int vis = info.mWindowVisibility;
if (vis != GONE) {
onWindowVisibilityChanged(vis);
if (isShown()) {
// Calling onVisibilityAggregated directly here since the subtree will also
// receive dispatchAttachedToWindow and this same call
onVisibilityAggregated(vis == VISIBLE);
}
}
// Send onVisibilityChanged directly instead of dispatchVisibilityChanged.
// As all views in the subtree will already receive dispatchAttachedToWindow
// traversing the subtree again here is not desired.
onVisibilityChanged(this, visibility);
if ((mPrivateFlags&PFLAG_DRAWABLE_STATE_DIRTY) != 0) {
// If nobody has evaluated the drawable state yet, then do it now.
refreshDrawableState();
}
needGlobalAttributesUpdate(false);
notifyEnterOrExitForAutoFillIfNeeded(true);
}
dispatchAttachedToWindow是给mAttachInfo赋值的
1.当窗口启动的时候view还没有依附到窗口时,mRunQueue是view内部新建的队列,view.post的对象就被存储在mRunQueue
2.开始依附的时候,先指向外部AttachInfo(其实实现在ViewRootImpl中)
3.dispatchAttachedToWindow的时候,如果发现一个view有mRunQueue,先提交到传入的AttachInfo的handler中去处理
3.后续执行onAttachedToWindow/onVisibilityChanged 这2个方法
4.所有view里的handler就是viewrootimpl里面的ViewRootHandler