文章目录
- [基础层(6 题)](#基础层(6 题))
-
- [#1 Window、DecorView、PhoneWindow 是什么关系? 🔥](#1 Window、DecorView、PhoneWindow 是什么关系? 🔥)
- [#2 WindowManager 的职责是什么?addView/removeView 流程? 🔥](#2 WindowManager 的职责是什么?addView/removeView 流程? 🔥)
- [#3 Window 有哪些常见类型(Type)? ⭐](#3 Window 有哪些常见类型(Type)? ⭐)
- [#4 DecorView 与 ContentView(android.R.id.content)区别? ⭐](#4 DecorView 与 ContentView(android.R.id.content)区别? ⭐)
- [#5 WindowInsets 是什么?包含哪些部分? ⭐](#5 WindowInsets 是什么?包含哪些部分? ⭐)
- [#6 Edge-to-Edge 是什么?为什么要做? 💡](#6 Edge-to-Edge 是什么?为什么要做? 💡)
- [进阶层(6 题)](#进阶层(6 题))
-
- [#7 WindowManager.LayoutParams 的 flags 常用有哪些? 🔥](#7 WindowManager.LayoutParams 的 flags 常用有哪些? 🔥)
- [#8 fitsSystemWindows 与 WindowInsets 迁移路径? 🔥](#8 fitsSystemWindows 与 WindowInsets 迁移路径? 🔥)
- [#9 WindowInsetsController 能做什么? 🔥](#9 WindowInsetsController 能做什么? 🔥)
- [#10 Dialog 与 PopupWindow 的 Window 差异? ⭐](#10 Dialog 与 PopupWindow 的 Window 差异? ⭐)
- [#11 Dialog 的 Window Token 机制? ⭐](#11 Dialog 的 Window Token 机制? ⭐)
- [#12 WindowInsets 动画(InsetsAnimation)解决什么? 💡](#12 WindowInsets 动画(InsetsAnimation)解决什么? 💡)
- [核心层(6 题)](#核心层(6 题))
-
- [#13 RootWindowContainer 与 WMS 的窗口层级? 🔥](#13 RootWindowContainer 与 WMS 的窗口层级? 🔥)
- [#14 Edge-to-Edge 完整适配要点? 🔥](#14 Edge-to-Edge 完整适配要点? 🔥)
- [#15 Window 焦点与输入事件如何衔接? ⭐](#15 Window 焦点与输入事件如何衔接? ⭐)
- [#16 多窗口模式下 Window 管理有何不同? ⭐](#16 多窗口模式下 Window 管理有何不同? ⭐)
- [#17 ViewRootImpl 在 Window 链路中的位置? 💡](#17 ViewRootImpl 在 Window 链路中的位置? 💡)
- [#18 Window 机制完整链路口述? 💡](#18 Window 机制完整链路口述? 💡)
- 面试策略速查
- 完整链路一句通
- 相关推荐
基础层(6 题)
#1 Window、DecorView、PhoneWindow 是什么关系? 🔥
参考回答
Window 是抽象窗口策略;PhoneWindow 是 Activity 默认实现,内部持有 DecorView(根 FrameLayout,含 TitleView 与 android.R.id.content)。setContentView 实际加到 content 子容器。每个 Activity 一个 PhoneWindow,通过 ViewRootImpl 与 WMS 中 WindowState 关联。
面试官可能继续追问
-
Android 工程里 Dialog 的 Window 和 Activity 区别?
Dialog 自有 PhoneWindow/DecorView,Token 依附宿主 Activity,类型常为 TYPE_APPLICATION_PANEL。
-
没有 Activity 能有 Window 吗?
可以;悬浮窗、Toast、System Alert 等用 Application Context+对应 Type,受权限与 BAL 约束。
#2 WindowManager 的职责是什么?addView/removeView 流程? 🔥
参考回答
WindowManager 继承 ViewManager,负责向 WMS 添加/更新/移除窗口 Surface。addView 创建 ViewRootImpl,经 Binder 在 system_server 注册 WindowState、分配 SurfaceControl,并建立 Choreographer 与 Input 通道。updateViewLayout 改 LayoutParams;removeView 释放 Surface 与 Input 通道。
面试官可能继续追问
-
Android 里 BadTokenException 什么原因?
Activity 已 finish 仍 show Dialog/PopupWindow,或 Token 无效时 addView。
-
WindowManager 和 WMS 是一回事吗?
应用侧接口是 WindowManager;WMS 是 system_server 服务,二者经 Binder 通信。
#3 Window 有哪些常见类型(Type)? ⭐
参考回答
TYPE_APPLICATION :Activity 主窗口。TYPE_APPLICATION_PANEL/SUB_PANEL :Dialog、Popup。TYPE_APPLICATION_OVERLAY :悬浮窗(需权限)。TYPE_STATUS_BAR/TYPE_NAVIGATION_BAR 等系统层。Type 决定 Z-order、触摸区域与权限策略;应用层主要用 APPLICATION 系列。
面试官可能继续追问
-
Android 悬浮窗 TYPE_APPLICATION_OVERLAY 注意什么?
API 26+ 需
SYSTEM_ALERT_WINDOW;Android 12+ 后台启动受限,勿替代 FGS 做长期悬浮。 -
Toast 的 Window Type?
内部用 TYPE_TOAST 或等价层级,不需应用 addView,系统代理展示。
#4 DecorView 与 ContentView(android.R.id.content)区别? ⭐
参考回答
DecorView 是窗口根 View,包含系统装饰(ActionBar/状态栏占位等)与 content 容器。setContentView 填充的是 content 子 View,非 DecorView 本身。Insets 分发从 DecorView 向下;Edge-to-Edge 常在 DecorView 层处理系统栏 inset。
面试官可能继续追问
-
Android 里 fitSystemWindows 加在哪层?
历史加 DecorView/content;现代改
WindowInsetsAPI 在根布局或 ComposeModifier.systemBarsPadding。 -
全屏时 content 会延伸到状态栏下吗?
Edge-to-Edge 下会;需处理 Insets 避免可点击内容被遮挡。
#5 WindowInsets 是什么?包含哪些部分? ⭐
参考回答
WindowInsets 描述窗口相对系统 UI 的内边距:statusBars、navigationBars、ime、displayCutout、systemGestures、tappableElement 等。Android 11+ 用 WindowInsetsCompat 分型获取;可监听 inset 动画。替代过时的 fitsSystemWindows 与手动 statusBar 高度计算。
面试官可能继续追问
-
Android 里键盘弹出怎么监听 Insets?
View.setOnApplyWindowInsetsListener或 ComposeimePadding(),读Insets.Type.ime()。 -
cutout(刘海)属于哪种 Inset?
displayCutout;需与 statusBars 一并处理避免内容进缺口。
#6 Edge-to-Edge 是什么?为什么要做? 💡
参考回答
Edge-to-Edge 让应用内容绘制到系统栏后方,由应用通过 Insets 自行留白或沉浸。Google 从 Android 15 起强制倾向;需 WindowCompat.setDecorFitsSystemWindows(window, false) 并处理 status/nav/ime inset。提升屏效与一致视觉,但须防手势冲突与可读性。
面试官可能继续追问
-
Android 工程里 Edge-to-Edge 第一步?
Activity 启用 decorFitsSystemWindows=false,根布局/onApplyWindowInsets 消费 padding。
-
Compose 还要管 Edge-to-Edge 吗?
要;
enableEdgeToEdge()+Scaffold insets 参数,与 XML 同等必要。
进阶层(6 题)
#7 WindowManager.LayoutParams 的 flags 常用有哪些? 🔥
参考回答
FLAG_FULLSCREEN :隐藏状态栏。FLAG_LAYOUT_NO_LIMITS :可超出屏幕。FLAG_NOT_FOCUSABLE :不抢焦点(如悬浮层)。FLAG_DIM_BEHIND :Dialog 背景变暗。FLAG_SECURE:防截屏。flags 与 type、format、softInputMode 共同决定窗口行为,错误组合导致无法输入或触摸穿透。
面试官可能继续追问
-
Android 里 Dialog 背景点击关闭怎么设?
setCanceledOnTouchOutside+合适 flags;勿用 NOT_FOCUSABLE 导致内部 EditText 无法聚焦。 -
secure flag 能防所有录屏吗?
防常规截屏/录屏;系统级或硬件外设仍可能泄露,敏感页还需业务层保护。
#8 fitsSystemWindows 与 WindowInsets 迁移路径? 🔥
参考回答
fitsSystemWindows 由 Framework 自动加 padding/margin,行为不透明且与 Edge-to-Edge 冲突。现代方案:setDecorFitsSystemWindows(false)+手动 WindowInsetsCompat 分发;Material EdgeToEdge.enable 封装常见场景。CoordinatorLayout 等仍可能内部兼容旧 API,新代码应显式 Insets。
面试官可能继续追问
-
Android 旧项目怎么渐进迁移 Edge-to-Edge?
逐 Activity 开 decorFits false,用 Material 组件 insets 辅助,回归测试键盘与手势导航。
-
Fragment 里谁处理 Insets?
通常在 Activity Window 层统一;Fragment 根 View 监听 applyWindowInsets 二次分发。
#9 WindowInsetsController 能做什么? 🔥
参考回答
控制 system bars 外观与行为:hide/show statusBars/navigationBars、setSystemBarsBehavior(immersive sticky 等)、setAppearanceLightStatusBars 图标深浅色。Android 11+ 替代 systemUiVisibility。与 Edge-to-Edge 配合实现沉浸阅读、全屏视频。
面试官可能继续追问
-
Android 里沉浸视频退出后栏不回来?
onWindowFocusChanged或播放结束调show(statusBars|navigationBars),避免 stuck hidden。 -
light status bar 和 dark 区别?
控制状态栏图标/文字对比度,适配浅色/深色顶栏背景。
#10 Dialog 与 PopupWindow 的 Window 差异? ⭐
参考回答
Dialog :独立 Window+DecorView,Modal 语义,走 FragmentManager/AlertDialog;Token 绑 Activity。PopupWindow:轻量浮层,常无 Modal 阻塞,可锚定 View;也可设 focusable/touchable。二者都经 WindowManager addView,Type 多为 PANEL;Dialog 生命周期需随 Activity dismiss。
面试官可能继续追问
-
Android 里 PopupWindow 泄漏怎么防?
Activity destroy 前
dismiss();勿用已销毁 Activity Context 创建。 -
BottomSheetDialogFragment 底层是什么?
基于 Dialog+Material 行为,Window inset 与拖拽由 Design 库处理。
#11 Dialog 的 Window Token 机制? ⭐
参考回答
Dialog 必须持有有效 Activity Window Token 才能 addView;Token 标识 WMS 中父 Window。Activity finish 后 Token 失效。ContextThemeWrapper 须来自活跃 Activity;Application Context 建 Dialog 会 BadTokenException(除非系统窗口 Type+权限)。
面试官可能继续追问
-
Android 旋转屏 Dialog 消失原因?
默认随配置重建;用
DialogFragment+setRetainInstance/ViewModel 或onSaveInstanceState恢复。 -
show Dialog 在 onSaveInstanceState 之后?
可能 IllegalStateException;改
commitAllowingStateLoss或延后到 RESUMED。
#12 WindowInsets 动画(InsetsAnimation)解决什么? 💡
参考回答
键盘弹出/收起时 Inset 连续变化;WindowInsetsAnimation.Callback 让 View 同步 translation/padding 而非跳变。WindowInsetsAnimationCompat 支持交互式 IME 跟手。改善 Chat/搜索框与键盘共存的 UX,减少 layout 跳闪。
面试官可能继续追问
-
Android 聊天页键盘跟手怎么实现?
注册 InsetsAnimation.Callback,按 interpolatedInsets 调整输入栏 translationY。
-
和 adjustResize/adjustPan 关系?
softInputMode 仍影响整体行为;动画 API 细粒度补平滑,二者可组合。
核心层(6 题)
#13 RootWindowContainer 与 WMS 的窗口层级? 🔥
参考回答
WMS 在 system_server 中以 RootWindowContainer 为根,下挂 DisplayContent→TaskDisplayArea→WindowToken→WindowState,与 ATMS 的 Task/ActivityRecord 对齐。SurfaceControl 层级决定 Z-order 与合成。应用 addView 最终在 WindowState 注册,非过时的「WindowManagerService 平铺列表」口述。
面试官可能继续追问
-
Android 面试里 WindowState 和 Surface 关系?
每个 WindowState 关联 SurfaceControl,SurfaceFlinger 按层级合成。
-
多 Display 扩展屏 Window 放哪?
对应 DisplayContent 下 TaskDisplayArea,ATMS/WMS 协同分配。
#14 Edge-to-Edge 完整适配要点? 🔥
参考回答
启用:decorFitsSystemWindows=false+enableEdgeToEdge()。处理:status/nav/ime/cutout 四类 Inset;手势导航区 systemGestures 留热区;对比度不足时 scrim。测试:键盘、Dialog、WebView 全屏、横竖屏、分屏。Android 15+ target 默认倾向 Edge-to-Edge,ignore 会导致内容被栏遮挡。
面试官可能继续追问
-
Android 列表最后一项被导航栏挡?
RecyclerView paddingBottom=navigationBars inset;Compose 用
navigationBarsPadding。 -
Edge-to-Edge 后状态栏文字看不清?
调
WindowInsetsControllerlight/dark appearance 或加顶栏 scrim。
#15 Window 焦点与输入事件如何衔接? ⭐
参考回答
WMS 维护焦点 Window;InputDispatcher 将事件发到焦点 Window 的 InputChannel→ViewRootImpl→DecorView 分发。Dialog 获焦点时下层 Activity 失焦但不一定 Stop。FLAG_NOT_FOCUSABLE 窗口不参与焦点竞争。ANR 输入超时与焦点 Window 主线程处理相关。
面试官可能继续追问
-
Android 里点击穿透到下层 Activity?
上层 Window 设 NOT_TOUCHABLE 或透明区域不消费;Popup 错误 flags 会导致。
-
焦点和 IME 关系?
IME 也是 Window;焦点 EditText 触发 IME Window 显示,Insets 联动。
#16 多窗口模式下 Window 管理有何不同? ⭐
参考回答
分屏/自由窗口下各 Activity Window 在独立 TaskDisplayArea/窗口容器,尺寸非全屏;Insets 随窗口 bounds 变化。PiP 窗口独立 Type 与尺寸策略。WMS 按 DisplayArea 裁剪 Surface;Focus 可在多 Resume Window 间切换。适配需 onMultiWindowModeChanged 与 Insets 重算。
面试官可能继续追问
-
Android 分屏下 Dialog 显示在哪?
仍在宿主 Activity Window 层,bounds 受分屏格约束,可能需缩小或滚动。
-
自由窗口 resize 触发什么?
configuration 变化+Insets 更新,可能走 onConfigurationChanged 或 layout 回调。
#17 ViewRootImpl 在 Window 链路中的位置? 💡
参考回答
ViewRootImpl 连接 DecorView 与 WMS/Choreographer:performTraversals 驱动 measure/layout/draw,Surface 提交给 SurfaceFlinger;注册 InputChannel 接收触摸/键。addView 时创建,removeView 销毁。是应用侧 Window 与系统合成的枢纽。
面试官可能继续追问
-
Android 性能里 ViewRootImpl 看什么?
Systrace
traversal、DrawFrame耗时;掉帧从 ViewRoot 主线程路径查。 -
和 SurfaceView 关系?
SurfaceView 独立 Surface Z-order 在 Window 之下或之上,ViewRoot 协调合成。
#18 Window 机制完整链路口述? 💡
参考回答
Activity→PhoneWindow→DecorView→ViewRootImpl→WMS addWindow→RootWindowContainer 层级→SurfaceControl 合成→Insets 下发→Input 焦点分发。Dialog/Popup 复用 addView 路径不同 Type/Token。Edge-to-Edge 改 decorFits 与 Insets 消费;现代勿用过时 fitsSystemWindows 单一路径。
面试官可能继续追问
-
Android 面试 Window 和 Activity 怎么分界?
Activity 管生命周期与逻辑;Window 管可见 Surface、Insets、焦点与 Z-order。
-
下一篇 View 衔接点?
DecorView 内 View 树 measure/layout/draw 与事件分发在 View 篇展开。
面试策略速查
| 面试等级 | 建议掌握 |
|---|---|
| 初级 | ★★★☆☆ |
| 中级 | ★★★★☆ |
| 高级 | ★★★★★ |
必背知识(🔥)
DecorView 结构、WindowManager addView、LayoutParams flags、fitsSystemWindows 迁移、RootWindowContainer、Edge-to-Edge 完整适配
高频追问
「Dialog Token 失效」「Edge-to-Edge 怎么做」「Insets 有哪些类型」「Popup 和 Dialog 区别」「BadTokenException 原因」
加分项(💡)
Edge-to-Edge 动机、Insets 动画、ViewRootImpl 位置、完整链路口述
容易踩坑
Application Context show Dialog;忽略 ime inset;只设 fullscreen 不处理 cutout;过时 fitsSystemWindows;混淆 WindowManager 与 WMS
完整链路一句通
Window 一条线:PhoneWindow 持 DecorView→ViewRootImpl addView→WMS/RootWindowContainer 注册 WindowState→Surface 合成→Insets 下发→Input 焦点至 DecorView→Edge-to-Edge 关 decorFits 手动消费 Inset→Dialog/Popup 复用同路径不同 Type/Token。
