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


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

    1、加载布局setContentView()

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

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

      

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

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

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

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

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

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

     

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

     

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

     

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

    3、页面绘制performTraversals()

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

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

     

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

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

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

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

     

     

     

  • 相关阅读:
    杰理之 DAC详细配置【篇】
    弘君资本今日投资参考:新能源消纳政策加码 智能网联汽车再加速
    Android studio连接MySQL并完成简单的登录注册功能
    考证必看 | PMP扫盲贴+PMP材料
    Linux系统中如何安装生信软件?保姆式全攻略
    对于Java中的Loop或For-each,哪个更快
    sort by 和 order by 的区别
    服务链路追踪 —— SpringCloud Sleuth
    LabVIEW连接PostgreSql
    java基础学习笔记总结
  • 原文地址:https://blog.csdn.net/u012975242/article/details/128117369