3-2.【Ability】为什么 Stage 模型将 WindowStage 生命周期从 UIAbility 中拆分出来?

3 阅读3分钟

为什么 Stage 模型将 WindowStage 生命周期从 UIAbility 中拆分出来?如果没有 WindowStage 会有什么架构问题?多窗口下 Ability 生命周期如何变化?

在 HarmonyOS 的 Stage 模型中,将 WindowStageUIAbility 中解耦是一次深思熟虑的架构进化。它解决了移动端从“单任务”向“多窗口/多设备协同”演进时的核心矛盾。


1. 为什么拆分 WindowStage?

在早期的 FA(Feature Ability)模型中,Ability 与窗口是强耦合的(1:1 关系)。Stage 模型引入 WindowStage 实现了**“业务逻辑”与“显示逻辑”的物理隔离**。

核心原因:

  • 职责分离(SoC): UIAbility 负责应用实例的后台生命周期(如数据初始化、进程存活);WindowStage 负责前台渲染布局(如加载页面、窗口沉浸式设置)。
  • 多窗口能力的底层支撑: 拆分后,一个 UIAbility 实例理论上可以管理多个 WindowStage(虽然目前主要维持 1:1,但架构上具备了 1:N 的扩展性)。
  • 解耦系统组件: 系统可以独立销毁 UI 窗口(回收显存)而保留 Ability 实例(保留业务状态),从而在极低内存下实现更优雅的“后台挂起”。

2. 如果没有 WindowStage 会有什么架构问题?

如果两者合二为一,应用开发将面临以下“重度耦合”带来的灾难:

  1. UI 资源无法按需回收: 如果系统想释放某个不显示的窗口,必须连带销毁整个 Ability。这会导致应用丢失所有内存中的业务数据,下次启动只能被迫“冷启动”。
  2. 窗口管理逻辑臃肿: UIAbility 类会变成一个“超级类”,既要处理生命周期,又要处理状态同步,还要处理刘海屏适配、悬浮窗位置等复杂的 UI 细节,违反单一职责原则。
  3. 多设备形态适配困难: 在折叠屏或平板上,一个应用可能同时开启左右两个分屏窗口。如果没有独立的 WindowStage,框架将无法区分这两部分 UI 应该如何独立调度和刷新。

3. 多窗口下 Ability 生命周期的变化

在多窗口(分屏、悬浮窗)场景下,生命周期的行为变得更加细腻,不再是简单的“可见即在前台”。

A. 焦点的竞争 (The Focus Rule)

  • Foreground 状态: 即使两个窗口在分屏状态下都可见,只有当前用户正在操作(获得焦点)的那个窗口对应的 Ability 处于真正的活跃状态。
  • 不触发 Background: 当你从左边的 A 应用操作右边的 B 应用时,A 窗口虽然失去焦点,但只要它在屏幕上依然可见,它就不会触发 onBackground。它依然留在 onForeground,但会失去某些交互特权。

B. 多窗口下的切换流程

  1. 焦点转移: 窗口 A 失去焦点 \rightarrow 窗口 B 获得焦点。
  2. 窗口状态回调: WindowStage 会触发 onWindowStageEvent(如 WINDOW_STAGE_EVENT_FOCUSEDUNFOCUSED)。
  3. Ability 不变: 两者的 UIAbility 均保持 onForeground 状态。

4. 关键点:生命周期与窗口状态的配合

场景UIAbility 状态WindowStage 状态
应用启动onCreateonWindowStageCreate
切到后台onBackground窗口不可见(隐藏)
分屏显示(非焦点)onForegroundWINDOW_STAGE_EVENT_UNFOCUSED
分屏显示(焦点)onForegroundWINDOW_STAGE_EVENT_FOCUSED

总结: UIAbility 控制“生与死”,WindowStage 控制“显与隐”。这种设计让 HarmonyOS 在处理折叠屏、智慧屏等复杂显示场景时,比传统移动 OS 更加游刃有余。