ViewRootImpl
2020-01-28 本文已影响0人
couriravant
https://www.jianshu.com/p/847f9a19acd8
在 Activity启动的最后一步,handlerResumeActivity中会把decorview通过addView添加,最终调用ViewRootImpl(),触发requestLayout,绘制decorview。
ViewRootImpl
ViewRootImpl是一个视图层次结构的顶部,它实现了View与WindowManager之间所需要的协议,作为WindowManagerGlobal中大部分的内部实现,也就说WindowManagerGlobal方法最后还是调用到了ViewRootImpl。
addView,removeView,update调用顺序
WindowManagerImpl -> WindowManagerGlobal -> ViewRootImpl
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
requestLayout();
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(), mWinFrame,
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel);
}
在setView方法中,首先会调用到requestLayout(),表示添加Window之前先完成第一次layout布局过程,以确保在收到任何系统事件后面重新布局。requestLayout最终会调用performTraversals方法来完成View的绘制。
接着会通过WindowSession最终来完成Window的添加过程。在下面的代码中mWindowSession类型是IWindowSession,它是一个Binder对象,真正的实现类是Session,也就是说这其实是一次IPC过程,远程调用了Session中的addToDisPlay方法。
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets,
Rect outOutsets, InputChannel outInputChannel) {
return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
outContentInsets, outStableInsets, outOutsets, outInputChannel);
}
这里的mService就是WindowManagerService,也就是说Window的添加请求,最终是通过WindowManagerService来添加的。
WMS会为这个添加的窗口分配Surface,并确定窗口显示次序,可见负责显示画面的画布是Surface,而不是窗口本身。WMS会把它所管理的Surface交给SurfaceFlinger处理,SurfaceFlinger会将这些Surface混合并绘制到屏幕上。