在 HarmonyOS 的 Stage 模型中,系统回收(Termination by System) 是资源调度的核心机制。系统为了保障前台应用的流畅度,会根据优先级动态“修剪”后台的 UIAbility 实例。
1. Ability 被系统回收的条件
系统不会无缘无故回收你的应用,通常遵循以下 “资源优先级法则” :
-
内存阈值(Memory Pressure): 当系统剩余内存低于预设的安全水位(Watermark)时,回收机制触发。
-
优先级排序:
- 前台(Foreground): 绝对不回收。
- 可见非焦点(Visible but Unfocused): 如分屏模式下的非活动窗口,优先级高,极少回收。
- 后台(Background): 优先级最低。系统会按照 LRU(最近最少使用) 算法,优先回收开启时间最早、占用内存最大的后台 Ability。
-
托管任务状态: 如果 Ability 关联了后台长连接、音乐播放或定位服务(Continuous Task),其回收优先级会被显著降低(即更难被回收)。
2. 如何模拟被系统回收?
在开发调试阶段,由于手机内存通常很大,很难靠自然等待来触发回收。你可以通过以下两种方式手动触发:
方法 A:利用 DevEco Studio 的调试工具(推荐)
在 Log 窗口或者 Profiler 工具栏中,有一个 "Terminate Process" 或类似强杀按钮。
- 模拟步骤: 先将应用按 Home 键切入后台,然后在 IDE 中断开连接或点击停止,模拟进程消失。
方法 B:命令行模拟 (Shell)
通过 hdc 工具向设备发送指令,强制清理内存:
Bash
# 这种方式更接近系统回收,会直接杀掉进程
hdc shell kill -9 [进程PID]
方法 B:设置“不保留活动”(开发者选项)
在 HarmonyOS 设备的 设置 > 系统和更新 > 开发人员选项 中,开启 “不保留活动” (Don't keep activities) 。
- 效果: 只要应用一离开前台,系统会立即触发销毁流程,这是测试状态恢复的最佳利器。
3. 如何做状态持久化与恢复?
为了应对“进程消失”带来的数据丢失,ArkTS 提供了 onSaveState 这一关键钩子。
第一步:在回收前保存状态
当 Ability 准备转入后台时,系统会触发 onSaveState。你可以将需要恢复的小型数据存入 want 参数中。
TypeScript
import UIAbility from '@ohos.app.ability.UIAbility';
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import Want from '@ohos.app.ability.Want';
export default class EntryAbility extends UIAbility {
// 1. 系统准备回收前调用
onSaveState(reason: AbilityConstant.StateType, wantParam: Want): AbilityConstant.OnSaveResult {
// 将需要恢复的数据存入 wantParam 的 parameters 中
wantParam.parameters = {
'input_text': '用户写了一半的评论',
'scroll_pos': 120
};
return AbilityConstant.OnSaveResult.ALL_AGREE;
}
}
第二步:在重建时恢复数据
当用户从历史任务栈切回应用时,系统会执行冷启动流程。此时 onCreate 的第一个参数 want 中会包含你之前保存的数据。
TypeScript
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
// 2. 检查是否有恢复数据
if (launchParam.launchReason === AbilityConstant.LaunchReason.LAST_EXIT_ABNORMAL) {
let savedText = want.parameters?.['input_text'];
let scrollPos = want.parameters?.['scroll_pos'];
// 将数据存入 AppStorage 或传给页面
AppStorage.setOrCreate('RestoredText', savedText);
}
}
}
4. 状态恢复的“黄金法则”
- 数据量限制:
onSaveState里的want适合存轻量级数据(如 ID、位置、简单的表单内容)。 - 大文件处理: 视频缓存、大量图片数据不要往
want里塞,应在onBackground阶段直接写入磁盘文件或数据库。 - UI 自动恢复: 对于
TextInput等基础组件,ArkUI 框架在一定程度上支持自动状态恢复,但复杂的自定义状态(如当前选中的 Tab 索引)必须通过上述代码手动处理。
一句话总结: 靠 onSaveState 存变量,靠 PersistentStorage 或 RDB 数据库存重数据,靠 onCreate 判断启动原因来回填。