3-9.【Ability】startAbility 跳转时,源 Ability 的生命周期如何变化?如果是透明 Ability 呢?

0 阅读3分钟

startAbility 跳转时,源 Ability 的生命周期如何变化?如果是透明 Ability 呢?多实例 Ability 会如何表现?

在 HarmonyOS 的 Stage 模型中,startAbility 的跳转逻辑是一个复杂的“协调过程”。系统会根据目标 Ability 的启动模式窗口属性以及任务栈状态,精确调度源 Ability 的状态。


1. 常规 startAbility 跳转:源 Ability 的变化

当源 Ability(A)启动一个非透明的常规 Ability(B)时:

  1. 失去焦点: A 立即感知到窗口失去焦点,触发 onWindowStageEvent (UNFOCUSED)。

  2. 转入后台: 随着 B 的 UI 逐渐覆盖全屏,A 变为不可见。

  3. 触发回调: A 执行 onBackground

    • 注意: A 不会执行 onDestroy。它会驻留在内存中(后台任务栈),等待用户点击返回键时通过热启动恢复。

2. 跳转到“透明 Ability”:特殊的可见性逻辑

这是开发者最容易混淆的场景。如果目标 Ability(B)配置了透明窗体(通过 module.json5 中的 windowType 或主题配置):

  • 可见性不消失: 由于 B 是透明的,用户仍然能看到 A 的内容。

  • 生命周期表现:

    • A 不会执行 onBackground。因为 A 依然处于“可见”状态。
    • A 会触发 onWindowStageEvent (UNFOCUSED) 。因为输入焦点已经转移到了透明的 B 上。
  • 性能影响: 这种模式下,系统必须同时维护两个 Ability 的渲染开销,因此不建议在透明 Ability 下方放置过于复杂的动画。


3. 多实例 (Multiton) Ability 的表现

多实例模式(在 module.json5 中配置 launchType: "multiton")决定了系统如何创建新实例。

场景:Ability A 启动 Ability B (Multiton)

每次调用 startAbility 启动 B,系统都会:

  1. 创建新进程/实例: 为 B 分配全新的内存空间和独立的 UIAbility 实例。
  2. 源 Ability (A) 的变化: A 正常进入 onBackground
  3. 任务栈: 在最近任务栏(Recents)中,你会看到两个 B 的任务卡片。它们彼此独立,修改其中一个 B 的全局变量不会影响另一个。

对比:单实例 (Singleton)

如果 B 是 singleton

  • 如果 B 已在后台,再次启动 B 时,源 Ability A 进入 onBackground,而 B 会触发 onNewWant \rightarrow onForeground,而不是重新 onCreate

4. 关键路径对比表

跳转场景源 Ability 最终状态是否执行 onBackground是否执行 onDestroy
跳转到普通 Ability后台 (Background)
跳转到透明 Ability前台失去焦点
跳转后销毁自己销毁 (Destroyed) (需手动调 terminateSelf)
返回上一个 Ability前台 (Foreground)N/A (源已销毁)

5. 跨端流转 (Hop) 中的生命周期

如果是跨设备跳转(例如从手机跳转到平板上的 Ability):

  • 源设备: Ability 依然保持在 onForeground(直到用户手动关闭或流转完成确认)。
  • 目标设备: 经历完整的冷启动流程(onCreate \rightarrow onWindowStageCreate \rightarrow onForeground),并通过 Want 参数接收流转过来的状态。

总结与建议

  1. 状态保存: 无论目标是什么,永远在源 Ability 的 onBackgroundonSaveState 中保存重要数据,防止跳转后系统内存压力大导致源 Ability 被回收。
  2. 透明窗体慎用: 仅在对话框、快捷支付等临时覆盖场景使用透明 Ability,避免因 A 不进入后台导致的额外电量消耗。
  3. 启动模式选型: 绝大多数业务功能推荐 singleton 以节省内存;只有像“浏览器新建标签页”这种需要并行操作的任务才使用 multiton