Android S(31) APP 页面绘制流程

接上一篇app 启动流程调用OnCreate方法,页面布局绘制进入setContentView

1、加载布局setContentView()

Android S(31) APP 页面绘制流程_第1张图片

这里getWindow()直接返回mWindow,这个早在onCreate 调用前Activity#attach里面完成初始化。

Android S(31) APP 页面绘制流程_第2张图片

进入attach方法,构建一个窗体对象PhoneWindow。

Android S(31) APP 页面绘制流程_第3张图片

Android S(31) APP 页面绘制流程_第4张图片  Android S(31) APP 页面绘制流程_第5张图片

进入mWindow.setWindowManager方法,mWindowManager 并不是WMS,而是一个WindowManagerImpl 对象,WindowManagerImpl 专注于与WMS 通信,作为WPS 在APP 中 代表,跟IApplicationThread作用差不多。

 综上setContentView的实际入口在PhoneWindow#setContentView,installDecor方法是根据主题绘制页面根部布局mDecor,也就是顶层View。mContentParent是传入的activity_main呈现的用户布局。

Android S(31) APP 页面绘制流程_第6张图片

 用户布局绘制 在mLayoutInflater.inflate(layoutResID, mContentParent),进入LayoutInflater#inflate方法,createViewFromTag 创建activity_main的顶层布局,

rInflateChildren是递归调用,绘制顶层view下面的子view,这也是为啥XML布局嵌套层数越多,可能会导致栈溢出,因为递归是不会释放栈的。

Android S(31) APP 页面绘制流程_第7张图片

2、添加view到窗体 wm.addView()

到此 setContentView分析结束,布局view 还没有添加到窗体,上面图一知道onCreate 结束后会调用到ActivityThread的handleResumeActivity,wm.addView(decor, l)这里把根布局添加到WM。

 Android S(31) APP 页面绘制流程_第8张图片

Android S(31) APP 页面绘制流程_第9张图片

 上面说到wm 就是WindowManagerImpl对象实例,这里遇到个坑AS 里面的源码WindowManagerImpl是没有WindowManagerGlobal的,addView 是空的,就是下面这样,

 Android S(31) APP 页面绘制流程_第10张图片

Android S(31) APP 页面绘制流程_第11张图片

 查看在线源码实际上,WindowManagerImpl#addView 方法调用WindowManagerGlobal#addView,如下

Android S(31) APP 页面绘制流程_第12张图片

 Android S(31) APP 页面绘制流程_第13张图片

 进入WindowManagerGlobal#addView,看到设置view的地方就在root.setView,也就是ViewRootImpl#setView,setContentView加载的xml 构建实例会统一交给ViewRootImpl管理。另外这里view.assignParent(this), ViewRootImpl本身持有view,这句代码让view反向 持有ViewRootImpl,后续会用到。

Android S(31) APP 页面绘制流程_第14张图片

3、页面绘制performTraversals()

 进入ViewRootImpl#setView 这里面重点看requestLayout(),scheduleTraversals()就好。

Android S(31) APP 页面绘制流程_第15张图片

Android S(31) APP 页面绘制流程_第16张图片

Android S(31) APP 页面绘制流程_第17张图片

 真正绘制的方法是performTraversals(),上面Choreographer  的发起postcallback绘制请求管理绘制的节奏,内容比较复杂,现在就不展开说了。

 Android S(31) APP 页面绘制流程_第18张图片

 performTraversals()-> relayoutWindow()-> mWindowSession.relayout(),sWindowSession为传入参数WindowManagerGlobal.getWindowSession(),是一个binder 代理类,通过WindowManagerService#openSession中 new Session 得到,所以实现在Session #relayout(),里面又调用WindowManagerService#relayoutWindow(),这个方法的作用是在WMS 保存窗体的相关信息,且对于窗体的可见性如果有变更则需要重新计算。

Android S(31) APP 页面绘制流程_第19张图片

WindowManagerService#relayoutWindow() ->createSurfaceControl() 创建 C++ 层的Surface。

Android S(31) APP 页面绘制流程_第20张图片

综上,relayoutWindow 处理了两件事,1是保存信息到WMS或者根据可见性重新计算坐标等数据, 2去底层申请一个Surface,并返回地址回来。

performTraversals()方法中,接下来走performMeasure->performLayout->performDraw,view 的工作流程就结束了。

 Android S(31) APP 页面绘制流程_第21张图片

 

 

你可能感兴趣的:(android)