diff --git a/zh-cn/application-dev/application-models/Readme-CN.md b/zh-cn/application-dev/application-models/Readme-CN.md index 2f5d818537a2e5020a0ab1617597d0b14427a5f4..e7482b11c9aafef87d85b70a0359cc97a3b43a3d 100644 --- a/zh-cn/application-dev/application-models/Readme-CN.md +++ b/zh-cn/application-dev/application-models/Readme-CN.md @@ -62,7 +62,7 @@ - 应用组件跨设备交互(流转) - [流转概述](inter-device-interaction-hop-overview.md) - [跨端迁移](hop-cross-device-migration.md) - - [多端协同(仅对系统应用开放)](hop-multi-device-collaboration.md) + - [多端协同](hop-multi-device-collaboration.md) - [订阅系统环境变量的变化](subscribe-system-environment-variable-changes.md) - 了解进程模型 - [进程模型概述](process-model-stage.md) diff --git a/zh-cn/application-dev/application-models/figures/hop-cross-device-migration.png b/zh-cn/application-dev/application-models/figures/hop-cross-device-migration.png index 6c5c343855af5e4c5d8473d7df26869468c19a0a..0f1a8f1e2ac353c241517fc30934af1fc615de63 100644 Binary files a/zh-cn/application-dev/application-models/figures/hop-cross-device-migration.png and b/zh-cn/application-dev/application-models/figures/hop-cross-device-migration.png differ diff --git a/zh-cn/application-dev/application-models/figures/hop-cross-device-migration1.png b/zh-cn/application-dev/application-models/figures/hop-cross-device-migration1.png index 952218badc407b8bc2470fc1622ae0e607c4bcfb..f77c36aa5967667723fd6011dce815496148f6f3 100644 Binary files a/zh-cn/application-dev/application-models/figures/hop-cross-device-migration1.png and b/zh-cn/application-dev/application-models/figures/hop-cross-device-migration1.png differ diff --git a/zh-cn/application-dev/application-models/figures/hop-cross-device-migration2.png b/zh-cn/application-dev/application-models/figures/hop-cross-device-migration2.png index a81cb2ab08506f4e368c6002be18d6931a056218..86158bc2bcd54b83e8dc73aec204788aab0b95a3 100644 Binary files a/zh-cn/application-dev/application-models/figures/hop-cross-device-migration2.png and b/zh-cn/application-dev/application-models/figures/hop-cross-device-migration2.png differ diff --git a/zh-cn/application-dev/application-models/figures/hop-cross-device-migration3.png b/zh-cn/application-dev/application-models/figures/hop-cross-device-migration3.png index 86158bc2bcd54b83e8dc73aec204788aab0b95a3..d46240bdfae944134af616f655e9bcd4fa9a651b 100644 Binary files a/zh-cn/application-dev/application-models/figures/hop-cross-device-migration3.png and b/zh-cn/application-dev/application-models/figures/hop-cross-device-migration3.png differ diff --git a/zh-cn/application-dev/application-models/figures/hop-cross-device-migration4.png b/zh-cn/application-dev/application-models/figures/hop-cross-device-migration4.png index c743b3d10f8f1fa0a8be76cf10fff219c52d0ebf..12353f3c01b8336e3acfc916ae10411946ba6295 100644 Binary files a/zh-cn/application-dev/application-models/figures/hop-cross-device-migration4.png and b/zh-cn/application-dev/application-models/figures/hop-cross-device-migration4.png differ diff --git a/zh-cn/application-dev/application-models/figures/hop-cross-device-migration5.png b/zh-cn/application-dev/application-models/figures/hop-cross-device-migration5.png index 854af7b632121a52c9e0364efb407b209dfb63bf..bd7fd15ba712854451e4970770c3d27bcb0c451f 100644 Binary files a/zh-cn/application-dev/application-models/figures/hop-cross-device-migration5.png and b/zh-cn/application-dev/application-models/figures/hop-cross-device-migration5.png differ diff --git a/zh-cn/application-dev/application-models/figures/hop-cross-device-migration6.png b/zh-cn/application-dev/application-models/figures/hop-cross-device-migration6.png index 2d38c00bbb5d268b8072dac4b8bf22238bbe869b..45972436d1130be2521b1cbaf4c0dd59b737221d 100644 Binary files a/zh-cn/application-dev/application-models/figures/hop-cross-device-migration6.png and b/zh-cn/application-dev/application-models/figures/hop-cross-device-migration6.png differ diff --git a/zh-cn/application-dev/application-models/figures/hop-cross-device-migration7.png b/zh-cn/application-dev/application-models/figures/hop-cross-device-migration7.png deleted file mode 100644 index e789d748fe97d3c08bfaa6d22cf151bee31eccc9..0000000000000000000000000000000000000000 Binary files a/zh-cn/application-dev/application-models/figures/hop-cross-device-migration7.png and /dev/null differ diff --git a/zh-cn/application-dev/application-models/hop-cross-device-migration.md b/zh-cn/application-dev/application-models/hop-cross-device-migration.md index dabca884bdec8de6584efd27acf9629f1f0c658a..e165e21508a8759056e98f1d73319255cdb5012e 100644 --- a/zh-cn/application-dev/application-models/hop-cross-device-migration.md +++ b/zh-cn/application-dev/application-models/hop-cross-device-migration.md @@ -1,61 +1,52 @@ # 跨端迁移 -## 功能描述 +## 概述 -跨端迁移的主要工作是实现将应用当前任务(包括页面控件状态变量等)迁移到目标设备,能在目标设备上接续。主要功能包括: +在用户使用设备的过程中,当使用情境发生变化时(例如从室内走到户外或者周围有更适合的设备等),之前使用的设备可能已经不适合继续当前的任务,此时,用户可以选择新的设备来继续当前的任务,原设备可按需决定是否退出任务,这个就是跨端迁移的场景。常见的跨端迁移场景实例:在平板上播放的视频,迁移到智慧屏继续播放,从而获得更佳的观看体验;平板上的视频应用退出。在应用开发层面,跨端迁移指在A端运行的UIAbility迁移到B端上,完成迁移后,B端UIAbility继续任务,而A端UIAbility可按需决定是否退出。 -- 支持用户自定义数据存储及恢复。 -- 支持页面路由信息和页面控件状态数据的存储及恢复。 -- 支持应用兼容性检测。 -- 支持应用根据实际使用场景动态设置迁移状态(默认迁移状态为 **ACTIVE** 激活状态)。如编辑类应用在编辑文本的页面下才需要迁移,其他页面不需要迁移,则可以通过[setMissionContinueState](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissioncontinuestate10)进行控制。 -- 支持应用动态选择是否进行页面栈恢复(默认进行页面栈信息恢复)。如应用希望自定义迁移到其他设备后显示的页面,则可以通过[SUPPORT_CONTINUE_PAGE_STACK_KEY](../reference/apis/js-apis-app-ability-wantConstant.md#wantconstantparams)进行控制。 -- 支持应用动态选择迁移成功后是否退出迁移发起端应用(默认迁移成功后退出迁移发起端应用)。则可以通过[SUPPORT_CONTINUE_SOURCE_EXIT_KEY](../reference/apis/js-apis-app-ability-wantConstant.md#wantconstantparams)进行控制。 +跨端迁移的核心任务是将应用的当前状态(包括页面控件、状态变量等)无缝迁移到另一设备,从而在新设备上无缝接续应用体验。这意味着用户在一台设备上进行的操作可以在另一台设备的相同应用中快速切换并无缝衔接。 +主要功能包括: -## 跨端迁移流程 - -跨端迁移流程如下图所示。 - -**图1** 跨端迁移流程图 -![hop-cross-device-migration](figures/hop-cross-device-migration.png) +- 支持用户自定义数据存储及恢复。 +- 支持页面路由信息和页面控件状态数据的存储及恢复。 -## 约束限制 +- 支持应用兼容性检测。 -- 应用迁移的发起依赖系统应用控制,系统应用开发者可以参考[验证指导中的demo示例](#验证指导)实现相关的控制能力。 -- 跨端迁移要求在同UIAbility之间进行,也就是需要相同的bundleName、abilityName和签名。 -- 为了获得最佳体验,使用wantParam传输的数据建议在100KB以下。 +- 支持应用根据实际使用场景动态设置迁移状态(默认迁移状态为 **ACTIVE** 激活状态)。例如,编辑类应用在编辑文本的页面下才需要迁移,其他页面不需要迁移,则可以通过[`setMissionContinueState`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissioncontinuestate10)进行控制。 +- 支持应用动态选择是否进行页面栈恢复(默认进行页面栈信息恢复)。例如,应用希望自定义迁移到其他设备后显示的页面,则可以通过[`SUPPORT_CONTINUE_PAGE_STACK_KEY`](../reference/apis/js-apis-app-ability-wantConstant.md#wantconstantparams)进行控制。 -## 接口说明 +- 支持应用动态选择迁移成功后是否退出迁移源端应用(默认迁移成功后退出迁移源端应用)。可以通过[`SUPPORT_CONTINUE_SOURCE_EXIT_KEY`](../reference/apis/js-apis-app-ability-wantConstant.md#wantconstantparams)进行控制。 -跨端迁移主要接口如下。详细接口介绍请参见[API参考](../reference/apis/js-apis-app-ability-uiAbility.md)。 + > **说明:** + > + > 开发者可以开发具有迁移能力的应用,迁移的触发由系统应用完成。 - **表1** 跨端迁移接口 -| **接口名** | **描述** | -| -------- | -------- | -| onContinue(wantParam : {[key: string]: Object}): OnContinueResult | 迁移发起端在该回调中保存迁移所需要的数据,同时返回是否同意迁移:
- AGREE:表示同意。
- REJECT:表示拒绝:如应用在onContinue中异常会导致钱以后数据恢复时显示异常,则可以建议REJECT。
- MISMATCH:表示版本不匹配:迁移发起端应用可以在onContinue中获取到迁移目标端应用的版本号,进行协商后,如果版本不匹配导致无法迁移,可以返回该错误。 | -| onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void; | 应用迁移目标端为冷启动或多实例应用热启动时,在该回调中完成数据恢复,并触发页面恢复。详见[应用组件启动模式](uiability-launch-type.md) | -| onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void; | 迁移目标端为单实例应用热启动时,在该回调中完成数据恢复,并触发页面恢复。详见[应用组件启动模式](uiability-launch-type.md) | +## 运作机制 +![hop-cross-device-migration](figures/hop-cross-device-migration.png) +1. 在源端,通过`UIAbility`的[`onContinue()`](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue)回调,开发者可以保存待接续的业务数据。例如,在浏览器应用中完成跨端迁移,开发者需要使用[`onContinue()`](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue)回调保存页面URL等业务内容,而系统将自动保存页面状态,如当前浏览进度。 +2. 分布式框架提供了跨设备应用界面、页面栈以及业务数据的保存和恢复机制,它负责将数据从源端发送到对端。 +3. 在对端,同一`UIAbility`可以通过[`onCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)/[`onNewWant()`](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)接口来恢复业务数据。 -## 开发步骤 -1.需要申请`ohos.permission.DISTRIBUTED_DATASYNC`权限 - -配置方式请参见[配置文件权限声明](../security/accesstoken-guidelines.md#配置文件权限声明)。 +## 约束限制 -2.同时需要在应用首次启动时弹窗向用户申请授权 +- 跨端迁移要求在同一`UIAbility`之间进行,也就是需要相同的`bundleName`、`abilityName`和签名信息。 +- 为了获得最佳体验,使用`wantParam`传输的数据需要控制在100KB以下。 +- 当前部分ArkUI组件支持迁移后,将特定状态恢复到对端设备。详情请见[分布式迁移标识](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-restoreId.md) -使用方式请参见[向用户申请授权](../security/accesstoken-guidelines.md#向用户申请授权)。 +## 开发步骤 -3.在配置文件中配置跨端迁移相关标签字段。 +1. 需要申请`ohos.permission.DISTRIBUTED_DATASYNC`权限,配置方式请参见[配置文件权限声明](../security/accesstoken-guidelines.md#配置文件权限声明)。 -配置应用支持迁移 -在module.json5中配置continuable标签:true表示支持迁移,false表示不支持,默认为false。配置为false的UIAbility将被系统识别为无法迁移。 +2. 同时需要在应用首次启动时弹窗向用户申请授权,使用方式请参见[向用户申请授权](../security/accesstoken-guidelines.md#向用户申请授权)。 +3. 在[module.json5配置文件](../quick-start/module-configuration-file.md)的abilities标签中配置跨端迁移标签`continuable`。 ```json { @@ -64,92 +55,82 @@ "abilities": [ { // ... - "continuable": true, + "continuable": true, // 配置UIAbility支持迁移 } ] } } ``` - 根据需要配置应用启动模式类型,配置详情请参照[UIAbility组件启动模式](uiability-launch-type.md)。 - -4.在发起端UIAbility中实现[onContinue](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue)接口。 - -当应用触发迁移时,[onContinue](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue)接口在发起端被调用,开发者可以在该接口中保存迁移数据,实现应用兼容性检测,决定是否支持此次迁移。 - -- 保存迁移数据:开发者可以将要迁移的数据通过键值对的方式保存在wantParam中。 - -- 应用兼容性检测:开发者可以通过从wantParam中获取目标应用的版本号与本应用版本号做兼容性校验。开发者可以在触发迁移时从`onContinue`接口中`wantParam.version`获取到迁移目标端应用的版本号与迁移发起端应用版本号做兼容校验。 - -- 迁移决策:开发者可以通过onContinue接口的返回值决定是否支持此次迁移,返回值信息见[接口说明](#接口说明)。 - - 示例如下: - - ```ts - import UIAbility from '@ohos.app.ability.UIAbility'; - import AbilityConstant from '@ohos.app.ability.AbilityConstant'; - - export default class EntryAbility extends UIAbility { - onContinue(wantParam: Record) { - console.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`) // 准备迁移数据 - let continueInput = '迁移的数据'; - if (continueInput) { - // 将要迁移的数据保存在wantParam的自定义字段(如:data)中; - wantParam["data"] = continueInput; - } - console.info(`onContinue input = ${wantParam["data"]}`); - return AbilityConstant.OnContinueResult.AGREE; - } - } - ``` - -5.在Stage模型中,应用在不同启动模式下将调用不同的接口,以恢复数据、加载界面。 - -不同情况下的函数调用如下图所示: - -![hop-cross-device-migration](figures/hop-cross-device-migration1.png) + > **说明:** + > + > 根据需要配置应用启动模式类型,配置详情请参照[UIAbility组件启动模式](uiability-launch-type.md)。 + +4. 在源端`UIAbility`中实现[`onContinue()`](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue)回调。 + + 当`UIAbility`实例触发迁移时,[`onContinue()`](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue)回调在源端被调用,开发者可以在该接口中保存迁移数据,实现应用兼容性检测,决定是否支持此次迁移。 + + - 保存迁移数据:开发者可以将要迁移的数据通过键值对的方式保存在`wantParam`参数中。 + - 应用兼容性检测:开发者可以通过从`wantParam`参数中获取对端应用的版本号与[源端应用版本号](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/faqs/faqs-bundle-management.md)做兼容性校验。开发者可以在触发迁移时从[`onContinue()`](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue)回调中`wantParam.version`获取到迁移对端应用的版本号与迁移源端应用版本号做兼容校验。 + - 迁移决策:开发者可以通过[`onContinue()`](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue)回调的返回值决定是否支持此次迁移。 + + ```ts + import UIAbility from '@ohos.app.ability.UIAbility'; + import AbilityConstant from '@ohos.app.ability.AbilityConstant'; + + export default class EntryAbility extends UIAbility { + onContinue(wantParam: Record):AbilityConstant.OnContinueResult { + let version = wantParam.version; + let targetDevice = wantParam.targetDevice; + console.info(`onContinue version = ${version}, targetDevice: ${targetDevice}`); // 准备迁移数据 + + // 获取源端版本号 + let versionSrc: number = -1; // 请填充具体获取版本号的代码 + + // 兼容性校验 + if (version !== versionSrc) { + // 在兼容性校验不通过时返回MISMATCH + return AbilityConstant.OnContinueResult.MISMATCH; + } + + // 将要迁移的数据保存在wantParam的自定义字段(例如data)中 + const continueInput = '迁移的数据'; + wantParam['data'] = continueInput; + + return AbilityConstant.OnContinueResult.AGREE; + } + } + ``` -在目标端设备UIAbility中实现onCreate与onNewWant接口,恢复迁移数据。 - -- onCreate实现示例 - - 目标端设备上,在onCreate中根据launchReason判断该次启动是否为迁移LaunchReason.CONTINUATION。 - - 开发者可以从want中获取保存的迁移数据。 - - 完成数据恢复后,开发者需要调用restoreWindowStage来触发页面恢复:包括页面栈信息。 - - ```ts - 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 { - storage : LocalStorage = new LocalStorage(); - onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { - console.info(`EntryAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`) - if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) { - // 将上述的保存的数据取出恢复 - let continueInput = ''; - if (want.parameters != undefined) { - continueInput = JSON.stringify(want.parameters.data); - console.info(`continue input ${continueInput}`) - } - // 将数据显示当前页面 - this.context.restoreWindowStage(this.storage); - } - } - } - ``` -- 如果是单实例应用,需要额外实现onNewWant接口,实现方式与onCreate的实现相同。 - - 在onNewWant中判断迁移场景,恢复数据,并触发页面恢复 - - ```ts - 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 { - storage : LocalStorage = new LocalStorage(); - onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void { - console.info(`EntryAbility onNewWant ${AbilityConstant.LaunchReason.CONTINUATION}`) +5. 源端设备`UIAbility`实例在冷启动和热启动情况下分别会调用不同的接口来恢复数据和加载UI。 + 在对端设备的`UIAbility`中,需要实现[`onCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)/[`onNewWant()`](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)接口来恢复迁移数据。 + + 通过在[`onCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)/[`onNewWant()`](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)回调中检查`launchReason`,可以判断此次启动是否有迁移触发。开发者可以从`want`中获取之前保存的迁移数据,并在数据恢复后调用`restoreWindowStage()`来触发页面恢复,包括页面栈信息。 + + ```ts + 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 { + storage : LocalStorage = new LocalStorage(); + + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + console.info('EntryAbility onCreate') + if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) { + // 将上述的保存的数据取出恢复 + let continueInput = ''; + if (want.parameters != undefined) { + continueInput = JSON.stringify(want.parameters.data); + console.info(`continue input ${continueInput}`) + } + // 将数据显示当前页面 + this.context.restoreWindowStage(this.storage); + } + } + + onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void { + console.info('EntryAbility onNewWant') if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) { // get user data from want params let continueInput = ''; @@ -160,33 +141,29 @@ this.context.restoreWindowStage(this.storage); } } - } - ``` - - + } + ``` -## 迁移功能可选配置 +## 可选配置迁移能力 -### 1.动态配置迁移能力 +### 动态配置迁移能力 -从API 10 起,提供了支持动态配置迁移能力的功能。即应用可以根据实际使用场景,在需要迁移功能时,设置开启应用迁移能力;在业务不需要迁移时,则可以关闭迁移能力。开发者可以通过调用[setMissionContinueState](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissioncontinuestate10)接口对迁移能力进行设置。默认状态下,可迁移应用的迁移能力为**ACTIVE**状态,即迁移能力开启,可以迁移。 +从API version 10开始,提供了支持动态配置迁移能力的功能。即应用可以根据实际使用场景,在需要迁移时开启应用迁移能力;在业务不需要迁移时则可以关闭迁移能力。 -| 接口状态值 | 含义 | -| :------------------------------------- | ---------------------- | -| AbilityConstant.ContinueState.ACTIVE | 应用当前可迁移能力开启 | -| AbilityConstant.ContinueState.INACTIVE | 应用当前可迁移能力关闭 | +开发者可以通过调用[`setMissionContinueState()`](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissioncontinuestate10)接口对迁移能力进行设置。默认状态下,应用的迁移能力为**ACTIVE**状态,即迁移能力开启,可以迁移。 **设置迁移能力的时机** 迁移能力的改变可以根据实际业务需求和代码实现,发生在应用生命周期的绝大多数时机。本文介绍常用的几种配置方式。 -在ability的onCreate函数中调用接口,可以在应用创建时设置应用的迁移状态。 +在`UIAbility`的[`onCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)回调中调用接口,可以在应用创建时设置应用的迁移状态。 ```ts // EntryAbility.ets 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 { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { // ... @@ -198,12 +175,12 @@ export default class EntryAbility extends UIAbility { } ``` -在页面的onPageShow函数中调用接口,可以设置单个页面出现时应用的迁移状态。 +在页面的`onPageShow()`回调中调用接口,可以设置单个页面出现时应用的迁移状态。 ```ts // PageName.ets import AbilityConstant from '@ohos.app.ability.AbilityConstant'; -import common from '@ohos.app.ability.common' +import common from '@ohos.app.ability.common'; @Entry @Component struct PageName { @@ -215,18 +192,19 @@ struct PageName { onPageShow(){ // 进入该页面时,将应用设置为可迁移状态 this.context.setMissionContinueState(AbilityConstant.ContinueState.ACTIVE, (result) => { - console.info('setMissionContinueState ACTIVE result: ', JSON.stringify(result)); + console.info(`setMissionContinueState ACTIVE result: ${JSON.stringify(result)}`); }); } } ``` -在某个组件的触发事件中设置应用迁移能力。如下例中,使用 **Button** 组件的 **onClick** 事件,触发迁移能力的改变。 +在某个组件的触发事件中设置应用迁移能力。 ```ts // PageName.ets import AbilityConstant from '@ohos.app.ability.AbilityConstant'; -import common from '@ohos.app.ability.common' +import common from '@ohos.app.ability.common'; + @Entry @Component struct PageName { @@ -234,11 +212,11 @@ struct PageName { build() { // ... Button() { - //... + // ... }.onClick(()=>{ - //点击该按钮时,将应用设置为可迁移状态 + // 点击该按钮时,将应用设置为可迁移状态 this.context.setMissionContinueState(AbilityConstant.ContinueState.ACTIVE, (result) => { - console.info('setMissionContinueState ACTIVE result: ', JSON.stringify(result)); + console.info(`setMissionContinueState ACTIVE result: ${JSON.stringify(result)}`); }); }) } @@ -247,28 +225,30 @@ struct PageName { **保证迁移连续性** -由于迁移加载时,目标端拉起的应用可能执行过自己的迁移状态设置命令(如:冷启动时目标端在onCreate中设置了 **INACTIVE** ;热启动时对端已打开了不可迁移的页面,迁移状态为 **INACTIVE** 等情况)。为了保证迁移过后的应用依然具有可以迁移回发起端的能力,应在 onCreate和onNewWant的迁移调用判断中,将迁移状态设置为 **ACTIVE** 。 +由于迁移加载时,对端拉起的应用可能执行过自己的迁移状态设置命令(例如,冷启动时对端在[`onCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)中设置了 **INACTIVE** ;热启动时对端已打开了不可迁移的页面,迁移状态为 **INACTIVE** 等情况)。为了保证迁移过后的应用依然具有可以迁移回源端的能力,应在 [`onCreate()`](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate)/[`onNewWant()`](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)的迁移调用判断中,将迁移状态设置为 **ACTIVE** 。 ```ts // EntryAbility.ets 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 { // ... onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { // ... // 调用原因为迁移时,设置状态为可迁移,应对冷启动情况 this.context.setMissionContinueState(AbilityConstant.ContinueState.INACTIVE, (result) => { - console.info(`setMissionContinueState: ${JSON.stringify(result)}`); + console.info(`setMissionContinueState INACTIVE result: ${JSON.stringify(result)}`); }); } + onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void { // ... // 调用原因为迁移时,设置状态为可迁移,应对热启动情况 if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) { this.context.setMissionContinueState(AbilityConstant.ContinueState.ACTIVE, (result) => { - console.info('setMissionContinueState ACTIVE result: ', JSON.stringify(result)); + console.info(`setMissionContinueState ACTIVE result: ${JSON.stringify(result)}`); }); } } @@ -276,63 +256,62 @@ export default class EntryAbility extends UIAbility { } ``` +### 按需迁移页面栈 +支持应用动态选择是否进行页面栈恢复(默认进行页面栈信息恢复)。如果应用不想使用系统默认恢复的页面栈,则可以设置不进行页面栈迁移,而需要在`onWindowStageRestore()`设置迁移后进入的页面,参数定义见[SUPPORT_CONTINUE_PAGE_STACK_KEY](../reference/apis/js-apis-app-ability-wantConstant.md#wantconstantparams)。 -### 2.按需迁移页面栈 +应用在源端的页面栈中存在Index和Second路由,而在对端恢复时不需要按照源端页面栈进行恢复,需要恢复到指定页面。 -支持应用动态选择是否进行页面栈恢复(默认进行页面栈信息恢复)。如果应用不想使用系统默认恢复的页面栈,则可以设置不进行页面栈迁移,而需要在`onWindowStageRestore`设置迁移后进入的页面,参数定义见[SUPPORT_CONTINUE_PAGE_STACK_KEY](../reference/apis/js-apis-app-ability-wantConstant.md#wantconstantparams)。 +例如,`UIAbility`迁移不需要自动迁移页面栈信息。 -应用在发起端的页面栈中存在Index和Second路由,而在目标端恢复时不需要按照发起端页面栈进行恢复,需要恢复到指定页面。 +```ts +// EntryAbility.ets +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import wantConstant from '@ohos.app.ability.wantConstant'; +import window from '@ohos.window'; -- 示例:应用迁移不需要自动迁移页面栈信息 +export default class EntryAbility extends UIAbility { + // ... + + onContinue(wantParam: Record) { + console.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`); + wantParam[wantConstant.Params.SUPPORT_CONTINUE_PAGE_STACK_KEY] = false; + return AbilityConstant.OnContinueResult.AGREE; + } - ```ts - // EntryAbility.ets - import UIAbility from '@ohos.app.ability.UIAbility'; - import AbilityConstant from '@ohos.app.ability.AbilityConstant'; - import wantConstant from '@ohos.app.ability.wantConstant'; - import window from '@ohos.window'; - export default class EntryAbility extends UIAbility { - // ... - onContinue(wantParam: Record) { - console.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`); - wantParam[wantConstant.Params.SUPPORT_CONTINUE_PAGE_STACK_KEY] = false; - return AbilityConstant.OnContinueResult.AGREE; + onWindowStageRestore(windowStage: window.WindowStage) { + // 若不需要自动迁移页面栈信息,则需要在此处设置应用迁移后进入的页面 + windowStage.loadContent('pages/Index', (err, data) => { + if (err.code) { + return; } - // ... - onWindowStageRestore(windowStage: window.WindowStage) { - // 若不需要自动迁移页面栈信息,则需要在此处设置应用迁移后进入的页面 - windowStage.loadContent('pages/Index', (err, data) => { - if (err.code) { - console.info('Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); - return; - } - console.info('Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); - }); - } - } - ``` + }); + } +} +``` -### 3.按需退出 +### 按需退出 -支持应用动态选择迁移成功后是否退出迁移发起端应用(默认迁移成功后退出迁移发起端应用)。如果应用不想让系统自动退出迁移发起端应用,则可以设置不退出,参数定义见[SUPPORT_CONTINUE_SOURCE_EXIT_KEY](../reference/apis/js-apis-app-ability-wantConstant.md#wantconstantparams)。 +支持应用动态选择迁移成功后是否退出迁移源端应用(默认迁移成功后退出迁移源端应用)。如果应用不想让系统自动退出迁移源端应用,则可以设置不退出,参数定义见[SUPPORT_CONTINUE_SOURCE_EXIT_KEY](../reference/apis/js-apis-app-ability-wantConstant.md#wantconstantparams)。 -- 示例:应用迁移设置不需要迁移成功后退出迁移发起端应用 +示例:`UIAbility`设置迁移成功后,源端不需要退出迁移应用。 - ```ts - import UIAbility from '@ohos.app.ability.UIAbility'; - import AbilityConstant from '@ohos.app.ability.AbilityConstant'; - import wantConstant from '@ohos.app.ability.wantConstant'; - export default class EntryAbility extends UIAbility { - // ... - onContinue(wantParam: Record) { - console.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`); - wantParam[wantConstant.Params.SUPPORT_CONTINUE_SOURCE_EXIT_KEY] = false; - return AbilityConstant.OnContinueResult.AGREE; - } - // ... - } - ``` +```ts +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import wantConstant from '@ohos.app.ability.wantConstant'; + +export default class EntryAbility extends UIAbility { + // ... + + onContinue(wantParam: Record) { + console.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`); + wantParam[wantConstant.Params.SUPPORT_CONTINUE_SOURCE_EXIT_KEY] = false; + return AbilityConstant.OnContinueResult.AGREE; + } +} +``` ## 验证指导 @@ -344,54 +323,42 @@ export default class EntryAbility extends UIAbility { public-SDK不支持开发者使用所有的系统API,例如:全局任务中心使用的[**@ohos.distributedDeviceManager**](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-distributedDeviceManager.md)不包括在public_SDK中。因此为了正确编译安装全局任务中心,开发者需要替换full-SDK,具体操作可参见[替换指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/faqs/full-sdk-switch-guide.md)。 -**说明**:本文中的截图仅为参考,具体的显示界面请以实际使用的DevEco Studio和SDK的版本为准。 +> **说明**: +> +> 本文中的截图仅为参考,具体的显示界面请以实际使用的DevEco Studio和SDK的版本为准。 #### **下载MissionCenter_Demo[示例代码](https://gitee.com/openharmony/ability_dmsfwk/tree/master/services/dtbschedmgr/test/missionCenterDemo/dmsDemo/entry/src/main)** #### **编译工程文件** -**新建OpenHarmony 空的工程,找到对应的文件夹替换下载文件** - -![hop-cross-device-migration](figures/hop-cross-device-migration2.png) +​ a.新建OpenHarmony 空的工程,找到对应的文件夹替换下载文件 +![hop-cross-device-migration](figures/hop-cross-device-migration1.png) -**自动签名,编译安装。** +​ b.自动签名,编译安装。 ​ DevEco的自动签名模板默认签名权限为normal级。而本应用设计到ohos.permission.MANAGE_MISSIONS权限为system_core级别。自动生成的签名无法获得足够的权限,所以需要将权限升级为system_core级别,然后签名。 -**系统权限设置**(以api10目录为例): 将Sdk目录下的openharmony\api版本(如:10)\toolchains\lib\UnsgnedReleasedProfileTemplate.json文件中的"apl":"normal_core"改为"apl":"system_core"。 - -①点击file->Project Structrue - -![hop-cross-device-migration](figures/hop-cross-device-migration3.png) - -②点击Signing Configs 点击OK - -![hop-cross-device-migration](figures/hop-cross-device-migration4.png) - -③连接开发板运行生成demo。 - -### 2.设备组网 - -①打开A,B两设备的计算器 - -②点击右上角箭头选择B设备 - -③在B设备选择信任设备,弹出PIN码 - -④在A设备输入PIN码 - -⑤已组网成功,验证方法:在A设备输入数字,B设备同步出现则证明组网成功 - -### 3.发起迁移 - -1.在B设备打开多设备协同权限的应用,A设备打开全局任务中心demo,A设备出现A设备名称(即:本机:OpenHarmony 3.2)和B设备名称(OpenHarmony 3.2)。 +​ c.系统权限设置(以api10目录为例): 将Sdk目录下的openharmony\api版本(如:10)\toolchains\lib\UnsgnedReleasedProfileTemplate.json文件中的"apl":"normal_core"改为"apl":"system_core"。 -![hop-cross-device-migration](figures/hop-cross-device-migration5.png) +1. 点击file->Project Structrue。 + ![hop-cross-device-migration](figures/hop-cross-device-migration2.png) +2. 点击Signing Configs 点击OK。 + ![hop-cross-device-migration](figures/hop-cross-device-migration3.png) +3. 连接开发板运行生成demo。 -2.点击B设备名称,然后出现B设备的应用。 +### 2. 设备组网 -![hop-cross-device-migration](figures/hop-cross-device-migration6.png) +1. 打开A,B两设备的计算器。 +2. 点击右上角箭头选择B设备。 +3. 在B设备选择信任设备,弹出PIN码。 +4. 在A设备输入PIN码。 +5. 已组网成功,验证方法:在A设备输入数字,B设备同步出现则证明组网成功。 -3.最后将应用拖拽到A设备名称处,A设备应用被拉起,B设备应用退出。 +### 3. 发起迁移 -![hop-cross-device-migration](figures/hop-cross-device-migration7.png) +1. 在B设备打开多设备协同权限的应用,A设备打开全局任务中心demo,A设备出现A设备名称(即:本机:OpenHarmony 3.2)和B设备名称(OpenHarmony 3.2)。 + ![hop-cross-device-migration](figures/hop-cross-device-migration4.png) +2. 点击B设备名称,然后出现B设备的应用。 + ![hop-cross-device-migration](figures/hop-cross-device-migration5.png) +3. 最后将应用拖拽到A设备名称处,A设备应用被拉起,B设备应用退出。 + ![hop-cross-device-migration](figures/hop-cross-device-migration6.png)