3-3.【Ability】UIAbility 在什么情况下会进入 onBackground?onBackground 是否一定会执行?

2 阅读3分钟

UIAbility 在什么情况下会进入 onBackground?onBackground 是否一定会执行?被强杀时是否会走 onDestroy?

1. UIAbility 在什么情况下会进入 onBackground

onBackground 触发的核心逻辑是 “UI 实例从前台可见状态变为后台不可见状态” 。具体场景包括:

  • 用户主动行为:

    • 用户点击了 Home 键(返回桌面)。
    • 用户通过 多任务管理界面 切换到了另一个应用。
    • 用户点击了系统的 返回键(如果当前 Ability 不是任务栈的最后一个,或者配置了不退出)。
  • 系统/应用跳转:

    • 当前 Ability 启动了另一个处于不同任务栈的 Ability(例如调用了系统浏览器、拨号盘)。
    • 系统弹出了全屏的模态通知或权限申请弹窗(视系统版本和 UI 类型而定)。
  • 设备状态变化:

    • 手机 锁屏(按下电源键)。

2. onBackground 是否一定会执行?

不是 100% 保证执行。 虽然在正常的生命周期流转中它是必经之路,但在以下异常或极端场景下,onBackground 会被跳过:

  1. 进程被“瞬间”强杀: 如果系统资源极其匮乏,或者用户在多任务卡片上快速划掉应用,系统可能会直接杀掉进程,此时没有任何生命周期回调会执行。
  2. 崩溃 (Crash): 如果应用在 onForeground 期间发生未捕获的异常导致进程闪退,onBackground 不会执行。
  3. 断电/系统重启: 硬件级别的关机或重启。

开发建议: 不要将必须完成的业务逻辑(如保存核心数据库记录)仅放在 onBackground 中。应当在数据变化时即时持久化,或者利用 onSaveState 来保存瞬时状态。


3. 被强杀(Terminated)时是否会走 onDestroy

结论:不会。

这是开发者最容易产生的误区。我们需要区分“正常销毁”和“强杀”:

  • 正常销毁(会走 onDestroy):

    • 用户点击返回键退出应用(且该 Ability 结束)。
    • 代码主动调用了 context.terminateSelf()
    • 系统内存回收机制有序地销毁不再需要的后台 Ability。
  • 强杀(不走 onDestroy):

    • 用户侧: 在多任务管理界面向上滑动划掉应用卡片。
    • 系统侧: 系统因为内存压力通过 kill -9 类似的机制直接终止应用进程。
    • 开发工具侧: 在 DevEco Studio 中点击 "Stop" 按钮停止运行。

底层逻辑: “强杀”意味着操作系统直接撤销了分配给该进程的所有内存空间和 CPU 资源,进程在微秒级消失。此时,ArkTS 虚拟机已经停止运行,没有任何机会去执行 onDestroy 中的 JS/ArkTS 代码。


4. 总结:生命周期的稳定性保障

场景onBackground 执行吗?onDestroy 执行吗?
按 Home 键返回桌面否(实例仍在后台)
正常退出应用(返回键)
多任务界面划掉应用 (通常直接干掉进程)
系统内存极低强制杀掉

架构方案建议:

如果你需要确保数据在应用消失前被保存,请遵循以下原则:

  1. 即时写入: 重要数据发生改变后立即保存。
  2. onSaveState 利用系统提供的状态保存回调,它在 onBackground 之前被调用,专门用于应对系统因内存压力回收 Ability 后的数据恢复。
  3. Emitter/订阅: 利用全局事件或后台任务监听状态,不依赖单一的销毁回调。