# 窗口类型与层级管理

Android系统中的窗口类型和层级管理是界面显示和交互的基础。本文深入分析Android窗口系统的类型分类、层级管理和显示机制。

## 窗口系统架构概览

```mermaid
graph TB
    subgraph "窗口层级（Z-Order）"
        A1[系统窗口 - 最高层级] --> B1[状态栏]
        A1 --> B2[导航栏]
        A1 --> B3[系统对话框]
        
        A2[应用窗口] --> B4[Activity窗口]
        A2 --> B5[对话框窗口]
        A2 --> B6[Toast窗口]
        
        A3[输入法窗口] --> B7[软键盘]
        
        A4[壁纸窗口 - 最低层级] --> B8[动态壁纸]
    end
```

## 1. 窗口类型分类

### 1.1 应用窗口（TYPE_APPLICATION）
- **Activity窗口**：应用主界面窗口
- **子窗口**：依附于父窗口的窗口
- **特点**：可接收输入焦点，参与任务栈管理

### 1.2 系统窗口
- **状态栏**（TYPE_STATUS_BAR）：系统状态显示
- **导航栏**（TYPE_NAVIGATION_BAR）：系统导航控制
- **系统警报**（TYPE_SYSTEM_ALERT）：系统级提示
- **输入法窗口**（TYPE_INPUT_METHOD）：软键盘

### 1.3 特殊窗口
- **壁纸窗口**（TYPE_WALLPAPER）：桌面壁纸
- **锁屏窗口**（TYPE_KEYGUARD）：锁屏界面
- **启动器窗口**（TYPE_APPLICATION_STARTING）：应用启动动画

## 2. 窗口层级（Z-Order）管理

### 2.1 层级定义
- **Z-Order**：窗口在Z轴上的顺序，决定显示优先级
- **Base Layer**：基础层级，决定窗口类型的基本位置
- **Sub Layer**：子层级，同一类型窗口内的顺序

### 2.2 层级计算
```java
// WindowManagerService中的层级计算
int assignWindowLayersLocked() {
    // 1. 按窗口类型排序
    sortWindowsByType();
    
    // 2. 计算每个窗口的层级
    for (WindowState window : windows) {
        // 基础层级 = 窗口类型的基础值
        int baseLayer = getBaseLayerForType(window.mAttrs.type);
        
        // 子层级 = 窗口在同类窗口中的顺序
        int subLayer = getSubLayerForWindow(window);
        
        // 最终层级 = 基础层级 + 子层级
        window.mLayer = baseLayer + subLayer;
    }
    
    // 3. 更新Surface的Z-Order
    updateSurfacesOrder();
}
```

## 3. 窗口属性配置

### 3.1 WindowManager.LayoutParams
```java
// 窗口属性配置示例
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    WindowManager.LayoutParams.MATCH_PARENT,
    WindowManager.LayoutParams.MATCH_PARENT,
    WindowManager.LayoutParams.TYPE_APPLICATION,
    WindowManager.LayoutParams.FLAG_FULLSCREEN |
    WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
    PixelFormat.TRANSLUCENT
);

// 设置窗口层级
params.type = WindowManager.LayoutParams.TYPE_APPLICATION;
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

// 设置窗口动画
params.windowAnimations = R.style.WindowAnimation;
```

### 3.2 关键属性说明
- **type**：窗口类型，决定基础层级
- **flags**：窗口标志，控制窗口行为
- **format**：像素格式，决定透明度支持
- **gravity**：窗口对齐方式
- **x, y, width, height**：窗口位置和大小

## 4. 窗口标志（Flags）详解

### 4.1 显示相关标志
- **FLAG_FULLSCREEN**：全屏显示
- **FLAG_NOT_FOCUSABLE**：不可获得焦点
- **FLAG_NOT_TOUCHABLE**：不可触摸
- **FLAG_NOT_TOUCH_MODAL**：非触摸模态
- **FLAG_KEEP_SCREEN_ON**：保持屏幕常亮

### 4.2 行为相关标志
- **FLAG_LAYOUT_NO_LIMITS**：布局无限制
- **FLAG_LAYOUT_IN_SCREEN**：在屏幕内布局
- **FLAG_LAYOUT_INSET_DECOR**：考虑装饰区域
- **FLAG_SECURE**：安全窗口，禁止截图

## 5. 窗口动画

### 5.1 系统默认动画
- **窗口进入动画**：窗口显示时的动画
- **窗口退出动画**：窗口隐藏时的动画
- **Activity切换动画**：Activity切换时的动画

### 5.2 自定义动画
```xml
<!-- 窗口动画定义 -->
<style name="WindowAnimation">
    <item name="android:windowEnterAnimation">@anim/slide_in_right</item>
    <item name="android:windowExitAnimation">@anim/slide_out_right</item>
</style>

<!-- 使用自定义动画 -->
params.windowAnimations = R.style.WindowAnimation;
```

## 6. 多窗口模式

### 6.1 分屏模式（Split-screen）
- **主窗口**：占据屏幕主要区域
- **副窗口**：占据屏幕次要区域
- **窗口调整**：用户可调整窗口大小
- **焦点管理**：活动窗口获得焦点

### 6.2 画中画模式（Picture-in-picture）
- **主窗口暂停**：进入画中画时主窗口暂停
- **小窗口显示**：以小窗口形式显示
- **位置可调**：用户可拖动小窗口位置
- **焦点切换**：点击小窗口恢复焦点

### 6.3 自由窗口模式（Freeform）
- **窗口可调**：窗口大小和位置可自由调整
- **多窗口共存**：多个窗口同时显示
- **窗口管理**：类似桌面操作系统的窗口管理

## 7. 调试与优化

### 7.1 调试工具
```bash
# 查看所有窗口信息
adb shell dumpsys window windows

# 查看窗口层级
adb shell dumpsys window windows | grep -A 20 "Window #"

# 查看窗口动画
adb shell dumpsys window animator

# 性能分析
adb shell dumpsys SurfaceFlinger --latency <window_name>
```

### 7.2 性能优化
- **减少窗口数量**：避免创建过多窗口
- **合理使用标志**：正确设置窗口标志
- **优化窗口动画**：使用轻量级动画
- **及时释放窗口**：不再使用的窗口及时释放

### 7.3 常见问题
- **窗口重叠**：层级设置不当导致窗口重叠
- **焦点丢失**：窗口焦点管理问题
- **内存泄漏**：窗口未正确释放
- **显示异常**：窗口显示位置或大小异常

## 总结

窗口类型与层级管理是Android显示系统的核心：
- **显示基础**：决定界面元素的显示顺序
- **交互基础**：决定输入事件的接收顺序
- **多窗口支持**：支持复杂的多任务场景
- **系统稳定**：正确的窗口管理确保系统稳定

深入理解窗口类型与层级管理，对于设计复杂界面、优化显示性能和排查显示问题具有重要意义。