应用卡死后借助AppRecovery优雅重生
相信不少开发者都遇到过这样的场景:用户正在应用中填写一份重要的表单,或者正在进行一笔关键的支付操作,突然应用画面定格、触控无响应——这就是常说的"应用卡死"(AppFreeze)。对于用户而言,这意味着正在进行的工作可能付诸东流;对于开发者而言,这往往意味着用户流失和差评。
前言
相信不少开发者都遇到过这样的场景:用户正在应用中填写一份重要的表单,或者正在进行一笔关键的支付操作,突然应用画面定格、触控无响应——这就是常说的”应用卡死”(AppFreeze)。对于用户而言,这意味着正在进行的工作可能付诸东流;对于开发者而言,这往往意味着用户流失和差评。
好消息是,HarmonyOS提供了一项名为AppRecovery的能力,专门用于应对这类场景。下面就一起来聊聊,如何让应用在发生卡死时能够”优雅地重启”,更好地保障用户体验。
什么是AppRecovery?
AppRecovery是HarmonyOS提供的一项应用故障恢复能力。当应用在运行过程中发生非预期的行为(如AppFreeze导致的卡死)时,系统默认会直接退出进程。如果用户在此时有未保存的数据,这些数据就会丢失——这对用户来说是非常糟糕的体验。
而启用了AppRecovery的应用则不同。框架会在应用异常退出前自动保存当前状态(包括页面栈、用户数据等),待应用重新启动后,这些数据会被完整恢复,让用户感觉”就像什么都没发生过一样”。
从API 10开始,AppRecovery已经支持应用卡死(AppFreeze)场景下的状态保存与自动重启,这对于需要保障数据安全的应用来说尤为重要。
AppRecovery核心接口一览
AppRecovery模块提供了以下关键接口:
| 接口名称 | 功能说明 |
| enableAppRecovery() | 使能应用恢复功能,建议在AbilityStage的onCreate中调用 |
| saveAppState() | 主动保存当前应用中支持恢复的UIAbility的状态 |
| restartApp() | 重启当前进程,并启动指定的UIAbility |
| setRestartWant() | 设置重启时拉起的UIAbility |
调用enableAppRecovery后,应用恢复时将按首个支持恢复的UIAbility进行恢复。saveAppState调用后,框架会回调当前进程中所有支持恢复的UIAbility的onSaveState方法,将相关数据及页面栈持久化到本地缓存。
实战:让应用具备”自愈”能力
下面通过三个步骤,让应用具备AppFreeze后的恢复能力。
第一步:使能自恢复特性
在AbilityStage的onCreate中启用appRecovery:
import { AbilityStage, appRecovery } from '@kit.AbilityKit';
export default class MyAbilityStage extends AbilityStage {
onCreate() {
console.info("[Demo] MyAbilityStage onCreate");
appRecovery.enableAppRecovery(
appRecovery.RestartFlag.ALWAYS_RESTART,
appRecovery.SaveOccasionFlag.SAVE_WHEN_ERROR | appRecovery.SaveOccasionFlag.SAVE_WHEN_BACKGROUND,
appRecovery.SaveModeFlag.SAVE_WITH_FILE
);
}
}
第二步:配置可恢复的UIAbility
在module.json5中声明支持恢复的UIAbility:
{
"abilities": [
{
"name": "EntryAbility",
"recoverable": true
}
]
}
第三步:实现状态保存与恢复
在UIAbility中实现onSaveState和onCreate方法:
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
let abilityWant: Want;
export default class EntryAbility extends UIAbility {
storage: LocalStorage | undefined = undefined;
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
console.info("[Demo] EntryAbility onCreate");
abilityWant = want;
// Determine if it is a recovery scenario
if (launchParam.launchReason == AbilityConstant.LaunchReason.APP_RECOVERY) {
this.storage = new LocalStorage();
if (want.parameters) {
let recoveryData = want.parameters["myData"];
this.storage.setOrCreate("myData", recoveryData);
this.context.restoreWindowStage(this.storage);
}
}
}
onSaveState(state: AbilityConstant.StateType, wantParams: Record<string, Object>) {
console.info("[Demo] EntryAbility onSaveState");
wantParams["myData"] = "my1234567";
return AbilityConstant.OnSaveResult.ALL_AGREE;
}
}
AppFreeze场景的特殊之处
相比其他故障类型,AppFreeze有其特殊性:应用主线程处于卡死状态,无法正常执行JS代码。为此,API 10针对AppFreeze场景做了特殊处理——onSaveState回调会在非主线程执行,确保状态能够被正确保存。
这里有几点需要特别注意:
1. 重启间隔:两次重启的间隔应大于一分钟,否则只会退出不会重启
2. 线程安全:由于回调不在JS线程执行,onSaveState中禁止访问主线程创建的thread_local对象
3. 状态标记:重启后可以通过wantConstant.Params.ABILITY_RECOVERY_RESTART判断是否为恢复场景
为用户打造的”无缝”体验
当AppRecovery正确配置后,用户的体验流程是这样的:
1. 应用发生AppFreeze,画面冻结
2. 底层恢复框架检测到故障,触发状态保存
3. 应用自动重启,onSaveState中保存的数据被持久化
4. 应用重新启动,检测到恢复状态,从上次中断的地方继续
整个过程对用户来说,就像经历了一次”快速重启”,正在进行的工作得以完整保留。数据不丢,用户自然更信任应用。
写在最后
应用发生卡死是一个小概率但后果严重的事件。通过AppRecovery能力,开发者可以为应用增添一道”安全网”——即使面对AppFreeze这样的极端场景,也能保障用户数据的完整性,提升应用的整体品质。
如果还没用过AppRecovery,现在就可以动手试试了。
注:本文档适用于HarmonyOS API 10及以上版本。不同版本的功能支持情况可能有所差异,请以官方文档为准。
—————————————————————————————————–
🔗 官网开发者学堂视频:https://developer.huawei.com/consumer/cn/training/result?type2List=201783644516849879&orderBy=1&courseType=5

🔗 社区DFX专题文章: https://developer.huawei.com/consumer/cn/forum/subject/2101218731402391001


【扫码加入 HarmonyOS DFX 技术交流群】
本文由 @华为开发者联盟 授权发布于人人都是产品经理。未经作者许可,禁止转载
题图来自Unsplash,基于CC0协议
该文观点仅代表作者本人,人人都是产品经理平台仅提供信息存储空间服务
- 目前还没评论,等你发挥!

起点课堂会员权益




