答案是:完全不需要。
这是最关键的区别。Window和PhoneWindow是Activity/Dialog窗口体系的专属设计,用于构建一个符合Android应用设计规范的窗口(带有DecorView、ActionBar、内容区域等)。
而当你不通过Activity,直接使用WindowManager.addView()时,你走的是另一条更底层、更直接的路径。你跳过了整个PhoneWindow的包装和构建过程,直接告诉系统:“我这里有一个View,请把它当作一个独立的窗口显示出来”。
角色再澄清:Window vs. PhoneWindow
为了更直观地理解整个体系,特别是关键组件Window和PhoneWindow的定位,可以参考下面的Android窗口系统层级图:
如上图所示,Window/PhoneWindow体系(右侧)和直接使用WindowManager(左侧)是两条独立的路径。它们最终都汇入WindowManager这个入口,但左侧路径更为直接和底层。
所以,Window和PhoneWindow可以看作是高级API,用于常规的、功能完整的应用界面;而直接使用WindowManager.addView()是低级API,用于实现悬浮窗、自定义弹幕等需要精确控制的特殊显示效果。
总结:回答你的三个问题
- 添加到哪里去了?
没有添加到任何Activity的视图树里。而是由WindowManager创建了一个新的、独立的窗口,这个View就是这个窗口的根视图。这个窗口由系统服务WindowManagerService (WMS)直接管理。 - 为何能显示出来?
因为WMS为这个新窗口分配了一块独立的Surface(画布) 。ViewRootImpl负责驱动View在这块画布上进行绘制,最后由SurfaceFlinger将这块画布和其他所有窗口的画布合成,最终输出到屏幕。它的层级由LayoutParams中的type决定,因此可以悬浮。 - 需要Window和PhoneWindow吗?
完全不需要。Window和PhoneWindow是Activity/Dialog体系的专属高级封装。直接使用WindowManager.addView()是绕过它们的一种低级操作方式,两者属于不同的技术路径。你只需要一个创建好的View对象和配置好的WindowManager.LayoutParams参数即可。