• 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 的工作流程就结束了。

     

     

     

  • 相关阅读:
    Oracle数据库如何定位trace file位置
    淘宝店铺发布API接口(新),淘宝oAuth2.0店铺商品API接口,淘宝商品发布API接口,淘宝商品上架API接口,一整套发布上架店铺接口对接分享
    学习尚硅谷HTML+CSS总结
    剑指offer专项突击版第26天
    LeetCode刷题(python版)——Topic42接雨水
    视觉人机器视觉线下培训遵循十大原则
    Linux------权限篇1)
    李开复和马斯克加入AGI大模型大战 零一万物和Grok有哪些特点
    WPF Panel笔记
    Java遍历map得六种方法
  • 原文地址:https://blog.csdn.net/u012975242/article/details/128117369