diff --git a/zh-cn/application-dev/dfx/apprecovery-guidelines.md b/zh-cn/application-dev/dfx/apprecovery-guidelines.md index 32d673bae7f18506e4062ddefe5dddac81eb8921..393083bb068e7f282675e166e24c012e2dd0e877 100644 --- a/zh-cn/application-dev/dfx/apprecovery-guidelines.md +++ b/zh-cn/application-dev/dfx/apprecovery-guidelines.md @@ -5,29 +5,48 @@ 应用在运行中不可避免会产生一些非预期的行为,如运行时抛出未处理的异常和错误,违反框架的调用/运行约束等。 系统默认对异常的处理方式为进程退出,如果应用使用过程中产生了用户数据,直接退出可能会导致用户工作中断,数据丢失。 -如果使用应用故障恢复相关接口,则可对临时数据进行保存,应用退出后会重启应用并恢复先前的状态和数据,能给用户带来更好的使用体验。 +如果应用使能了应用恢复功能,并对临时数据进行保存,应用非预期退出后的下一次启动会恢复先前的状态和数据,给用户更连贯的使用体验。这里状态包括应用的页面栈以及onSaveState接口中保存的数据。 -目前该接口仅支持单进程单Ability的Stage模型应用开发。 +API 9上的应用恢复接口支持单Ability的Stage模型应用开发。支持JsError故障时的状态保存与自动重启。 + +API 10在API 9的基础上新增支持多Ability的Stage模型应用开发。支持AppFreeze故障时的状态保存回调。支持应用被管控模式杀死后,下次启动的状态恢复。 ## 接口说明 -应用故障恢复接口由appRecovery模块提供,开发者可以通过import引入,详见[开发示例](#开发示例)。本文档描述的为API9版本的接口行为,后续接口行为变更会更新本文档。 +应用故障恢复接口由appRecovery模块提供,开发者可以通过import引入,详见[开发示例](#开发示例)。 ### 应用恢复接口功能介绍 | 接口名称 | 说明 | | ------------------------------------------------------------ | ---------------------------------------------------- | -| enableAppRecovery(restart?: RestartFlag, saveOccasion?: SaveOccasionFlag, saveMode?: SaveModeFlag) : void; | 使能应用恢复功能。| -| saveAppState(): boolean; | 主动保存当前应用中Ability的状态。 | -| restartApp(): void; | 重启当前进程,如果有已经保存的Ability状态,会在Ability的OnCreate生命周期回调的want参数中的wantParam属性传入。 | +| enableAppRecovery(restart?: RestartFlag, saveOccasion?: SaveOccasionFlag, saveMode?: SaveModeFlag) : void;9+ | 使能应用恢复功能,参数按顺序填入。该接口调用后,应用从启动器启动时第一个Ability支持恢复。| +| saveAppState(): boolean;9+ | 主动保存当前应用中支持恢复的Ability的状态。 | +| restartApp(): void;9+ | 重启当前进程,并启动由**setRestartWant**指定的Ability,如果未指定,将重新拉起处于前台且支持恢复的Ability。 | +| saveAppState(context?: UIAbilityContext): boolean;10+ | 主动保存由Context指定的Ability状态。 | +| setRestartWant(want: Want): void;10+ | 设置主动调用**restartApp**以及**RestartFlag**不为**NO_RESTART**时重启的Ability。该Ability必须在同一个包名下,且必须为**UiAbility**。 | -由于本接口为故障处理时使用,不会返回异常,需要开发者熟悉使用的场景。 +由于上述接口可能在故障处理时使用,所以不会返回异常,需要开发者熟悉使用的场景。 **enableAppRecovery:** 需要在应用初始化阶段调用,比如AbilityStage的OnCreate调用赋能。具体其各参数定义详见[参数说明](../reference/apis/js-apis-app-ability-appRecovery.md)。 -**saveAppState:** 调用后框架会回调Ability的onSaveState方法,如果在onSaveState方法中同意保存数据,则会将相关数据及Ability的页面栈持久化到应用的本地缓存。 +**saveAppState:** 调用后框架会回调**当前进程中所有支持恢复的Ability**的onSaveState方法,如果在onSaveState方法中同意保存数据,则会将相关数据及Ability的页面栈持久化到应用的本地缓存。如果需要保存指定Ability,则需要指定Ability对应的Context。 + +**setRestartWant:** 指定由appRecovery发起重启的Ability。 + +**restartApp:** 调用后框架会杀死当前应用进程,并重新拉起由**setRestartWant**指定的Ability,其中启动原因为APP_RECOVERY。API 9以及未使用**setRestartWant**指定Ability的场景,会拉起最后一个支持恢复且在前台的Ability,如果当前前台的Ability不支持恢复,则应用表现闪退。如果重启的Ability存在已经保存的状态,这些状态数据会在Ability的OnCreate生命周期回调的want参数中作为wantParam属性传入。 + +### 应用恢复状态管理示意 +从API 10起,应用恢复的场景不仅局限于异常时自动重启。所以需要理解应用何时会加载恢复的状态。 +一句话概括就是**如果应用任务的上次退出不是由用户发起的,且应用存在用于恢复的状态,应用下一次由用户拉起时的启动原因会被设为APP_RECOVERY,并清理该任务的恢复状态。** +应用恢复状态标识会在状态保存接口主动或者被动调用时设置。在该任务正常退出或者消费了该状态时清理。正常退出目前包括用户按**后退键退出**以及用户**清理最近任务**。 + +![应用恢复状态管理示意](./figures/20230315112155.png) -**restartApp:** 调用后框架会杀死当前应用进程,并重新拉起处于前台的Ability,其中启动原因为APP_RECOVERY。 +### 应用卡死的状态保存及恢复 +API 10开始支持应用卡死时的状态保存。JsError故障时,onSaveState接口在主线程进行回调。对于AppFreeze故障,主线程可能处于卡死的状态,onSaveState会在非主线程进行回调。其主要流程如下图: + +![应用卡死状态保存恢复示意](./figures/20230315112235.png) +由于卡死时的回调不在JS线程上执行,onSaveState回调中的代码建议不要使用import进来的Native动态库,禁止访问主线程创建的thread_local对象。 ### 框架故障管理流程示意 @@ -52,7 +71,7 @@ | 故障名称 | 故障监听 | 状态保存 | 自动重启 | 日志查询 | | ----------|--------- |--------- |--------- |--------- | | [JS_CRASH](../reference/apis/js-apis-faultLogger.md#faulttype) | 支持|支持|支持|支持| -| [APP_FREEZE](../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切入后台后自动保存的方式最大限度的保护用户数据。 @@ -77,6 +96,18 @@ export default class MyAbilityStage extends AbilityStage { appRecovery.SaveModeFlag.SAVE_WITH_FILE); } } +``` +### 配置支持恢复的Ability +Ability的配置清单一般的名字为module.json5。 +```json +{ + "abilities": [ + { + "name": "EntryAbility", + "recoverable": true, + }] +} + ``` ### 数据保存和恢复 diff --git a/zh-cn/application-dev/dfx/figures/20230315112155.png b/zh-cn/application-dev/dfx/figures/20230315112155.png new file mode 100644 index 0000000000000000000000000000000000000000..20324a0b23f2b409c2fef8daaa74bcccd5427398 Binary files /dev/null and b/zh-cn/application-dev/dfx/figures/20230315112155.png differ diff --git a/zh-cn/application-dev/dfx/figures/20230315112235.png b/zh-cn/application-dev/dfx/figures/20230315112235.png new file mode 100644 index 0000000000000000000000000000000000000000..34cf30ce75516810536335bd9a2789517360eae3 Binary files /dev/null and b/zh-cn/application-dev/dfx/figures/20230315112235.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 index a513c1d0c68d7e5386529c0ab378aee6f6cfad7f..8658417d06f5e70a9f87a3ae9555a6fa82a628fa 100644 --- 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 @@ -4,7 +4,7 @@ appRecovery模块提供了应用在故障状态下的恢复能力。 > **说明:** > -> 本模块首批接口从API version 9开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。当前版本仅支持单进程中单Ability的应用恢复。 +> 本模块首批接口从API version 9开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。API9仅支持单进程中单Ability的应用恢复。API10支持进程中包含多个Ability的场景。 ## 导入模块 ```ts @@ -51,7 +51,7 @@ import appRecovery from '@ohos.app.ability.appRecovery'; enableAppRecovery(restart?: [RestartFlag](#apprecoveryrestartflag), saveOccasion?: [SaveOccasionFlag](#apprecoverysaveoccasionflag), saveMode?: [SaveModeFlag](#apprecoverysavemodeflag)) : void; -使能应用恢复功能,参数按顺序填入。 +使能应用恢复功能,参数按顺序填入。该接口调用后,应用从启动器启动时第一个Ability支持恢复。 **系统能力**:SystemCapability.Ability.AbilityRuntime.Core @@ -84,7 +84,14 @@ export default class MyAbilityStage extends AbilityStage { restartApp(): void; -重启当前App进程,可以配合[errorManager](js-apis-app-ability-errorManager.md)相关接口使用。 +重启当前进程,并拉起应用启动时第一个Ability,如果该Ability存在已经保存的状态,这些状态数据会在Ability的OnCreate生命周期回调的want参数中作为wantParam属性传入。 + +API10时将启动由[setRestartWant](#apprecoverysetrestartwant)指定的Ability。如果没有指定则按以下规则启动:\ +如果当前应用前台的Ability支持恢复,则重新拉起该Ability。\ +如果存在多个支持恢复的Ability处于前台,则只拉起最后一个。\ +如果没有Ability处于前台,则不拉起。 + +可以配合[errorManager](js-apis-app-ability-errorManager.md)相关接口使用。 **系统能力**:SystemCapability.Ability.AbilityRuntime.Core @@ -142,3 +149,53 @@ try { console.error('error: ${paramError.code}, ${paramError.message}'); } ``` + +## appRecovery.saveAppState10+ + +saveAppState(context?: UIAbilityContext): boolean; + +主动保存Ability的状态,这个状态将在下次恢复启动时使用。可以配合[errorManager](js-apis-app-ability-errorManager.md)相关接口使用 + +**系统能力**:SystemCapability.Ability.AbilityRuntime.Core + +**返回值:** + +| 类型 | 说明 | +| -------- | -------- | +| boolean | 保存成功与否。true:保存成功,false:保存失败。 | + +**示例:** + +```ts +import appRecovery from '@ohos.app.ability.appRecovery'; +onBackground() { + hilog.info(0x0000, '[demo]', '%{public}s', 'EntryAbility onBackground'); + appRecovery.saveAppState(this.context) +} +``` + +## appRecovery.setRestartWant10+ + +setRestartWant(want: Want): void; + +设置下次恢复主动拉起场景下的Ability。该Ability必须为当前包下的UIAbility。 + +**系统能力**:SystemCapability.Ability.AbilityRuntime.Core + +**示例:** + +```ts +import appRecovery from '@ohos.app.ability.appRecovery'; +Button("启动到恢复Ability") + .fontSize(40) + .fontWeight(FontWeight.Bold) + .onClick(()=> { + // set restart want + let want = { + bundleName: "ohos.samples.recovery", + abilityName: "RecoveryAbility" + }; + + appRecovery.setRestartWant(want); + }) +``` \ No newline at end of file diff --git a/zh-cn/release-notes/changelogs/OpenHarmony_4.0.5.2/changelogs-ability.md b/zh-cn/release-notes/changelogs/OpenHarmony_4.0.5.2/changelogs-ability.md new file mode 100644 index 0000000000000000000000000000000000000000..ba5ef87f8bb33c7ffb56cba4e92e711f07248c79 --- /dev/null +++ b/zh-cn/release-notes/changelogs/OpenHarmony_4.0.5.2/changelogs-ability.md @@ -0,0 +1,64 @@ +# 元能力子系统ChangeLog + +## cl.ability.appRecovery新增saveAppState接口 + +新增接口saveAppState(context?: UIAbilityContext): boolean; + +**变更影响** + +基于OpenHarmony4.0.5.2及之后的SDK版本开发的应用,可以使用saveAppState接口传入指定Ability Context,实现主动保存指定的Ability状态。 + +**关键接口/组件变更** + +@ohos.app.ability.appRecovery.d.ts中新增saveAppState接口。 + +| 模块名 | 类名 | 方法/属性/枚举/常量 | 变更类型 | +| -- | -- | -- | -- | +| @ohos.app.ability.appRecovery.d.ts | appRecovery | saveAppState(context?: UIAbilityContext): boolean; | 新增 | + +**适配指导** + +通过调用saveAppState传入UIAbility Context参数主动保存此指定的Ability的状态。 + +```ts +import appRecovery from '@ohos.app.ability.appRecovery'; +onBackground() { + hilog.info(0x0000, '[demo]', '%{public}s', 'EntryAbility onBackground'); + appRecovery.saveAppState(this.context) +} +``` +## cl.ability.appRecovery新增setRestartWant接口 + +新增接口setRestartWant(want: Want): void; + +**变更影响** + +基于OpenHarmony4.0.5.2及之后的SDK版本开发的应用,可以使用setRestartWant接口设置下次由恢复主动拉起场景下的Ability。 + +**关键接口/组件变更** + +@ohos.app.ability.appRecovery.d.ts中新增setRestartWant接口。 + +| 模块名 | 类名 | 方法/属性/枚举/常量 | 变更类型 | +| -- | -- | -- | -- | +| @ohos.app.ability.appRecovery.d.ts | appRecovery | setRestartWant(want: Want): void; | 新增 | + +**适配指导** + +通过调用setRestartWant设置下次恢复到的指定Ability。 + +```ts +import appRecovery from '@ohos.app.ability.appRecovery'; +Button("启动到恢复Ability") + .fontSize(40) + .fontWeight(FontWeight.Bold) + .onClick(()=> { + // set restart want + let want = { + bundleName: "ohos.samples.recovery", + abilityName: "RecoveryAbility" + }; + + appRecovery.setRestartWant(want); + }) +``` \ No newline at end of file