diff --git a/en/application-dev/ability/stage-ability-continuation.md b/en/application-dev/ability/stage-ability-continuation.md index 0695a3bd491785d414d75be6520d513229b0bcbc..6945f49db8ef05109452fc1b3dcad3dc1e5ddeca 100644 --- a/en/application-dev/ability/stage-ability-continuation.md +++ b/en/application-dev/ability/stage-ability-continuation.md @@ -12,8 +12,9 @@ The following table lists the APIs used for ability continuation. For details ab |API| Description| |:------ | :------| -| onContinue(wantParam : {[key: string]: any}): OnContinueResult | Called by the initiator to store the data required for continuation and request continuation. The value **AGREE** means that the continuation is accepted, and **REJECT** means the continuation is rejected, and **MISMATCH** means a version mismatch.| -| onCreate(want: Want, param : LaunchParam): void | Called by the target to restore the data and UI page.| +| onContinue(wantParam : {[key: string]: any}): OnContinueResult | Called by the initiator to store the data required for continuation. The return value indicates whether the continuation request is accepted. The value **AGREE** means that the continuation request is accepted, **REJECT** means that the continuation request is rejected, and **MISMATCH** means a version mismatch.| +| onCreate(want: Want, param: AbilityConstant.LaunchParam): void; | Called by the target to restore the data and UI page in the multi-instance ability scenario.| +| onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void; | Called by the target to restore the data and UI page in the singleton ability scenario.| @@ -21,20 +22,30 @@ The following table lists the APIs used for ability continuation. For details ab ![continuation_dev](figures/continuation-info.png) -In effect, ability continuation is a cross-device ability startup that carries data. When the continuation is triggered, device A calls back **onContinue()** of the application. You must save the current data in this API. Then, device A initiates a cross-device ability startup on device B and transmits the data to device B. Device B calls back **onCreate()**. You must restore the transmitted data in this API. +In effect, ability continuation is a cross-device ability startup that carries data. When a continuation action is initiated, the system on device A calls back **onContinue()** of the application. You must implement storage of the current data in this API. Then, the system initiates a cross-device ability startup on device B and transmits the data to device B. The system on device B calls back **onCreate()** or **onNewWant()**. You must implement restoration of the transmitted data in this API. ## How to Develop +The code snippets provided below are all from [Sample](https://gitee.com/openharmony/ability_dmsfwk/tree/master/services/dtbschedmgr/test/samples/continuationManualTestSuite). + ### Application Continuation -1. Configuration +1. Modify the configuration file. - Configure the application to support ability continuation. Set the **continuable** field in the **module.json5** file to **true**. The default value is **false**. If this parameter is set to **false**, the application cannot be continued on another device. ```javascript - "continuable": true + { + "module": { + "abilities": [ + { + "continuable": true, + } + ] + } + } ``` @@ -42,30 +53,53 @@ In effect, ability continuation is a cross-device ability startup that carries d - Configure the application startup type. - Set **launchType** in the **module.json5** file to **standard** to add multi-instance support to the application. + If **launchType** is set to **standard** in the **module.json5** file, the application is of the multi-instance launch type. During ability continuation, regardless of whether the application is already open, the target starts the application and restores the UI page. If **launchType** is set to **singleton**, the application is of the singleton launch type. If the application is already open, the target clears the existing page stack and restores the UI page. For more information, see "Launch Type" in [Ability Development](./stage-ability.md). + + Configure a multi-instance application as follows: ```javascript - "launchType": "standard" + { + "module": { + "abilities": [ + { + "launchType": "standard", + } + ] + } + } ``` - - - + Configure a singleton application as follows or retain the default settings of **launchType**: + + ```javascript + { + "module": { + "abilities": [ + { + "launchType": "singleton", + } + ] + } + } + ``` + + + - Apply for the distributed permissions. Declare the **DISTRIBUTED_DATASYNC** permission in the **module.json5** file for the application. - + ```javascript "requestPermissions": [ { "name": "ohos.permission.DISTRIBUTED_DATASYNC" }, ``` - + This permission must be granted by the user in a dialog box when the application is started for the first time. To enable the application to display a dialog box to ask for the permission, add the following code to **onWindowStageCreate** of the **Ability** class: - + ```javascript requestPermissions = async () => { let permissions: Array = [ @@ -102,14 +136,13 @@ In effect, ability continuation is a cross-device ability startup that carries d } } ``` - - + 2. Implement the **onContinue()** API. - The **onContinue()** API is called by the initiator to save the UI component state variables and memory data and prepare for continuation. After the application completes the continuation preparation, the system must return **OnContinueResult.AGREE(0)** to accept the continuation request. If an error code is returned, the request is rejected. If this API is not implemented, the system rejects the continuation request by default. + The **onContinue()** API is called by the initiator to save the UI component state variables and memory data and prepare for continuation. After the application completes the continuation preparation, the system must return either **OnContinueResult.AGREE(0)** to accept the continuation request or an error code to reject the request. If this API is not implemented, the system rejects the continuation request by default. Modules to import: @@ -119,22 +152,25 @@ In effect, ability continuation is a cross-device ability startup that carries d ``` To implement ability continuation, you must implement this API and have the value **AGREE** returned. - + + You can obtain the target device ID (identified by the key **targetDevice**) and the version number (identified by the key **version**) of the application installed on the target device from the **wantParam** parameter of this API. The version number can be used for compatibility check. If the current application version is incompatible with that on the target device, **OnContinueResult.MISMATCH** can be returned to reject the continuation request. + Example - + ```javascript - onContinue(wantParam : {[key: string]: any}) { - Logger.info("onContinue using distributedObject") - // Set the user input data into want params. - wantParam["input"] = AppStorage.Get('ContinueInput'); - Logger.info(`onContinue input = ${wantParam["input"]}`); - return AbilityConstant.OnContinueResult.AGREE - } + onContinue(wantParam : {[key: string]: any}) { + Logger.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`) + let workInput = AppStorage.Get('ContinueWork'); + // Set the user input data into wantParam. + wantParam["work"] = workInput // set user input data into want params + Logger.info(`onContinue input = ${wantParam["input"]}`); + return AbilityConstant.OnContinueResult.AGREE + } ``` - + -3. Implement the continuation logic in the **onCreate()** API. +3. Implement the continuation logic in the **onCreate()** or **onNewWant()** API. The **onCreate()** API is called by the target. When the ability is started on the target device, this API is called to instruct the application to synchronize the memory data and UI component state, and triggers page restoration after the synchronization is complete. If the continuation logic is not implemented, the ability will be started in common startup mode and the page cannot be restored. @@ -142,22 +178,34 @@ In effect, ability continuation is a cross-device ability startup that carries d After data restore is complete, call **restoreWindowStage** to trigger page restoration. - Example + + You can also use **want.parameters.version** in the **want** parameter to obtain the application version number of the initiator. + + Example + ```javascript - onCreate(want, launchParam) { - Logger.info(`MainAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`) - globalThis.abilityWant = want; - if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) { - let input = want.parameters.input // Obtain user data from want params. - AppStorage.SetOrCreate('ContinueInput', input) - Logger.info(`onCreate for continuation sessionId: ${this.sessionId}`) - - this.contentStorage = new ContentStorage(); - this.context.restoreWindowStage(this.contentStorage); - } - } + import Ability from '@ohos.application.Ability'; + import distributedObject from '@ohos.data.distributedDataObject'; + + export default class MainAbility extends Ability { + storage : LocalStorag; + + onCreate(want, launchParam) { + Logger.info(`MainAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`) + if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) { + // Obtain the user data from the want parameter. + let workInput = want.parameters.work + Logger.info(`work input ${workInput}`) + AppStorage.SetOrCreate('ContinueWork', workInput) + + this.storage = new LocalStorage(); + this.context.restoreWindowStage(this.storage); + } + } + } ``` +For a singleton ability, use **onNewWant()** to achieve the same implementation. @@ -169,28 +217,38 @@ Distributed objects allow cross-device data synchronization like local variables In the ability continuation scenario, the distributed data object is used to synchronize the memory data from the local device to the target device. -- In **onContinue()**, the initiator saves the data to be continued to the distributed object, sets the session ID, and sends the session ID to the target device through **wantParam**. +- In **onContinue()**, the initiator saves the data to be migrated to the distributed object, calls the **save()** API to save the data and synchronize the data to the target device, sets the session ID, and sends the session ID to the target device through **wantParam**. ```javascript import Ability from '@ohos.application.Ability'; import distributedObject from '@ohos.data.distributedDataObject'; - var g_object = distributedObject.createDistributedObject({name:undefined}); + var g_object = distributedObject.createDistributedObject({data:undefined}); export default class MainAbility extends Ability { - contentStorage : ContentStorage sessionId : string; onContinue(wantParam : {[key: string]: any}) { - Logger.info("onContinue using distributedObject") - this.sessionId = distributedObject.genSessionId(); - // Set the session ID for the distributed data object. - g_object.setSessionId(this.sessionId); - g_object.name = "Amy"; - // Set the session ID into the want parameter. - wantParam["session"] = this.sessionId; - return AbilityConstant.OnContinueResult.AGREE - } + Logger.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`) + + if (g_object.__sessionId === undefined) { + this.sessionId = distributedObject.genSessionId() + Logger.info(`onContinue generate new sessionId`) + } + else { + this.sessionId = g_object.__sessionId; + } + + wantParam["session"] = this.sessionId + g_object.data = AppStorage.Get('ContinueStudy'); + Logger.info(`onContinue sessionId = ${this.sessionId}, name = ${g_object.data}`) + g_object.setSessionId(this.sessionId); + g_object.save(wantParam.targetDevice, (result, data)=>{ + Logger.info("save callback"); + Logger.info("save sessionId " + data.sessionId); + Logger.info("save version " + data.version); + Logger.info("save deviceId " + data.deviceId); + }); ``` @@ -201,15 +259,11 @@ In the ability continuation scenario, the distributed data object is used to syn import Ability from '@ohos.application.Ability'; import distributedObject from '@ohos.data.distributedDataObject'; - var g_object = distributedObject.createDistributedObject({name:undefined}); + var g_object = distributedObject.createDistributedObject({data:undefined}); export default class MainAbility extends Ability { - contentStorage : ContentStorage - sessionId : string; + storage : LocalStorag; - statusCallback(sessionId, networkid, status) { - Logger.info(`continuation object status change, sessionId: ${sessionId}, status: ${status}, g_object.name: ${g_object.name}`) - } onCreate(want, launchParam) { Logger.info(`MainAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`) @@ -218,13 +272,40 @@ In the ability continuation scenario, the distributed data object is used to syn this.sessionId = want.parameters.session Logger.info(`onCreate for continuation sessionId: ${this.sessionId}`) - g_object.on("status", this.statusCallback); - // Set the session ID for data synchronization. - g_object.setSessionId(this.sessionId); + // Before fetching data from the remote device, reset g_object.data to undefined. + g_object.data = undefined; + // Set the session ID, so the target will fetch data from the remote device. + g_object.setSessionId(this.sessionId); - this.contentStorage = new ContentStorage(); - this.context.restoreWindowStage(this.contentStorage); + AppStorage.SetOrCreate('ContinueStudy', g_object.data) + this.storage = new LocalStorage(); + this.context.restoreWindowStage(this.storage); } + } } ``` + + + +### More Information + +1. Timeout + + - If the application to be continued is not installed on the target device, the system checks whether the application can be installed on it and waits for a response for 4 seconds. If no response is received within 4 seconds, the caller receives a timeout error code, which means that the application cannot be installed on the target device. If the application can be installed, the system prompts the consumer to install the application on the target device. The consumer can initiate the continuation again after the installation. + - If the application to be continued has been installed on the target device, the system waits for a response to the continuation request for 20 seconds. If no response is received within 20 seconds, the caller receives a timeout error code, which means that the continuation fails. + +2. By default, the system supports page stack information migration, which means that the page stack of the initiator will be automatically migrated to the target device. No adaptation is required. + + + +### Restrictions + +1. The continuation must be performed between the same ability, which means the same bundle name, module name, and ability name. For details, see [Application Package Structure Configuration File](../quick-start/stage-structure.md). +2. Currently, the application can only implement the continuation capability. The continuation action must be initiated by the system. + + + +### Best Practice + + For better user experience, you are advised to use the **wantParam** parameter to transmit data smaller than 100 KB and use distributed objects to transmit data larger than 100 KB.