【Android 13源码分析】WMS-添加窗口(addWindow)流程-1-应用进程处理

💡 原文中文,约19800字,阅读约需48分钟。
📝

内容提要

本文介绍了Android中Activity的addWindow流程,包括创立WindowState、relayout和finishDrawing三个过程。文章详细解释了APP进程中addWindow的流程,包括创立Window、设置WindowManager、调用addView等步骤。最后,文章提到了ViewRootImpl的setView方法触发了跨进程通讯,将后续流程交给了WMS处理。

🔎

延伸解读

窗口显示的三步流程

文章指出,一个窗口要显示在屏幕上,必须经历addWindow、relayout和finishDrawing三个过程。addWindow负责创建WindowState并挂载到窗口树;relayout触发Surface创建和窗口位置摆放;finishDrawing将UI数据合成并显示。绝大多数情况下,这三步是必经流程,只有开机动画等少数场景直接通过SurfaceFlinger制作。理解这一整体流程有助于定位窗口显示问题。

onResume与UI显示的差异

根据调用链,Activity先执行onResume,再执行addView。因此,onResume仅表示Activity可见,并不代表View已经显示。如果后续addView或WMS处理出现问题,XML布局可能不会显示。这提醒开发者,不能简单认为onResume执行后UI就一定可见,需要关注窗口添加的后续流程。

关键类与职责区分

文章强调要理清Window、PhoneWindow、WindowManagerImpl和WindowManagerGlobal的区别。Activity中的Window实际是PhoneWindow,是Window的唯一子类;WindowManagerImpl是Window的成员,负责调用WindowManagerGlobal;WindowManagerGlobal是进程单例,管理所有窗口的添加,内部维护mViews、mRoots和mParams三个集合,并创建ViewRootImpl。混淆这些类容易导致源码分析错误。

跨进程通信的起点

ViewRootImpl::setView是APP进程处理addWindow的终点。它通过mWindowSession(即Session对象)调用addToDisplayAsUser,进而跨进程调用WMS的addWindow方法。同时,setView还触发requestLayout和computeFrames等操作。虽然addWindow流程在代码顺序上似乎先于relayoutWindow,但由于doTraversal是异步的,实际仍先执行addWindow。理解这一点对掌握窗口添加时序很重要。

❓

Q&A

Android中addWindow流程的主要步骤是什么?

addWindow流程主要包括创立WindowState、relayout和finishDrawing三个步骤。

在addWindow流程中,relayout的作用是什么?

relayout流程触发Surface的创立,并进行窗口位置的摆放逻辑。

ViewRootImpl的setView方法在addWindow流程中起什么作用?

setView方法触发跨进程通讯,通知WMS执行addWindow逻辑。

APP进程在addWindow流程中执行哪些操作?

APP进程在addWindow流程中执行onCreate和onResume生命周期,创立Window并调用addView。

WindowManagerGlobal在addWindow流程中有什么作用?

WindowManagerGlobal是单例,负责管理窗口的添加和处理,调用addView方法。

addWindow流程中,finishDrawing的作用是什么?

finishDrawing流程将UI数据合成并显示到屏幕上。

🏷️

标签

➡️

继续阅读