Android ViewTreeObserver

DecorView加入到WindowManager,并且ViewRootImpl第一次调用performTraversals时,会调用DecorViewdispatchAttachedToWindow

host.dispatchAttachedToWindow(mAttachInfo, 0);

因为DecorView是ViewGroup,所以会调用ViewGroup的dispatchAttachedToWindow

ViewGroup.dispatchAttachedToWindow

@Override
void dispatchAttachedToWindow(AttachInfo info, int visibility) {
    super.dispatchAttachedToWindow(info, visibility);

    final int count = mChildrenCount;
    final View[] children = mChildren;
    for (int i = 0; i < count; i++) {
        final View child = children[i];
        child.dispatchAttachedToWindow(info,
                combineVisibility(visibility, child.getVisibility()));
    }
}

除了调用父类view的dispatchAttachedToWindow,同时还调用每个child view的dispatchAttachedToWindow

View.dispatchAttachedToWindow

void dispatchAttachedToWindow(AttachInfo info, int visibility) {
   mAttachInfo = info;
   ....
}

View.dispatchAttachedToWindowViewRootImpl中创建的AttachInfo传入ViewmAttachInfo中,AttachInfo中有一个变量mTreeObserver保存了ViewTreeObserver实例,ViewgetViewTreeObserver方法可以返回这个实例对象

public ViewTreeObserver getViewTreeObserver() {
    if (mAttachInfo != null) {
        return mAttachInfo.mTreeObserver;
    }
    if (mFloatingTreeObserver == null) {
        mFloatingTreeObserver = new ViewTreeObserver();
    }
    return mFloatingTreeObserver;
}

ViewTreeObserver的作用就是可以注册一堆Listener,去监听当前View Hierarchy的各种事件,比如focus change, attach, detach, predraw, draw这些事件。比如:

view.getViewTreeObserver().addOnWindowAttachListener(new ViewTreeObserver.OnWindowAttachListene() {
    @Overide
    void onWindowAttached() {
    }
    @Overide
    void onWindowDetached() {
    }
});

这些事件的调用是在ViewRootImplperformTraversals中发送的:

ViewRootImpl.performTraversals

private void performTraversals() {
  .....
  mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(true);
  
  .....

  mAttachInfo.mTreeObserver.dispatchOnGlobalLayout();
}

另外整个View Hierarchy的AttachInfo都指向ViewRootImpl中创建的同一个AttachInfo,下一篇文章研究一下这个AttachInfo

你可能感兴趣的:(Android ViewTreeObserver)