diff --git a/zh-cn/application-dev/dfx/Readme-CN.md b/zh-cn/application-dev/dfx/Readme-CN.md index e136fdc028d69c3283b6fa496302e0a8fb6f42f8..38a5bb7d8c623e9c7b37ebae70eb78d5772331ef 100644 --- a/zh-cn/application-dev/dfx/Readme-CN.md +++ b/zh-cn/application-dev/dfx/Readme-CN.md @@ -10,4 +10,5 @@ - [分布式跟踪概述](hitracechain-overview.md) - [分布式跟踪开发指导](hitracechain-guidelines.md) - 错误管理 - - [错误管理开发指导](errormanager-guidelines.md) \ No newline at end of file + - [错误管理开发指导](errormanager-guidelines.md) + - [应用恢复开发指导](apprecovery-guidelines.md) \ No newline at end of file diff --git a/zh-cn/application-dev/dfx/apprecovery-guidelines.md b/zh-cn/application-dev/dfx/apprecovery-guidelines.md new file mode 100644 index 0000000000000000000000000000000000000000..fba61846635b13b167ed96d6f2ee97f5fb1d3ca0 --- /dev/null +++ b/zh-cn/application-dev/dfx/apprecovery-guidelines.md @@ -0,0 +1,193 @@ +# 应用恢复开发指导 + +## 场景介绍 + +应用在运行中不可避免会产生一些非预期的行为,如运行时抛出未处理的异常和错误,违反框架的调用/运行约束等。 + +系统默认对异常的处理方式为进程退出,如果应用使用过程中产生了用户数据,直接退出可能会导致用户工作中断,数据丢失。 +如果使用应用故障恢复相关接口,则可对临时数据进行保存,应用退出后会重启应用并恢复先前的状态和数据,能给用户带来更好的使用体验。 + +目前该接口仅支持单进程单Ability的Stage模型应用开发。 + +## 接口说明 + +应用故障恢复接口由appRecovery模块提供,开发者可以通过import引入,详见[开发示例](#开发示例)。本文档描述的为API9版本的接口行为,后续接口行为变更会更新本文档。 + +### 应用恢复接口功能介绍 + +| 接口名称 | 说明 | +| ------------------------------------------------------------ | ---------------------------------------------------- | +| enableAppRecovery(restart?: RestartFlag, saveOccasion?: SaveOccasionFlag, saveMode?: SaveModeFlag) : void; | 使能应用恢复功能。| +| saveAppState(): boolean; | 主动保存当前应用中Ability的状态。 | +| restartApp(): void; | 重启当前进程,如果有已经保存的Ability状态,会在Ability的OnCreate生命周期回调的want参数中的wantParam属性传入。 | + +由于本接口为故障处理时使用,不会返回异常,需要开发者熟悉使用的场景。 + +**enableAppRecovery:** 需要在应用初始化阶段调用,比如AbilityStage的OnCreate调用赋能。具体其各参数定义详见[参数说明](../reference/apis/js-apis-app-ability-appRecovery.md)。 + +**saveAppState:** 调用后框架会回调Ability的onSaveState方法,如果在onSaveState方法中同意保存数据,则会将相关数据及Ability的页面栈持久化到应用的本地缓存。 + +**restartApp:** 调用后框架会杀死当前应用进程,并重新拉起处于前台的Ability,其中启动原因为APP_RECOVERY。 + +### 框架故障管理理流程示意 + +故障管理是应用提升用户体验的重要手段。鸿蒙应用框架为开发者提供了故障监听,故障恢复以及故障查询三种方式来管理应用的故障。 + +- 故障监听指的是通过[errorManager](../reference/apis/js-apis-errorManager.md)注册[ErrorObserver](../reference/apis/js-apis-errorManager.md#errorobserver),监听故障的发生,并通知到监听方。 + +- 故障恢复指的是[appRecovery](../reference/apis/js-apis-app-ability-appRecovery.md),及故障发生后,将应用重启恢复到故障之前的状态。 + +- 故障查询指的是[faultLogger](../reference/apis/js-apis-faultLogger.md)通过其查询接口获取当前的故障信息。 + +下图中并没有标记[faultLogger](../reference/apis/js-apis-faultLogger.md)的调用时机,开发者可以根据应用启动时传入的[LastExitReason](../reference/apis/js-apis-application-abilityConstant.md#abilityconstantlastexitreason)来决定是否调用[faultLogger](../reference/apis/js-apis-faultLogger.md)查询上次的故障信息。 +![故障处理流程示意](./figures/20221106203527.png) +这里建议应用开发者使用[errorManager](../reference/apis/js-apis-errorManager.md)对应用的异常进行处理,处理完成后开发者可以选择调用状态保存接口并主动重启应用。 +如果开发者没有注册[ErrorObserver](../reference/apis/js-apis-errorManager.md#errorobserver)也没有使能自动恢复,则按照系统的默认逻辑执行进程退出。用户可以选择从启动器再次打开应用。 +如果开发者使能了自动恢复,框架会首先检查当前故障是否支持状态保存以及开发者是否配置了状态保存,如果支持则会回调[Ability](../reference/apis/js-apis-application-ability.md#ability)的[onSaveState](../reference/apis/js-apis-application-ability.md#abilityonsavestate)的接口。最后重启应用。 + +### 应用故障管理接口支持场景 + +通常的故障类型有JS程序Crash、应用程序卡死、C++程序Crash。Crash故障时应用一般都会被关闭。Freeze故障为应用无响应卡屏场景。应用上层无需关注故障类型,底层恢复框架会根据故障类型来实现不同场景的故障管理。 + +| 故障名称 | 故障监听 | 状态保存 | 自动重启 | 日志查询 | +| ----------|--------- |--------- |--------- |--------- | +| [JS_CRASH](../reference/apis/js-apis-faultLogger.md#faulttype) | 支持|支持|支持|支持| +| [APP_FREEZE](../reference/apis/js-apis-faultLogger.md#faulttype) | 不支持|不支持|支持|支持| +| [CPP_CRASH](../reference/apis/js-apis-faultLogger.md#faulttype) | 不支持|不支持|不支持|支持| + +这里状态保存指的是故障时状态保存,对于应用卡死场景,开发者可以采用定时保存状态或者在Ability切入后台后自动保存的方式最大限度的保护用户数据。 + + + +## 开发示例 + +### 使能开启自恢复特性 + + 开发者需要在应用模块初始化时使能appRecovery功能。下面为示例的AbilityStage。 + +```ts +import AbilityStage from '@ohos.app.ability.AbilityStage' +import appRecovery from '@ohos.app.ability.appRecovery' + +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); + } +} +``` + +### 数据保存和恢复 + +在使能appRecovery功能后,开发者可以在Ability中采用主动保存状态,主动恢复或者选择被动恢复的方式使用appRecovery功能。 +下面为示例的MainAbility。 + +#### 导包 + +```ts +import errorManager from '@ohos.app.ability.errorManager' +import appRecovery from '@ohos.app.ability.appRecovery' +import AbilityConstant from '@ohos.app.ability.AbilityConstant' +``` + +#### 主动触发保存和恢复 + +- 定义和注册[ErrorObserver](../reference/apis/js-apis-errorManager.md#errorobserver) callback + +```ts + var registerId = -1; + var callback = { + onUnhandledException: function (errMsg) { + console.log(errMsg); + appRecovery.saveAppState(); + appRecovery.restartApp(); + } + } + + onWindowStageCreate(windowStage) { + // Main window is created, set main page for this ability + console.log("[Demo] MainAbility onWindowStageCreate") + + globalThis.registerObserver = (() => { + registerId = errorManager.registerErrorObserver(callback); + }) + + windowStage.loadContent("pages/index", null); + } +``` + +- 数据保存 + +callback触发appRecovery.saveAppState()调用后,会触发MainAbility的onSaveState(state, wantParams)函数回调。 + +```ts + onSaveState(state, wantParams) { + // Ability has called to save app data + console.log("[Demo] MainAbility onSaveState") + wantParams["myData"] = "my1234567"; + return AbilityConstant.onSaveResult.ALL_AGREE; + } +``` + +- 数据恢复 + +callback触发后appRecovery.restartApp()调用后,应用会重启,重启后会走到MainAbility的onSaveState(state, wantParams)函数,保存的数据会在want参数的parameters里。 + +```ts +storage: LocalStorage +onCreate(want, launchParam) { + console.log("[Demo] MainAbility onCreate") + globalThis.abilityWant = want; + if (launchParam.launchReason == AbilityConstant.LaunchReason.APP_RECOVERY) { + this.storage = new LocalStorage(); + let recoveryData = want.parameters["myData"]; + this.storage.setOrCreate("myData", recoveryData); + this.context.restoreWindowStage(this.storage); + } +} +``` + +- 取消注册ErrorObserver callback + +```ts +onWindowStageDestroy() { + // Main window is destroyed, release UI related resources + console.log("[Demo] MainAbility onWindowStageDestroy") + + globalThis.unRegisterObserver = (() => { + errorManager.unregisterErrorObserver(registerId, (result) => { + console.log("[Demo] result " + result.code + ";" + result.message) + }); + }) +} +``` + +#### 被动保存和恢复 + +被动保存和恢复依赖恢复框架底层触发,无需注册监听ErrorObserver callback,只需实现Ability的onSaveState接口数据保存和onCreate接口数据恢复流程即可。 + +```ts +export default class MainAbility extends Ability { + storage: LocalStorage + onCreate(want, launchParam) { + console.log("[Demo] MainAbility onCreate") + globalThis.abilityWant = want; + if (launchParam.launchReason == AbilityConstant.LaunchReason.APP_RECOVERY) { + this.storage = new LocalStorage(); + let recoveryData = want.parameters["myData"]; + this.storage.setOrCreate("myData", recoveryData); + this.context.restoreWindowStage(this.storage); + } + } + + onSaveState(state, wantParams) { + // Ability has called to save app data + console.log("[Demo] MainAbility onSaveState") + wantParams["myData"] = "my1234567"; + return AbilityConstant.onSaveResult.ALL_AGREE; + } +} +``` + diff --git a/zh-cn/application-dev/dfx/figures/20221106203527.png b/zh-cn/application-dev/dfx/figures/20221106203527.png new file mode 100644 index 0000000000000000000000000000000000000000..4f47f6ddd487f82723e68520c1bb3a52875d9a2c Binary files /dev/null and b/zh-cn/application-dev/dfx/figures/20221106203527.png differ diff --git a/zh-cn/application-dev/reference/apis/js-apis-app-ability-appRecovery.md b/zh-cn/application-dev/reference/apis/js-apis-app-ability-appRecovery.md new file mode 100644 index 0000000000000000000000000000000000000000..ae6136c862c3d60dcd90261e3c9d48f01c13e7ef --- /dev/null +++ b/zh-cn/application-dev/reference/apis/js-apis-app-ability-appRecovery.md @@ -0,0 +1,122 @@ +# appRecovery + +appRecovery模块提供了应用在故障状态下的恢复能力。 + +> **说明:** +> +> 本模块首批接口从API version 9开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。当前版本仅支持单进程中单Ability的应用恢复。 + +## 导入模块 +``` +import appRecovery from '@ohos.app.ability.appRecovery' +``` + + +## appRecovery.RestartFlag + +[enableAppRecovery](#apprecoveryenableapprecovery)接口重启选项参数。 + +**系统能力**:以下各项对应的系统能力均为SystemCapability.Ability.AbilityRuntime.Core + +| 变量 | 值 | 说明 | +| ----------------------------- | ---- | ------------------------------------------------------------ | +| ALWAYS_RESTART | 0 | 总是重启应用。 | +| CPP_CRASH_NO_RESTART | 1 | 发生CPP_CRASH时不重启应用。 | +| JS_CRASH_NO_RESTART | 2 | 发生JS_CRASH时不重启应用。 | +| APP_FREEZE_NO_RESTART | 4 | 发生APP_FREEZE时不重启应用。 | +| NO_RESTART | 65535 | 总是不重启应用。 | + +## appRecovery.SaveOccasionFlag + +[enableAppRecovery](#apprecoveryenableapprecovery)接口状态保存时机选项参数。 + +**系统能力**:以下各项对应的系统能力均为SystemCapability.Ability.AbilityRuntime.Core + +| 变量 | 值 | 说明 | +| ----------------------------- | ---- | ------------------------------------------------------------ | +| SAVE_WHEN_ERROR | 1 | 当发生应用故障时保存。 | +| SAVE_WHEN_BACKGROUND | 2 | 当应用切入后台时保存。 | + +## appRecovery.SaveModeFlag + +[enableAppRecovery](#apprecoveryenableapprecovery)接口状态保存方式的参数。 + +**系统能力**:以下各项对应的系统能力均为SystemCapability.Ability.AbilityRuntime.Core + +| 变量 | 值 | 说明 | +| ----------------------------- | ---- | ------------------------------------------------------------ | +| SAVE_WITH_FILE | 1 | 每次状态保存都会写入到本地文件缓存。 | +| SAVE_WITH_SHARED_MEMORY | 2 | 状态先保存在内存中,应用故障退出时写入到本地文件缓存。 | + +## appRecovery.enableAppRecovery + +enableAppRecovery(restart?: RestartFlag, saveOccasion?: SaveOccasionFlag, saveMode?: SaveModeFlag) : void; + +使能应用恢复功能,参数按顺序填入。 + +**系统能力**:SystemCapability.Ability.AbilityRuntime.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------- | -------- | -------- | +| restart | [RestartFlag](#apprecoveryrestartflag) | 否 | 发生对应故障时是否重启,默认为不重启。 | +| saveOccasion | [SaveOccasionFlag](#apprecoverysaveoccasionflag) | 否 | 状态保存时机,默认为故障时保存。 | +| saveMode | [SaveModeFlag](#apprecoverysavemodeflag) | 否 | 状态保存方式, 默认为文件缓存。 | + +**示例:** + +```ts +export default class MyAbilityStage extends AbilityStage { + onCreate() { + appRecovery.enableAppRecovery(RestartFlag::ALWAYS_RESTART, SaveOccasionFlag::SAVE_WHEN_ERROR, SaveModeFlag::SAVE_WITH_FILE); + } +} +``` + +## appRecovery.restartApp + +restartApp(): void; + +重启当前App进程,可以配合[errorManager](js-apis-errorManager.md#errorobserver)相关接口使用。 + +**系统能力**:SystemCapability.Ability.AbilityRuntime.Core + + +**示例:** + +```ts +var observer = { + onUnhandledException(errorMsg) { + console.log('onUnhandledException, errorMsg: ', errorMsg) + appRecovery.restartApp(); + } +} + +``` + +## appRecovery.saveAppState + +saveAppState(): boolean; + +保存当前App状态,可以配合[errorManager](js-apis-errorManager.md#errorobserver)相关接口使用 + +**系统能力**:SystemCapability.Ability.AbilityRuntime.Core + +**返回值:** + +| 类型 | 说明 | +| -------- | -------- | +| boolean | 保存成功与否。 | + +**示例:** + +```ts +var observer = { + onUnhandledException(errorMsg) { + console.log('onUnhandledException, errorMsg: ', errorMsg) + appRecovery.saveAppState(); + } +} + +``` diff --git a/zh-cn/application-dev/reference/apis/js-apis-application-ability.md b/zh-cn/application-dev/reference/apis/js-apis-application-ability.md index fc61145af95542b9d40503644445fa2337f1c2d6..9f77de28addb28d66abe81edf4b5e0c7bd827c15 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-application-ability.md +++ b/zh-cn/application-dev/reference/apis/js-apis-application-ability.md @@ -315,6 +315,40 @@ onMemoryLevel(level: AbilityConstant.MemoryLevel): void; ``` +## Ability.onSaveState + +onSaveState(reason: AbilityConstant.StateType, wantParam : {[key: string]: any}): AbilityConstant.OnSaveResult; + +该API配合[appRecovery](js-apis-app-ability-appRecovery.md)使用。在应用故障时,如果使能了自动保存状态,框架将回调onSaveState保存Ability状态。 + +**系统能力**:SystemCapability.Ability.AbilityRuntime.AbilityCore + +**参数:** + + | 参数名 | 类型 | 必填 | 说明 | + | -------- | -------- | -------- | -------- | + | reason | [AbilityConstant.StateType](js-apis-application-abilityConstant.md#abilityconstantstatetype) | 是 | 回调保存状态的原因。 | + | wantParam | {[key: string]: any} | 是 | want相关参数。 | + +**返回值:** + + | 类型 | 说明 | + | -------- | -------- | + | AbilityConstant.OnSaveResult | 是否同意保存当前Ability的状态。 | + +**示例:** + + ```js + class myAbility extends Ability { + onSaveState(reason, wantParam) { + console.log('onSaveState'); + wantParams["myData"] = "my1234567"; + return AbilityConstant.OnSaveResult.RECOVERY_AGREE; + } + } + ``` + + ## Caller diff --git a/zh-cn/application-dev/reference/apis/js-apis-application-abilityConstant.md b/zh-cn/application-dev/reference/apis/js-apis-application-abilityConstant.md index affcdf6022b3c7d02f0b165a0b408539afd287a0..2ad41649d261c4a03316fc4d2a5bb65ee0b66002 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-application-abilityConstant.md +++ b/zh-cn/application-dev/reference/apis/js-apis-application-abilityConstant.md @@ -36,6 +36,7 @@ import AbilityConstant from '@ohos.application.AbilityConstant'; | START_ABILITY | 1 | 启动能力。 | | CALL | 2 | 呼叫。 | | CONTINUATION | 3 | 继续。 | +| APP_RECOVERY | 4 | 状态恢复。 | ## AbilityConstant.LastExitReason @@ -88,3 +89,29 @@ import AbilityConstant from '@ohos.application.AbilityConstant'; | MEMORY_LEVEL_MODERATE | 0 | 内存占用适中。 | | MEMORY_LEVEL_LOW | 1 | 内存占用低。 | | MEMORY_LEVEL_CRITICAL | 2 | 内存占用高。 | + +## AbilityConstant.OnSaveResult + +保存应用数据的结果类型。 + +**系统能力**:以下各项对应的系统能力均为SystemCapability.Ability.AbilityRuntime.Core + +| 变量 | 值 | 说明 | +| ----------------------------- | ---- | ------------------------------------------------------------ | +| ALL_AGREE | 0 | 同意保存状态。 | +| CONTINUATION_REJECT | 1 | 拒绝迁移保存状态。 | +| CONTINUATION_MISMATCH | 2 | 迁移不匹配。| +| RECOVERY_AGREE | 3 | 同意恢复保存状态。 | +| RECOVERY_REJECT | 4 | 拒绝恢复保存状态。| +| ALL_REJECT | 5 | 拒绝保存状态。| + +## AbilityConstant.StateType + +保存应用数据场景原因类型。 + +**系统能力**:以下各项对应的系统能力均为SystemCapability.Ability.AbilityRuntime.Core + +| 变量 | 值 | 说明 | +| ----------------------------- | ---- | ------------------------------------------------------------ | +| CONTINUATION | 0 | 迁移保存状态。 | +| APP_RECOVERY | 1 | 应用恢复保存状态。 |