Activity 启动 和 Window

发布于 2025-01-27 02:55:32 字数 3271 浏览 8 评论 0

问题

  • 一个进程启动后创建的第一个对象是什么?
  • 一个 Activity 在 onCreate 里调 startActivity 跳转后第二个 Activity 后,生命周期怎么回调?为什么?
  • 一个 Activity 在 onCreate 里 不调用 setContentView(),直接调 finish() 生命周期怎么回调?为什么?
  • DecorView 包括哪些 view?
  • 启动文章
  • setContentView 文章

Activity 的 attach()

  1. attachBaseContext
  2. new PhoneWindow
  3. setWindowManager

Window

Window 是一个抽象的概念,每一个 Window 都对应着一个 View 和一个 ViewRootImpl,Window 和 View 通过 ViewRootImpl 来建立联系,因此 Window 并不是不存在的,它是以 View 的形式存在。这点从 ViewManager 的定义也可以看得出来,它只提供三个接口方法:addView、updateViewLayout、removeView,这些方法都是针对 View 的,所以说 Window 是 View 的直接管理者。

回顾 window.addview()

WmS 运行在单独的进程中。这里 IWindowSession 执行的 addtoDisplay 操作应该是 IPC 调用。接下来的 Window 添加过程, 我们会知道每个 window 创建时,最终都会创建一个 ViewRootImpl 对象。

ViewRootImpl 是一很重要的类,类似 ApplicationThread 负责跟 AmS 通信一样,ViewRootImpl 的一个重要职责就是跟 WmS 通信,它通静态变量 sWindowSession(IWindowSession 实例)与 WmS 进行通信。

每个应用进程,仅有一个 sWindowSession 对象 ,它对应了 WmS 中的 Session 子类,WmS 为每一个应用进程分配一个 Session 对象。WindowState 类有一个 IWindow mClient 参数,是由 Session 调用 addToDisplay 传递过来的,对应了 ViewRootImpl 中的 W 类的实例。

简单的总结一下,ViewRootImpl 通过 IWindowSession 远程 IPC 通知 WmS,并且由 W 类接收 WmS 的远程 IPC 通知。(这个 W 类和 ActivityThread 的 H 类同样精悍的命名,并且也是同样的工作职责!

WindowManagerGlobal

一个进程就只有一个 WindowManagerGlobal 对象

  • WindowManagerGlobal 存储的东西:
    //存储所有 Window 对应的 View
    private final ArrayList<View> mViews = new ArrayList<View>();

    //存储所有 Window 对应的 ViewRootImpl
    private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();

    //存储所有 Window 对应的布局参数
    private final ArrayList<WindowManager.LayoutParams> mParams =
            new ArrayList<WindowManager.LayoutParams>();

    //存储正被删除的 View 对象(已经调用 removeView 但是还未完成删除操作的 Window 对象)     
    private final ArraySet<View> mDyingViews = new ArraySet<View>();
  • Token:在源码中 token 一般代表的是 Binder 对象,作用于 IPC 进程间数据通讯。并且它也包含着此次通讯所需要的信息,在 ViewRootImpl 里,token 用来表示 mWindow(W 类,即 IWindow),并且在 WmS 中只有符合要求的 token 才能让 Window 正常显示。 这也是为什么 dialog 必须要传入 Activity 的 Context,因为它有 token。
    • 应用窗口 : token 表示的是 activity 的 mToken(ActivityRecord)
    • 子窗口 : token 表示的是父窗口的 W 对象,也就是 mWindow(IWindow)

WindowManagerGlobal.addview

  1. 调整布局参数,并设置 token
  2. 找到父窗口的 token(viewRootImpl 的 W 类,也就是 IWindow)
  3. 创建 ViewRootImpl,并且将 view 与之绑定。 此时 new W(this),用来接收 WmS 消息
  4. 通过 ViewRootImpl 的 setView 方法,完成 view 的绘制流程(performTraversals 的三部曲),并添加到 window 上。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

流年已逝

暂无简介

文章
评论
26 人气
更多

推荐作者

十二

文章 0 评论 0

飞烟轻若梦

文章 0 评论 0

OPleyuhuo

文章 0 评论 0

wxb0109

文章 0 评论 0

旧城空念

文章 0 评论 0

-小熊_

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文