diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index 0887372..faf42f7 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -27,12 +27,12 @@ "state": { "type": "markdown", "state": { - "file": "docs/android面试/系统原理/WMS面试.md", + "file": "docs/技术面试问题回答.md", "mode": "source", "source": false }, "icon": "lucide-file", - "title": "WMS面试" + "title": "技术面试问题回答" } } ], @@ -198,10 +198,10 @@ "command-palette:打开命令面板": false } }, - "active": "25c9f7051aac05b3", + "active": "5b497a77c6d68c73", "lastOpenFiles": [ - "docs/Obsidian笔记体系/Projects/saars开发/aiapply/未命名 1.md", "docs/android面试/系统原理/WMS面试.md", + "docs/Obsidian笔记体系/Projects/saars开发/aiapply/未命名 1.md", "docs/Obsidian笔记体系/Projects/saars开发/aiapply/未命名.md", "docs/Obsidian笔记体系/Projects/saars开发/aiapply", "docs/dify/管理员账户.md", diff --git a/docs/技术面试问题回答.md b/docs/技术面试问题回答.md index c4ca200..addbe38 100644 --- a/docs/技术面试问题回答.md +++ b/docs/技术面试问题回答.md @@ -322,3 +322,1483 @@ ## 总结 以上是我基于10年Android开发经验,在Framework层和应用层开发、系统稳定性保障、性能优化、架构设计等方面的技术积累。我具备解决复杂技术问题的能力,能够从系统层面思考问题,提供最优解决方案。同时,我注重团队协作,能够将技术经验分享给团队,共同提升技术水平。 + + + + + +# WMS窗口常见面试题 + + + +本文档整理了Android WMS(Window Manager Service)窗口管理相关的常见面试题,涵盖基础概念、架构原理、源码分析、问题排查等多个方面。 + + + +## 目录 + + + +- [基础概念类](#基础概念类) + +- [架构原理类](#架构原理类) + +- [窗口管理类](#窗口管理类) + +- [源码分析类](#源码分析类) + +- [性能优化类](#性能优化类) + +- [问题排查类](#问题排查类) + +- [多窗口相关](#多窗口相关) + + + +--- + + + +## 基础概念类 + + + +### Q1: 什么是WMS?它的主要职责是什么? + + + +**答案:** + + + +WMS(Window Manager Service)是Android窗口系统的核心服务,运行在system_server进程中。 + + + +**主要职责:** + + + +1. **窗口管理**:管理所有窗口的创建、显示、销毁等生命周期 + +2. **窗口层级管理**:维护窗口的Z-Order顺序,决定窗口的显示优先级 + +3. **布局计算**:计算窗口的位置、大小和可见区域 + +4. **输入事件分发**:将触摸、按键等输入事件分发给正确的窗口 + +5. **窗口动画**:管理窗口的显示、隐藏、切换等动画效果 + +6. **屏幕旋转**:处理屏幕方向变化时的窗口布局调整 + +7. **多显示支持**:支持多个显示设备的窗口管理 + + + +```java + +// WMS是系统服务,在SystemServer中启动 + +public class SystemServer { + +    private void startOtherServices(...) { + +        WindowManagerService wm = WindowManagerService.main(...); + +        ServiceManager.addService(Context.WINDOW_SERVICE, wm); + +    } + +} + +``` + + + +### Q2: WMS与WindowManager、WindowManagerGlobal的关系是什么? + + + +**答案:** + + + +这三者的关系如下: + + + +1. **WindowManager**:应用层接口,开发者使用的API + +2. **WindowManagerGlobal**:应用层实现,管理ViewRootImpl和窗口会话 + +3. **WindowManagerService**:系统服务,实际管理窗口的服务端 + + + +**调用流程:** + + + +``` + +应用层:WindowManager.addView() + +    ↓ + +WindowManagerGlobal.addView() + +    ↓ + +ViewRootImpl.setView() + +    ↓ + +IWindowSession.addToDisplay() (Binder调用) + +    ↓ + +WMS.addWindow() (服务端) + +``` + + + +```java + +// WindowManager接口 + +public interface WindowManager extends ViewManager { + +    void addView(View view, ViewGroup.LayoutParams params); + +    void removeView(View view); + +    void updateViewLayout(View view, ViewGroup.LayoutParams params); + +} + + + +// WindowManagerGlobal实现 + +public final class WindowManagerGlobal { + +    public void addView(View view, ViewGroup.LayoutParams params, ...) { + +        ViewRootImpl root = new ViewRootImpl(view.getContext(), display); + +        root.setView(view, wparams, panelParentView); + +    } + +} + + + +// WMS服务端 + +public class WindowManagerService { + +    public int addWindow(Session session, IWindow client, ...) { + +        // 实际窗口管理逻辑 + +    } + +} + +``` + + + +### Q3: 窗口类型有哪些?它们的层级关系是什么? + + + +**答案:** + + + +**窗口类型:** + + + +1. **应用窗口(APPLICATION)** + +   - `TYPE_APPLICATION`:普通Activity窗口 + +   - `TYPE_APPLICATION_STARTING`:启动窗口 + +   - `TYPE_BASE_APPLICATION`:应用基础窗口 + + + +2. **子窗口(SUB_WINDOW)** + +   - `TYPE_APPLICATION_PANEL`:应用面板 + +   - `TYPE_APPLICATION_SUB_PANEL`:应用子面板 + +   - `TYPE_APPLICATION_ATTACHED_DIALOG`:附加对话框 + + + +3. **系统窗口(SYSTEM_WINDOW)** + +   - `TYPE_STATUS_BAR`:状态栏 + +   - `TYPE_NAVIGATION_BAR`:导航栏 + +   - `TYPE_SYSTEM_ALERT`:系统警告窗口 + +   - `TYPE_TOAST`:Toast窗口 + +   - `TYPE_APPLICATION_OVERLAY`:悬浮窗(需要权限) + + + +**层级关系(Z-Order):** + + + +``` + +系统窗口(最高) + +    ↓ + +应用窗口(中等) + +    ↓ + +子窗口(最低) + +``` + + + +```java + +// 窗口类型定义 + +public static class LayoutParams { + +    // 应用窗口:1000-1999 + +    public static final int TYPE_APPLICATION = 2; + +    public static final int TYPE_APPLICATION_STARTING = 3; + +    // 子窗口:1000-1999 + +    public static final int TYPE_APPLICATION_PANEL = 1000; + +    // 系统窗口:2000-2999 + +    public static final int TYPE_STATUS_BAR = 2000; + +    public static final int TYPE_SYSTEM_ALERT = 2003; + +    public static final int TYPE_TOAST = 2005; + +    public static final int TYPE_APPLICATION_OVERLAY = 2038; + +} + +``` + + + +--- + + + +## 架构原理类 + + + +### Q4: WMS的架构是怎样的?包含哪些核心组件? + + + +**答案:** + + + +**WMS架构分层:** + + + +``` + +┌─────────────────────────────────┐ + +│  应用层(客户端)                  │ + +│  Activity/WindowManager          │ + +└──────────────┬──────────────────┘ + +               │ Binder IPC + +┌──────────────▼──────────────────┐ + +│  系统服务层(服务端)              │ + +│  WindowManagerService            │ + +│  ├── WindowState                 │ + +│  ├── DisplayContent              │ + +│  ├── WindowToken                 │ + +│  └── WindowAnimator              │ + +└──────────────┬──────────────────┘ + +               │ + +┌──────────────▼──────────────────┐ + +│  显示层                          │ + +│  SurfaceFlinger                 │ + +└─────────────────────────────────┘ + +``` + + + +**核心组件:** + + + +1. **WindowManagerService**:WMS主类,管理所有窗口 + +2. **WindowState**:窗口状态,表示一个窗口的所有信息 + +3. **DisplayContent**:显示内容,管理一个显示设备上的所有窗口 + +4. **WindowToken**:窗口令牌,用于窗口分组和权限控制 + +5. **WindowAnimator**:窗口动画控制器 + +6. **WindowStateAnimator**:单个窗口的动画状态 + + + +```java + +// WindowState:窗口状态 + +class WindowState { + +    final WindowManagerService mService; + +    final WindowToken mToken; + +    final WindowManager.LayoutParams mAttrs; + +    final DisplayContent mDisplayContent; + +    SurfaceControl mSurfaceControl; + +    // 窗口属性 + +    int mLayer;  // 层级 + +    Rect mFrame; // 位置和大小 + +    boolean mVisible; // 是否可见 + +} + +``` + + + +### Q5: 窗口添加的完整流程是什么? + + + +**答案:** + + + +**窗口添加流程:** + + + +``` + +1. Activity.attach() + +   └──> 创建PhoneWindow + +2. Activity.onCreate() + +   └──> setContentView() + +       └──> PhoneWindow.setContentView() + +           └──> 创建DecorView + +3. Activity.onResume() + +   └──> Activity.makeVisible() + +       └──> WindowManager.addView() + +           └──> WindowManagerGlobal.addView() + +               └──> 创建ViewRootImpl + +                   └──> ViewRootImpl.setView() + +                       └──> IWindowSession.addToDisplay() + +                           └──> WMS.addWindow() + +                               ├──> 创建WindowState + +                               ├──> 创建Surface + +                               └──> 更新布局 + +``` + + + +**关键代码:** + + + +```java + +// 1. Activity创建窗口 + +public final void attach(...) { + +    mWindow = new PhoneWindow(this, window, activityConfigCallback); + +    mWindow.setWindowManager( + +        (WindowManager)context.getSystemService(Context.WINDOW_SERVICE), + +        mToken, mComponent.flattenToString(), + +        (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0); + +} + + + +// 2. WMS添加窗口 + +public int addWindow(Session session, IWindow client, ...) { + +    // 权限检查 + +    if (!checkCallingPermission(...)) { + +        return WindowManagerGlobal.ADD_PERMISSION_DENIED; + +    } + +    // 创建WindowState + +    WindowState win = new WindowState(this, session, client, ...); + +    // 添加到DisplayContent + +    DisplayContent displayContent = getDisplayContent(displayId); + +    displayContent.addWindow(win); + +    // 创建Surface + +    win.createSurfaceControl(); + +    // 更新布局 + +    performLayoutAndPlaceSurfacesLocked(); + +    return WindowManagerGlobal.ADD_OKAY; + +} + +``` + + + +### Q6: WMS如何管理窗口的Z-Order(层级)? + + + +**答案:** + + + +**Z-Order管理机制:** + + + +1. **基础层级**:由窗口类型决定(TYPE值) + +2. **层级调整**:通过`WindowState.mLayer`动态计算 + +3. **层级排序**:DisplayContent维护窗口列表,按层级排序 + + + +**层级计算:** + + + +```java + +// WMS计算窗口层级 + +void assignWindowLayers(DisplayContent displayContent) { + +    int baseLayer = 0; + +    // 1. 系统窗口:最高层级 + +    for (WindowState win : systemWindows) { + +        win.mLayer = baseLayer + win.mAttrs.type; + +    } + +    // 2. 应用窗口:中等层级 + +    for (WindowState win : applicationWindows) { + +        win.mLayer = baseLayer + win.mAttrs.type; + +    } + +    // 3. 子窗口:最低层级(相对于父窗口) + +    for (WindowState win : childWindows) { + +        win.mLayer = win.mParentWindow.mLayer + win.mAttrs.type; + +    } + +    // 4. 按层级排序 + +    displayContent.sortWindowsByLayer(); + +} + +``` + + + +**影响层级的因素:** + + + +- 窗口类型(TYPE) + +- 窗口标志(FLAG) + +- 窗口动画状态 + +- 窗口可见性 + + + +--- + + + +## 窗口管理类 + + + +### Q7: WindowState的作用是什么?它包含哪些关键信息? + + + +**答案:** + + + +**WindowState的作用:** + + + +WindowState是WMS中表示一个窗口状态的核心类,包含了窗口的所有信息。 + + + +**关键信息:** + + + +1. **窗口属性**:LayoutParams、类型、标志等 + +2. **窗口状态**:可见性、焦点状态、动画状态等 + +3. **窗口位置**:Frame、可见区域、裁剪区域等 + +4. **Surface信息**:SurfaceControl、Surface等 + +5. **窗口关系**:父窗口、子窗口、Token等 + + + +```java + +class WindowState { + +    // 窗口属性 + +    final WindowManager.LayoutParams mAttrs; + +    final WindowToken mToken; + +    final DisplayContent mDisplayContent; + +    // 窗口状态 + +    boolean mVisible; + +    boolean mHasSurface; + +    boolean mIsAnimating; + +    // 窗口位置 + +    Rect mFrame;           // 窗口位置和大小 + +    Rect mVisibleFrame;     // 可见区域 + +    Rect mContentFrame;    // 内容区域 + +    // Surface + +    SurfaceControl mSurfaceControl; + +    Surface mSurface; + +    // 窗口关系 + +    WindowState mParentWindow; + +    ArrayList mChildWindows; + +    // 层级 + +    int mLayer; + +} + +``` + + + +### Q8: DisplayContent的作用是什么?它如何管理窗口? + + + +**答案:** + + + +**DisplayContent的作用:** + + + +DisplayContent表示一个显示设备上的所有窗口内容,管理该显示设备上的窗口栈、布局和显示。 + + + +**主要功能:** + + + +1. **窗口管理**:维护该显示设备上的所有窗口 + +2. **窗口栈管理**:维护窗口的Z-Order顺序 + +3. **布局计算**:计算窗口的位置和大小 + +4. **显示配置**:管理显示设备的分辨率、方向等 + + + +```java + +class DisplayContent { + +    final int mDisplayId; + +    final Display mDisplay; + +    // 窗口列表 + +    final WindowList mWindows = new WindowList(); + +    // 窗口栈 + +    final ArrayList mStacks = new ArrayList<>(); + +    // 显示配置 + +    Configuration mDisplayConfiguration; + +    // 添加窗口 + +    void addWindow(WindowState win) { + +        mWindows.add(win); + +        assignWindowLayers(); + +    } + +    // 布局计算 + +    void performLayout() { + +        for (WindowState win : mWindows) { + +            computeWindowFrame(win); + +        } + +    } + +} + +``` + + + +### Q9: WindowToken的作用是什么?为什么需要WindowToken? + + + +**答案:** + + + +**WindowToken的作用:** + + + +WindowToken是窗口的令牌,用于: + +1. **窗口分组**:将属于同一应用的窗口分组 + +2. **权限控制**:控制哪些窗口可以添加到Token + +3. **窗口关联**:关联Activity、Service等组件 + + + +**为什么需要WindowToken:** + + + +1. **安全性**:防止其他应用随意添加窗口到你的应用 + +2. **窗口管理**:统一管理同一组件的所有窗口 + +3. **生命周期**:Token销毁时,所有关联窗口都会被移除 + + + +```java + +class WindowToken { + +    final IBinder token;  // Token标识 + +    final int windowType; // 窗口类型 + +    final String name;    // Token名称 + +    // 关联的窗口列表 + +    final ArrayList windows = new ArrayList<>(); + +    // 添加窗口 + +    void addWindow(WindowState win) { + +        windows.add(win); + +    } + +    // 移除窗口 + +    void removeWindow(WindowState win) { + +        windows.remove(win); + +        if (windows.isEmpty()) { + +            // Token可以销毁 + +        } + +    } + +} + +``` + + + +--- + + + +## 源码分析类 + + + +### Q10: WMS的addWindow方法做了哪些事情? + + + +**答案:** + + + +**addWindow方法流程:** + + + +```java + +public int addWindow(Session session, IWindow client, ...) { + +    // 1. 权限检查 + +    if (!checkCallingPermission(...)) { + +        return WindowManagerGlobal.ADD_PERMISSION_DENIED; + +    } + +    // 2. 参数验证 + +    if (attrs.type < FIRST_APPLICATION_WINDOW || + +        attrs.type > LAST_APPLICATION_WINDOW) { + +        // 系统窗口需要特殊权限 + +    } + +    // 3. 获取或创建WindowToken + +    WindowToken token = getWindowToken(attrs.token); + +    if (token == null) { + +        // 创建新Token + +        token = new WindowToken(...); + +    } + +    // 4. 创建WindowState + +    WindowState win = new WindowState(this, session, client, token, ...); + +    // 5. 添加到DisplayContent + +    DisplayContent displayContent = getDisplayContent(displayId); + +    displayContent.addWindow(win); + +    // 6. 创建Surface + +    win.createSurfaceControl(); + +    // 7. 更新布局 + +    performLayoutAndPlaceSurfacesLocked(); + +    return WindowManagerGlobal.ADD_OKAY; + +} + +``` + + + +**关键步骤:** + + + +1. **权限检查**:检查是否有权限添加该类型窗口 + +2. **Token管理**:获取或创建WindowToken + +3. **创建WindowState**:创建窗口状态对象 + +4. **添加到DisplayContent**:将窗口添加到对应的显示设备 + +5. **创建Surface**:创建窗口的Surface用于绘制 + +6. **更新布局**:重新计算所有窗口的布局 + + + +### Q11: performLayoutAndPlaceSurfacesLocked方法的作用是什么? + + + +**答案:** + + + +**方法作用:** + + + +`performLayoutAndPlaceSurfacesLocked`是WMS的核心布局方法,负责: + +1. 计算所有窗口的位置和大小 + +2. 分配窗口的层级 + +3. 更新Surface的位置和大小 + +4. 处理窗口动画 + + + +**执行流程:** + + + +```java + +void performLayoutAndPlaceSurfacesLocked() { + +    // 1. 遍历所有显示设备 + +    for (DisplayContent displayContent : mDisplayContents) { + +        // 2. 计算显示配置 + +        displayContent.computeScreenConfiguration(); + +        // 3. 应用窗口策略 + +        applyWindowPolicy(displayContent); + +        // 4. 计算窗口位置和大小 + +        for (WindowState win : displayContent.mWindows) { + +            computeWindowFrame(win); + +        } + +        // 5. 分配窗口层级 + +        assignWindowLayers(displayContent); + +        // 6. 更新Surface + +        for (WindowState win : displayContent.mWindows) { + +            if (win.mHasSurface) { + +                updateSurface(win); + +            } + +        } + +        // 7. 处理窗口动画 + +        displayContent.mAnimator.updateWindowsLocked(); + +    } + +} + +``` + + + +### Q12: WMS如何与SurfaceFlinger交互? + + + +**答案:** + + + +**交互流程:** + + + +``` + +WMS + +  ├──> 创建SurfaceControl + +  ├──> 设置Surface属性(位置、大小、层级) + +  └──> 通过SurfaceControl与SurfaceFlinger通信 + +       └──> SurfaceFlinger合成Surface并显示 + +``` + + + +**关键代码:** + + + +```java + +// WMS创建Surface + +class WindowState { + +    void createSurfaceControl() { + +        mSurfaceControl = new SurfaceControl.Builder() + +            .setName(mWindowTag) + +            .setBufferSize(mFrame.width(), mFrame.height()) + +            .setFormat(PixelFormat.TRANSLUCENT) + +            .build(); + +        mSurface = new Surface(mSurfaceControl); + +    } + +    void updateSurface() { + +        // 设置Surface位置和大小 + +        mSurfaceControl.setPosition(mFrame.left, mFrame.top); + +        mSurfaceControl.setSize(mFrame.width(), mFrame.height()); + +        // 设置Surface层级 + +        SurfaceControl.Transaction t = new SurfaceControl.Transaction(); + +        t.setLayer(mSurfaceControl, mLayer); + +        t.apply(); + +    } + +} + +``` + + + +--- + + + +## 性能优化类 + + + +### Q13: 如何优化窗口的创建和显示性能? + + + +**答案:** + + + +**优化策略:** + + + +1. **减少窗口数量**:避免创建过多窗口 + +2. **延迟创建**:非关键窗口延迟创建 + +3. **复用窗口**:复用已有的窗口 + +4. **优化布局**:减少布局层级和复杂度 + +5. **使用硬件加速**:启用硬件加速提升绘制性能 + + + +```java + +// 1. 延迟创建窗口 + +Handler.postDelayed(() -> { + +    createWindow(); + +}, 100); + + + +// 2. 复用窗口 + +if (mWindow == null) { + +    mWindow = createWindow(); + +} else { + +    updateWindow(mWindow); + +} + + + +// 3. 启用硬件加速 + + + +``` + + + +### Q14: 窗口动画对性能有什么影响?如何优化? + + + +**答案:** + + + +**影响:** + + + +1. **CPU占用**:动画计算消耗CPU + +2. **GPU占用**:动画渲染消耗GPU + +3. **帧率下降**:复杂动画可能导致掉帧 + + + +**优化方法:** + + + +1. **简化动画**:使用简单的动画效果 + +2. **使用硬件加速**:利用GPU加速动画 + +3. **减少动画时长**:缩短动画时间 + +4. **避免同时多个动画**:减少并发动画数量 + + + +```java + +// 使用硬件加速动画 + +ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha", 0f, 1f); + +animator.setDuration(300); + +animator.setInterpolator(new AccelerateDecelerateInterpolator()); + +animator.start(); + +``` + + + +--- + + + +## 问题排查类 + + + +### Q15: 如何排查窗口显示异常的问题? + + + +**答案:** + + + +**排查步骤:** + + + +1. **检查窗口状态**:使用`adb shell dumpsys window` + +2. **检查Surface状态**:查看Surface是否创建成功 + +3. **检查布局**:查看窗口的Frame是否正确 + +4. **检查层级**:查看窗口的Layer是否正确 + +5. **使用Systrace**:分析窗口创建和布局流程 + + + +```bash + +# 1. 查看窗口信息 + +adb shell dumpsys window windows + + + +# 2. 查看窗口层级 + +adb shell dumpsys window displays + + + +# 3. 使用Systrace分析 + +python systrace.py -t 10 -o trace.html wm + +``` + + + +### Q16: 窗口泄漏如何排查和解决? + + + +**答案:** + + + +**排查方法:** + + + +1. **检查WindowManager引用**:确保及时移除窗口 + +2. **检查生命周期**:确保在onDestroy中移除窗口 + +3. **使用LeakCanary**:检测窗口泄漏 + +4. **检查WindowToken**:确保Token正确管理 + + + +```java + +// 正确的窗口管理 + +class MyActivity extends Activity { + +    private View floatingView; + +    @Override + +    protected void onCreate(Bundle savedInstanceState) { + +        super.onCreate(savedInstanceState); + +        // 创建悬浮窗 + +        createFloatingWindow(); + +    } + +    @Override + +    protected void onDestroy() { + +        super.onDestroy(); + +        // 必须移除窗口 + +        if (floatingView != null) { + +            WindowManager wm = getWindowManager(); + +            wm.removeView(floatingView); + +            floatingView = null; + +        } + +    } + +} + +``` + + + +--- + + + +## 多窗口相关 + + + +### Q17: 分屏模式是如何实现的? + + + +**答案:** + + + +**分屏实现原理:** + + + +1. **任务栈管理**:每个分屏窗口对应一个TaskStack + +2. **窗口布局**:WMS计算每个窗口的位置和大小 + +3. **输入事件分发**:根据触摸位置分发到对应窗口 + +4. **焦点管理**:管理两个窗口的焦点切换 + + + +```java + +// 分屏窗口布局 + +void layoutSplitScreenWindows(DisplayContent displayContent) { + +    // 计算分屏窗口大小 + +    Rect primaryFrame = new Rect(0, 0, screenWidth / 2, screenHeight); + +    Rect secondaryFrame = new Rect(screenWidth / 2, 0, screenWidth, screenHeight); + +    // 设置主窗口位置 + +    primaryWindow.mFrame = primaryFrame; + +    // 设置次窗口位置 + +    secondaryWindow.mFrame = secondaryFrame; + +} + +``` + + + +### Q18: 悬浮窗(Overlay Window)如何实现? + + + +**答案:** + + + +**实现步骤:** + + + +1. **申请权限**:`SYSTEM_ALERT_WINDOW`权限 + +2. **设置窗口类型**:`TYPE_APPLICATION_OVERLAY` + +3. **创建窗口**:使用WindowManager添加窗口 + +4. **管理生命周期**:及时移除窗口 + + + +```java + +// 创建悬浮窗 + +private void createOverlayWindow() { + +    // 1. 检查权限 + +    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + +        if (!Settings.canDrawOverlays(this)) { + +            // 请求权限 + +            requestOverlayPermission(); + +            return; + +        } + +    } + +    // 2. 创建窗口参数 + +    WindowManager.LayoutParams params = new WindowManager.LayoutParams( + +        WindowManager.LayoutParams.WRAP_CONTENT, + +        WindowManager.LayoutParams.WRAP_CONTENT, + +        WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, + +        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, + +        PixelFormat.TRANSLUCENT + +    ); + +    // 3. 创建视图 + +    View overlayView = LayoutInflater.from(this) + +        .inflate(R.layout.overlay_window, null); + +    // 4. 添加窗口 + +    WindowManager wm = getSystemService(Context.WINDOW_SERVICE); + +    wm.addView(overlayView, params); + +} + +``` + + + +--- + + + +## 总结 + + + +WMS窗口面试题主要涵盖: + + + +1. **基础概念**:WMS作用、窗口类型、层级关系 + +2. **架构原理**:WMS架构、窗口添加流程、Z-Order管理 + +3. **窗口管理**:WindowState、D \ No newline at end of file