美文网首页
Android Activity 生成 View 过程

Android Activity 生成 View 过程

作者: 1999c1b720cd | 来源:发表于2018-03-05 23:01 被阅读0次

    前言

    在梳理 Android 必备知识过程中,想理解 Activity.setContentView 之后到显示出 View 的过程背后到底干了什么,将阅读和分析完源码之后知识点输出到博客进行记录和备忘

    问题

    • 如果让你实现 WMS,你怎么做
    • 如果让你实现 WMGlobal,你怎么做
    • WMS 如何管理 Window
    • Window 如何管理 View
    • 如果让你修改 WMS 的代码,你能改吗

    数据结构

    Client / Server 模型

    • Server 端 WindowManagerService 对象
    • Client 端 Session 对象
    • Client 和 Server 之间通过 Binder 进行 IPC 通信

    结构图

    Server 端

    wms.server.png

    Client 端

    wms.client.png

    UML 类图

    WMS.addWindow.png
    • 蓝色代表 SystemServer 进程空间,白色代表 App 进程空间
    • WMS 内部记录所有 Session 和 WindowState 对象信息,是整个 Window 信息处理的中心
    • Session 是 WMS 看到的 App 进程,某一 App 进程内的所有 Window 都属于同一个 Session 对象
    • WindowState 是 WMS 管理 Window 的单元,本身是树形结构,即 Window 树。它记录自己从属的 Session 和 App 端的 IWindow Binder 对象
    • WindowManagerGlobal 是 App 进程的 WindowManager 真正干活的类,记录当前进程空间内所有 Window 的 DecorView、ViewRootImpl、LayoutParams 以及 WMS 的 Binder 代理和 Session 信息
    • WindowManagerImpl 是 WindowManager 接口的实现类,每个 Window 都有独立的 WindowManagerImpl 实例
    • PhoneWindow 是 Window 的实现类,记录 DecorView
    • ViewRootImpl 是控件树的祖先节点,负责与 WMS 通信
    • DecorView 是 Window 的根 View,负责装饰开发者的 View
    • IWindow 是一个 Binder ,用于 WMS 与 App 进程间 Window 的通信,它的 API 运行在 Binder 线程池中,需要通过 ViewRootImpl 内部的 Handler 切换到主线程执行
    • Activity 是用户活动,记录 Window 和 WindowManager

    基本操作

    UML 序列图


    Activity.setContentView.png
    • Activity 对象转发 setContentView 消息给内部 PhoneWindow
    • PhoneWindow 创建 DecorView,先把输入 View 挂到一个 LinearLayout 下,再把 LinearLayout 挂到 DecorView 下面。到这里 App 空间的控件树已经绑定完毕
    • ActivityThread 收到 AMS 的 scheduleResumeActivity 消息并从 Binder 线程池中通过
      Handler 调度到主线程后给 ActivityThread 发送 handleResumeActivity 消息
    • Activity 收到 onResume 之后,由 ActivityThread 判断 Activity 的窗口未添加(mWindowAdded 为 false),此时向 WindowManagerImpl 发送 addView 消息
    • WindowManagerImpl 把消息转发给 WindowManagerGlobal 对象
    • WindowManagerGlobal 负责创建 ViewRootImpl,并且把 View, ViewRootImpl, LayoutParams 三个信息保存在其内部的数组中
    • ViewRootImpl 通过 Binder IPC 向 WMS 请求 openSession ,拿到 WMS 创建的 Session Binder 对象的代理
    • ViewRootImpl 创建 IWindow.Stub Binder 对象,用于传给 WMS 标识一个 Window 对象
    • ViewRootImpl 收到 setView 信息,开始第一次 requestLayout, 异步刷新布局
    • ViewRootImpl 向 mWindowSession Binder Proxy 对象发送 addToDisplay 消息,参数是 IWindow Binder 对象
    • SystemServer 进程 Session Binder 实体对象收到 addToDisplay 消息,告诉 WMS addWindow 消息
    • WMS 创建 WindowState 对象封装 App 进程传递过来的 IWindow Binder 对象,把 WindowState 记录在内部的 mWindowMap 映射表里面,并向 WindowState 对象发送 attach 消息
    • WindowState 向 Session 发送 windowAddedLocked 消息
    • Session 收到消息后把自己记录在 WMS 的 mSessions 数组里面,到这里 WMS 已经记录了 App 的一个 IWindow 对象
    • 接下来就是 ViewRootImpl 收到 performTraverse 进行整个控件树的 measure , layout, draw 信息处理
    • 锁住 Surface 对象,通过 Canvas 对象进行渲染,解锁后发送到显存供显卡读取显示

    练习题

    • 单步跟踪 App 进程和 SystemServer 进程的 Window 添加流程
    • 理解 Window, DecorView, ViewRootImpl, Session, IWindow, WindowState 的创建时机
    • 画出 UML 类图,理解数据结构
    • 画出 UML 序列图,理解消息的处理过程
    • 按模块分析 WMS 添加、删除、更新 Window 的过程

    总结

    • 在理清相关数据结构的前提下,跟踪信息传递过程,抓关键对象的创建和绑定时机,理解 Window 的添加过程

    相关文章

      网友评论

          本文标题:Android Activity 生成 View 过程

          本文链接:https://www.haomeiwen.com/subject/yhlqfftx.html