UIAbility 在什么情况下会进入 onBackground?onBackground 是否一定会执行?被强杀时是否会走 onDestroy?
1. UIAbility 在什么情况下会进入 onBackground?
onBackground 触发的核心逻辑是 “UI 实例从前台可见状态变为后台不可见状态” 。具体场景包括:
-
用户主动行为:
- 用户点击了 Home 键(返回桌面)。
- 用户通过 多任务管理界面 切换到了另一个应用。
- 用户点击了系统的 返回键(如果当前 Ability 不是任务栈的最后一个,或者配置了不退出)。
-
系统/应用跳转:
- 当前 Ability 启动了另一个处于不同任务栈的 Ability(例如调用了系统浏览器、拨号盘)。
- 系统弹出了全屏的模态通知或权限申请弹窗(视系统版本和 UI 类型而定)。
-
设备状态变化:
- 手机 锁屏(按下电源键)。
2. onBackground 是否一定会执行?
不是 100% 保证执行。 虽然在正常的生命周期流转中它是必经之路,但在以下异常或极端场景下,onBackground 会被跳过:
- 进程被“瞬间”强杀: 如果系统资源极其匮乏,或者用户在多任务卡片上快速划掉应用,系统可能会直接杀掉进程,此时没有任何生命周期回调会执行。
- 崩溃 (Crash): 如果应用在
onForeground期间发生未捕获的异常导致进程闪退,onBackground不会执行。 - 断电/系统重启: 硬件级别的关机或重启。
开发建议: 不要将必须完成的业务逻辑(如保存核心数据库记录)仅放在 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 键返回桌面 | 是 | 否(实例仍在后台) |
| 正常退出应用(返回键) | 是 | 是 |
| 多任务界面划掉应用 | 否 (通常直接干掉进程) | 否 |
| 系统内存极低强制杀掉 | 否 | 否 |
架构方案建议:
如果你需要确保数据在应用消失前被保存,请遵循以下原则:
- 即时写入: 重要数据发生改变后立即保存。
onSaveState: 利用系统提供的状态保存回调,它在onBackground之前被调用,专门用于应对系统因内存压力回收 Ability 后的数据恢复。- Emitter/订阅: 利用全局事件或后台任务监听状态,不依赖单一的销毁回调。