WindowManager添加View需要Window/PhoneWindow吗?

44 阅读2分钟

答案是:完全不需要。

这是最关键的区别。WindowPhoneWindowActivity/Dialog窗口体系的专属设计,用于构建一个符合Android应用设计规范的窗口(带有DecorView、ActionBar、内容区域等)。

而当你不通过Activity,直接使用WindowManager.addView()时,你走的是另一条更底层、更直接的路径。你跳过了整个PhoneWindow的包装和构建过程,直接告诉系统:“我这里有一个View,请把它当作一个独立的窗口显示出来”。


角色再澄清:Window vs. PhoneWindow

为了更直观地理解整个体系,特别是关键组件WindowPhoneWindow的定位,可以参考下面的Android窗口系统层级图:

deepseek_mermaid_20250820_6c42f1.png

如上图所示,Window/PhoneWindow体系(右侧)和直接使用WindowManager(左侧)是两条独立的路径。它们最终都汇入WindowManager这个入口,但左侧路径更为直接和底层。

所以,WindowPhoneWindow可以看作是高级API,用于常规的、功能完整的应用界面;而直接使用WindowManager.addView()低级API,用于实现悬浮窗、自定义弹幕等需要精确控制的特殊显示效果。


总结:回答你的三个问题

  1. 添加到哪里去了?
    没有添加到任何Activity的视图树里。而是由WindowManager创建了一个新的、独立的窗口,这个View就是这个窗口的根视图。这个窗口由系统服务WindowManagerService (WMS)直接管理。
  2. 为何能显示出来?
    因为WMS为这个新窗口分配了一块独立的Surface(画布)ViewRootImpl负责驱动View在这块画布上进行绘制,最后由SurfaceFlinger将这块画布和其他所有窗口的画布合成,最终输出到屏幕。它的层级由LayoutParams中的type决定,因此可以悬浮。
  3. 需要Window和PhoneWindow吗?
    完全不需要。  WindowPhoneWindow是Activity/Dialog体系的专属高级封装。直接使用WindowManager.addView()是绕过它们的一种低级操作方式,两者属于不同的技术路径。你只需要一个创建好的View对象和配置好的WindowManager.LayoutParams参数即可。