# Cross-Device Migration (System Applications Only)]
## When to Use
The main task of cross-device migration is to migrate the current task (including the page control status) of an application to the target device so that the task can continue on it. Cross-device migration supports the following functionalities:
- Storage and restoration of custom data
- Storage and restoration of page routing information and page control status data
- Application compatibility detection
## Cross-Device Migration Process
The following figure shows the cross-device migration process.
**Figure 1** Cross-device migration process
![hop-cross-device-migration](figures/hop-cross-device-migration.png)
## Constraints
- Since cross-device migration task management is not available, you can only develop applications that support cross-device migration. Your application cannot initiate migration.
- Cross-device migration can be performed between the same UIAbility component. In other words, the components must have the same **bundleName**, **abilityName**, and **signature**.
## Best Practices
For better user experience, you are advised to use the **wantParam** parameter to transmit data smaller than 100 KB.
## Available APIs
The table below describes the main APIs used for cross-device migration. For details, see [API Reference](../reference/apis/js-apis-app-ability-uiAbility.md).
**Table 1** Cross-device migration APIs
| **API**| Description|
| -------- | -------- |
| onContinue(wantParam : {[key: string]: any}): OnContinueResult | Called by the initiator to store the data required for migration and indicate whether the migration is accepted.
- **AGREE**: The migration is accepted.
- **REJECT**: The migration is rejected.
- **MISMATCH**: The version does not match.|
| onCreate(want: Want, param: AbilityConstant.LaunchParam): void; | Called by the target to restore the data and UI page in the multi-instance migration scenario.|
| onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void; | Called by the target to restore the data and UI page in the singleton migration scenario.|
## How to Develop
1. Configure the data synchronization permission in the **module.json5** file. The sample code is as follows:
```json
{
"module": {
"requestPermissions":[
{
"name" : "ohos.permission.DISTRIBUTED_DATASYNC",
}
]
}
}
```
2. Configure the fields related to cross-device migration in the configuration file.
- Configure the application to support migration.
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 the target device.
```json
{
"module": {
// ...
"abilities": [
{
// ...
"continuable": true,
}
]
}
}
```
- Configure the application launch type. For details, see [UIAbility Component Launch Type](uiability-launch-type.md).
3. Request the data synchronization permission. The sample code for displaying a dialog box to request the permission is as follows:
```ts
requestPermission() {
let context = this.context
let permissions: Array = ['ohos.permission.DISTRIBUTED_DATASYNC']
context.requestPermissionsFromUser(permissions).then((data) => {
console.info("Succeed to request permission from user with data: "+ JSON.stringify(data))
}).catch((error) => {
console.info("Failed to request permission from user with error: "+ JSON.stringify(error))
})
}
```
4. Implement [onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) in the UIAbility of the initiator.
[onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) is called on the initiator. You can save the data in this method to implement application compatibility check and migration decision.
- Saving migrated data: You can save the data to be migrated in key-value pairs in **wantParam**.
- Checking application compatibility: You can obtain the version number of the target application from **wantParam** and check the compatibility between the target application and the current application.
- Making a migration decision: You can determine whether to support the migration based on the return value of **onContinue()**. For details about the return value, see [Available APIs](#available-apis).
The sample code is as follows:
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
onContinue(wantParam : {[key: string]: any}) {
console.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
console.info(`onContinue input = ${wantParam["input"]}`);
return AbilityConstant.OnContinueResult.AGREE
}
```
5. Implement **onCreate()** and **onNewWant()** in the UIAbility of the target application to implement data restoration.
- Implementation example of **onCreate** in the multi-instance scenario
- The target device determines whether the startup is **LaunchReason.CONTINUATION** based on **launchReason** in **onCreate()**.
- You can obtain the saved migration data from the **want** parameter.
- After data restoration is complete, call **restoreWindowStage()** to trigger page restoration.
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import distributedObject from '@ohos.data.distributedDataObject';
export default class EntryAbility extends UIAbility {
storage : LocalStorage;
onCreate(want, launchParam) {
console.info(`EntryAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`)
if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) {
// Obtain the user data from the want parameter.
let workInput = want.parameters.work
console.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.