当DecorView
加入到WindowManager
,并且ViewRootImpl
第一次调用performTraversals
时,会调用DecorView
的dispatchAttachedToWindow
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.dispatchAttachedToWindow
将ViewRootImpl
中创建的AttachInfo
传入View
的mAttachInfo
中,AttachInfo
中有一个变量mTreeObserver
保存了ViewTreeObserver
实例,View
的getViewTreeObserver
方法可以返回这个实例对象
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() {
}
});
这些事件的调用是在ViewRootImpl
的performTraversals
中发送的:
ViewRootImpl.performTraversals
private void performTraversals() {
.....
mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(true);
.....
mAttachInfo.mTreeObserver.dispatchOnGlobalLayout();
}
另外整个View Hierarchy的AttachInfo都指向ViewRootImpl中创建的同一个AttachInfo,下一篇文章研究一下这个AttachInfo