1# Intra-Device Interaction Between UIAbility Components 2 3 4UIAbility is the minimum unit that can be scheduled by the system. Redirection between functional modules in a device involves starting of specific UIAbility components, which belong to the same or a different application (for example, starting UIAbility of a third-party payment application). 5 6 7This topic describes the UIAbility interaction modes in the following scenarios. For details about cross-device application component interaction, see [Inter-Device Application Component Interaction (Continuation)](inter-device-interaction-hop-overview.md). 8 9 10- [Starting UIAbility in the Same Application](#starting-uiability-in-the-same-application) 11 12- [Starting UIAbility in the Same Application and Obtaining the Return Result](#starting-uiability-in-the-same-application-and-obtaining-the-return-result) 13 14- [Starting UIAbility of Another Application](#starting-uiability-of-another-application) 15 16- [Starting UIAbility of Another Application and Obtaining the Return Result](#starting-uiability-of-another-application-and-obtaining-the-return-result) 17 18- [Starting UIAbility with Window Mode Specified (for System Applications Only)](#starting-uiability-with-window-mode-specified-for-system-applications-only) 19 20- [Starting a Specified Page of UIAbility](#starting-a-specified-page-of-uiability) 21 22- [Using Call to Implement UIAbility Interaction (for System Applications Only)](#using-call-to-implement-uiability-interaction-for-system-applications-only) 23 24 25## Starting UIAbility in the Same Application 26 27This scenario is possible when an application contains multiple UIAbility components. For example, in a payment application, you may need to start the payment UIAbility from the entry UIAbility. 28 29Assume that your application has two UIAbility components: EntryAbility and FuncAbility, either in the same module or different modules. To start FuncAbility from EntryAbility, proceed as follows: 30 311. In EntryAbility, call [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) and pass the [want](../reference/apis/js-apis-app-ability-want.md) parameter to start the UIAbility instance. In the **want** parameter, **bundleName** indicates the bundle name of the application to start; **abilityName** indicates the name of the UIAbility to start; **moduleName** is required only when the target UIAbility belongs to a different module from EntryAbility; **parameters** is used to carry custom information. For details about how to obtain the context in the example, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). 32 33 ```ts 34 import common from '@ohos.app.ability.common'; 35 import Want from '@ohos.app.ability.Want'; 36 import { BusinessError } from '@ohos.base'; 37 38 let context: common.UIAbilityContext = ...; // UIAbilityContext 39 let want: Want = { 40 deviceId: '', // An empty deviceId indicates the local device. 41 bundleName: 'com.example.myapplication', 42 moduleName: 'func', // moduleName is optional. 43 abilityName: 'FuncAbility', 44 parameters: { // Custom information. 45 info: 'From the Index page of EntryAbility', 46 }, 47 } 48 // context is the UIAbilityContext of the initiator UIAbility. 49 context.startAbility(want).then(() => { 50 console.info('Succeeded in starting ability.'); 51 }).catch((err: BusinessError) => { 52 console.error(`Failed to start ability. Code is ${err.code}, message is ${err.message}`); 53 }) 54 ``` 55 562. In FuncAbility, use [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) or [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonnewwant) to receive the parameters passed in by EntryAbility. 57 58 ```ts 59 import UIAbility from '@ohos.app.ability.UIAbility'; 60 import AbilityConstant from '@ohos.app.ability.AbilityConstant'; 61 import Want from '@ohos.app.ability.Want'; 62 63 export default class FuncAbility extends UIAbility { 64 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { 65 // Receive the parameters passed by the initiator UIAbility. 66 let funcAbilityWant = want; 67 let info = funcAbilityWant?.parameters?.info; 68 // ... 69 } 70 } 71 ``` 72 73 > **NOTE** 74 > 75 > In FuncAbility started, you can obtain the PID and bundle name of the UIAbility through **parameters** in the passed **want** parameter. 76 773. To stop the **UIAbility** instance after the FuncAbility service is not needed, call [terminateSelf()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateself) in FuncAbility. 78 79 ```ts 80 import common from '@ohos.app.ability.common'; 81 82 let context: common.UIAbilityContext = ...; // UIAbilityContext 83 84 // context is the UIAbilityContext of the UIAbility instance to stop. 85 context.terminateSelf((err) => { 86 if (err.code) { 87 console.error(`Failed to terminate Self. Code is ${err.code}, message is ${err.message}`); 88 return; 89 } 90 }); 91 ``` 92 93 > **NOTE** 94 > 95 > When [terminateSelf()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateself) is called to stop the **UIAbility** instance, the snapshot of the instance is retained by default. That is, the mission corresponding to the instance is still displayed in Recents. If you do not want to retain the snapshot, set **removeMissionAfterTerminate** under the [abilities](../quick-start/module-configuration-file.md#abilities) tag to **true** in the [module.json5 file](../quick-start/module-configuration-file.md) of the corresponding UIAbility. 96 974. To stop all UIAbility instances of the application, call [killProcessBySelf()](../reference/apis/js-apis-inner-application-applicationContext.md#applicationcontextkillallprocesses9) of [ApplicationContext](../reference/apis/js-apis-inner-application-applicationContext.md). 98 99 100## Starting UIAbility in the Same Application and Obtaining the Return Result 101 102When starting FuncAbility from EntryAbility, you may want the result to be returned after the FuncAbility service is finished. For example, after the sign-in operation is finished in the sign-in UIAbility of your application, you want the sign-in result to be returned to the entry UIAbility. 103 1041. In EntryAbility, call [startAbilityForResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult) to start FuncAbility. Use **data** in the asynchronous callback to receive information returned after FuncAbility stops itself. For details about how to obtain the context in the example, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). 105 106 ```ts 107 import common from '@ohos.app.ability.common'; 108 import Want from '@ohos.app.ability.Want'; 109 import { BusinessError } from '@ohos.base'; 110 111 let context: common.UIAbilityContext = ...; // UIAbilityContext 112 let want: Want = { 113 deviceId: '', // An empty deviceId indicates the local device. 114 bundleName: 'com.example.myapplication', 115 moduleName: 'func', // moduleName is optional. 116 abilityName: 'FuncAbility', 117 parameters: { // Custom information. 118 info: 'From the Index page of EntryAbility', 119 }, 120 } 121 // context is the UIAbilityContext of the initiator UIAbility. 122 context.startAbilityForResult(want).then((data) => { 123 // ... 124 }).catch((err: BusinessError) => { 125 console.error(`Failed to start ability for result. Code is ${err.code}, message is ${err.message}`); 126 }) 127 ``` 128 1292. Call [terminateSelfWithResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult) to stop FuncAbility. Use the input parameter **abilityResult** to carry the information that FuncAbility needs to return to EntryAbility. 130 131 ```ts 132 import common from '@ohos.app.ability.common'; 133 import Want from '@ohos.app.ability.Want'; 134 135 let context: common.UIAbilityContext = ...; // UIAbilityContext 136 const RESULT_CODE: number = 1001; 137 let abilityResult: common.AbilityResult = { 138 resultCode: RESULT_CODE, 139 want: { 140 bundleName: 'com.example.myapplication', 141 moduleName: 'func', // moduleName is optional. 142 abilityName: 'FuncAbility', 143 parameters: { 144 info: 'From the Index page of FuncAbility', 145 }, 146 }, 147 } 148 // context is the AbilityContext of the target UIAbility. 149 context.terminateSelfWithResult(abilityResult, (err) => { 150 if (err.code) { 151 console.error(`Failed to terminate self with result. Code is ${err.code}, message is ${err.message}`); 152 return; 153 } 154 }); 155 ``` 156 1573. After FuncAbility stops itself, EntryAbility uses [startAbilityForResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult) to receive the information returned by FuncAbility. The value of **RESULT_CODE** must be the same as that specified in the preceding step. 158 159 ```ts 160 import common from '@ohos.app.ability.common'; 161 import Want from '@ohos.app.ability.Want'; 162 import { BusinessError } from '@ohos.base'; 163 164 let context: common.UIAbilityContext = ...; // UIAbilityContext 165 const RESULT_CODE: number = 1001; 166 167 let want: Want = { 168 deviceId: '', // An empty deviceId indicates the local device. 169 bundleName: 'com.example.myapplication', 170 moduleName: 'func', // moduleName is optional. 171 abilityName: 'FuncAbility', 172 } 173 174 // context is the UIAbilityContext of the initiator UIAbility. 175 context.startAbilityForResult(want).then((data) => { 176 if (data?.resultCode === RESULT_CODE) { 177 // Parse the information returned by the target UIAbility. 178 let info = data.want?.parameters?.info; 179 // ... 180 } 181 }).catch((err: BusinessError) => { 182 console.error(`Failed to start ability for result. Code is ${err.code}, message is ${err.message}`); 183 }) 184 ``` 185 186 187## Starting UIAbility of Another Application 188 189Generally, the user only needs to perform a general operation (for example, selecting a document application to view the document content) to start the UIAbility of another application. In this case, the [implicit Want launch mode](want-overview.md#types-of-want) is recommended. In this mode, the system identifies a matched UIAbility and starts it based on the **want** parameter of the initiator UIAbility. 190 191There are two ways to start **UIAbility**: [explicit and implicit](want-overview.md). 192 193- Explicit Want launch is used to start a determined UIAbility component of an application. You need to set **bundleName** and **abilityName** of the target application in the **want** parameter. 194 195- Implicit Want launch is used to start a UIAbility based on the matching conditions. That is, the UIAbility to start is not determined (the **abilityName** parameter is not specified). When [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, the **want** parameter specifies a series of parameters such as **entities** and **actions**. **entities** provides category information of the target UIAbility, such as the browser or video player. **actions** specifies the common operations to perform, such as viewing and sharing. Then the system analyzes the **want** parameter to find the right UIAbility to start. If you are not sure about whether the target application is installed and what **bundleName** and **abilityName** of the target application are, consider using implicit Want launch. 196 197The following example describes how to start the UIAbility of another application through implicit Want. 198 1991. Install multiple document applications on your device. In the [module.json5 file](../quick-start/module-configuration-file.md) of each UIAbility component, configure **entities** and **actions** under **skills**. 200 201 ```json 202 { 203 "module": { 204 "abilities": [ 205 { 206 ... 207 "skills": [ 208 { 209 "entities": [ 210 ... 211 "entity.system.default" 212 ], 213 "actions": [ 214 ... 215 "ohos.want.action.viewData" 216 ] 217 } 218 ] 219 } 220 ] 221 } 222 } 223 ``` 224 2252. Include **entities** and **actions** of the initiator UIAbility's **want** parameter into **entities** and **actions** under **skills** of the target UIAbility. After the system identifies the UIAbility instances that match the **entities** and **actions** information, a dialog box is displayed, showing the list of matching UIAbility instances for users to select. For details about how to obtain the context in the example, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). 226 227 ```ts 228 import common from '@ohos.app.ability.common'; 229 import Want from '@ohos.app.ability.Want'; 230 import { BusinessError } from '@ohos.base'; 231 232 let context: common.UIAbilityContext = ...; // UIAbilityContext 233 let want: Want = { 234 deviceId: '', // An empty deviceId indicates the local device. 235 // Uncomment the line below if you want to implicitly query data only in the specific bundle. 236 // bundleName: 'com.example.myapplication', 237 action: 'ohos.want.action.viewData', 238 // entities can be omitted. 239 entities: ['entity.system.default'], 240 } 241 242 // context is the UIAbilityContext of the initiator UIAbility. 243 context.startAbility(want).then(() => { 244 console.info('Succeeded in starting ability.'); 245 }).catch((err: BusinessError) => { 246 console.error(`Failed to start ability. Code is ${err.code}, message is ${err.message}`); 247 }) 248 ``` 249 250 The following figure shows the effect. When you click **Open PDF**, a dialog box is displayed for you to select the application to use. 251 252  253 2543. To stop the **UIAbility** instance when the document application is not in use, call [terminateSelf()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateself). 255 256 ```ts 257 import common from '@ohos.app.ability.common'; 258 259 let context: common.UIAbilityContext = ...; // UIAbilityContext 260 261 // context is the UIAbilityContext of the UIAbility instance to stop. 262 context.terminateSelf((err) => { 263 if (err.code) { 264 console.error(`Failed to terminate self. Code is ${err.code}, message is ${err.message}`); 265 return; 266 } 267 }); 268 ``` 269 270 271## Starting UIAbility of Another Application and Obtaining the Return Result 272 273If you want to obtain the return result when using implicit Want to start the UIAbility of another application, use [startAbilityForResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult). An example scenario is that your application needs to start a third-party payment application and obtain the payment result. 274 2751. In the [module.json5 file](../quick-start/module-configuration-file.md) of the UIAbility corresponding to the payment application, set **entities** and **actions** under **skills**. 276 277 ```json 278 { 279 "module": { 280 "abilities": [ 281 { 282 ... 283 "skills": [ 284 { 285 "entities": [ 286 ... 287 "entity.system.default" 288 ], 289 "actions": [ 290 ... 291 "ohos.want.action.editData" 292 ] 293 } 294 ] 295 } 296 ] 297 } 298 } 299 ``` 300 3012. Call [startAbilityForResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult) to start the UIAbility of the payment application. Include **entities** and **actions** of the initiator UIAbility's **want** parameter into **entities** and **actions** under **skills** of the target UIAbility. Use **data** in the asynchronous callback to receive the information returned to the initiator UIAbility after the payment UIAbility stops itself. After the system identifies the UIAbility instances that match the **entities** and **actions** information, a dialog box is displayed, showing the list of matching UIAbility instances for users to select. 302 303 ```ts 304 import common from '@ohos.app.ability.common'; 305 import Want from '@ohos.app.ability.Want'; 306 import { BusinessError } from '@ohos.base'; 307 308 let context: common.UIAbilityContext = ...; // UIAbilityContext 309 let want:Want = { 310 deviceId: '', // An empty deviceId indicates the local device. 311 // Uncomment the line below if you want to implicitly query data only in the specific bundle. 312 // bundleName: 'com.example.myapplication', 313 action: 'ohos.want.action.editData', 314 // entities can be omitted. 315 entities: ['entity.system.default'] 316 } 317 318 // context is the UIAbilityContext of the initiator UIAbility. 319 context.startAbilityForResult(want).then((data) => { 320 // ... 321 }).catch((err: BusinessError) => { 322 console.error(`Failed to start ability for result. Code is ${err.code}, message is ${err.message}`); 323 }) 324 ``` 325 3263. After the payment is finished, call [terminateSelfWithResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult) to stop the payment UIAbility and return the **abilityResult** parameter. 327 328 ```ts 329 import common from '@ohos.app.ability.common'; 330 import Want from '@ohos.app.ability.Want'; 331 332 let context: common.UIAbilityContext = ...; // UIAbilityContext 333 const RESULT_CODE: number = 1001; 334 let abilityResult: common.AbilityResult = { 335 resultCode: RESULT_CODE, 336 want: { 337 bundleName: 'com.example.funcapplication', 338 moduleName: 'entry', // moduleName is optional. 339 abilityName: 'EntryAbility', 340 parameters: { 341 payResult: 'OKay', 342 }, 343 }, 344 } 345 // context is the AbilityContext of the target UIAbility. 346 context.terminateSelfWithResult(abilityResult, (err) => { 347 if (err.code) { 348 console.error(`Failed to terminate self with result. Code is ${err.code}, message is ${err.message}`); 349 return; 350 } 351 }); 352 ``` 353 3544. Receive the information returned by the payment application in the callback of the [startAbilityForResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult) method. The value of **RESULT_CODE** must be the same as that returned by [terminateSelfWithResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult). 355 356 ```ts 357 import common from '@ohos.app.ability.common'; 358 import Want from '@ohos.app.ability.Want'; 359 import { BusinessError } from '@ohos.base'; 360 361 let context: common.UIAbilityContext = ...; // UIAbilityContext 362 const RESULT_CODE: number = 1001; 363 364 let want: Want = { 365 // Want parameter information. 366 }; 367 368 // context is the UIAbilityContext of the initiator UIAbility. 369 context.startAbilityForResult(want).then((data) => { 370 if (data?.resultCode === RESULT_CODE) { 371 // Parse the information returned by the target UIAbility. 372 let payResult = data.want?.parameters?.payResult; 373 // ... 374 } 375 }).catch((err: BusinessError) => { 376 console.error(`Failed to start ability for result. Code is ${err.code}, message is ${err.message}`); 377 }) 378 ``` 379 380## Starting UIAbility with Window Mode Specified (for System Applications Only) 381 382By specifying the window mode when starting the UIAbility of an application, you can have the application displayed in the specified window mode, which can be full-screen, floating window, or split-screen. 383 384In full-screen mode, an application occupies the entire screen after being started. Users cannot view other windows or applications. This mode is suitable for an application that requires users to focus on a specific task or UI. 385 386In floating window mode, an application is displayed on the screen as a floating window after being started. Users can easily switch to other windows or applications. This mode is suitable for an application that allows users to process multiple tasks at the same time. 387 388In split-screen mode, two applications occupy the entire screen, side by side, horizontally or vertically. This mode helps users improve multi-task processing efficiency. 389 390The window mode is specified by the **windowMode** field in the [StartOptions](../reference/apis/js-apis-app-ability-startOptions.md) parameter of [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability). 391 392> **NOTE** 393> 394> - If the **windowMode** field is not specified, the UIAbility is started in the default window mode. 395> - To ensure that the application can be displayed in the required window mode, check the **supportWindowMode** field under [abilities](../quick-start/module-configuration-file.md#abilities) in the [module.json5 file](../quick-start/module-configuration-file.md) of the UIAbility and make sure the specified window mode is supported. 396 397The following describes how to start the FuncAbility from the EntryAbility page and display it in floating window mode. 398 3991. Add the [StartOptions](../reference/apis/js-apis-app-ability-startOptions.md) parameter in [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability). 4002. Set the **windowMode** field in the [StartOptions](../reference/apis/js-apis-app-ability-startOptions.md) parameter to **WINDOW_MODE_FLOATING**. 401 402For details about how to obtain the context in the example, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). 403 404```ts 405import AbilityConstant from '@ohos.app.ability.AbilityConstant'; 406import common from '@ohos.app.ability.common'; 407import Want from '@ohos.app.ability.Want'; 408import StartOptions from '@ohos.app.ability.StartOptions'; 409import { BusinessError } from '@ohos.base'; 410 411let context: common.UIAbilityContext = ...; // UIAbilityContext 412let want: Want = { 413 deviceId: '', // An empty deviceId indicates the local device. 414 bundleName: 'com.example.myapplication', 415 moduleName: 'func', // moduleName is optional. 416 abilityName: 'FuncAbility', 417 parameters: { // Custom information. 418 info: 'From the Index page of EntryAbility', 419 }, 420} 421let options: StartOptions = { 422 windowMode: AbilityConstant.WindowMode.WINDOW_MODE_FLOATING 423}; 424// context is the UIAbilityContext of the initiator UIAbility. 425context.startAbility(want, options).then(() => { 426 console.info('Succeeded in starting ability.'); 427}).catch((err: BusinessError) => { 428 console.error(`Failed to start ability. Code is ${err.code}, message is ${err.message}`); 429}) 430``` 431 432The display effect is shown below. 433 434 435 436## Starting a Specified Page of UIAbility 437 438### Overview 439 440A UIAbility component can have multiple pages that each display in specific scenarios. 441 442A UIAbility component can be started in two modes: 443 444- Cold start: The UIAbility instance is totally closed before being started. This requires that the code and resources of the UIAbility instance be completely loaded and initialized. 445- Hot start: The UIAbility instance has been started, running in the foreground, and then switched to the background before being started again. In this case, the status of the UIAbility instance can be quickly restored. 446 447This section describes how to start a specified page in both modes: [cold start](#cold-starting-uiability) and [hot start](#hot-starting-uiability). Before starting a specified page, you will learn how to specify a startup page on the initiator UIAbility. 448 449 450### Specifying a Startup Page 451 452When the initiator UIAbility starts another UIAbility, it usually needs to redirect to a specified page of the target UIAbility. For example, with FuncAbility, which contains two pages, starting FuncAbility means to redirect to either of the pages: Index (corresponding to the home page) and Second (corresponding to feature A page). You can configure the specified page URL in the **want** parameter by adding a custom parameter to **parameters** in **want**. For details about how to obtain the context in the example, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). 453 454 455```ts 456import common from '@ohos.app.ability.common'; 457import Want from '@ohos.app.ability.Want'; 458import { BusinessError } from '@ohos.base'; 459 460let context: common.UIAbilityContext = ...; // UIAbilityContext 461let want: Want = { 462 deviceId: '', // An empty deviceId indicates the local device. 463 bundleName: 'com.example.funcapplication', 464 moduleName: 'entry', // moduleName is optional. 465 abilityName: 'EntryAbility', 466 parameters: { // Custom parameter used to pass the page information. 467 router: 'funcA', 468 }, 469} 470// context is the UIAbilityContext of the initiator UIAbility. 471context.startAbility(want).then(() => { 472 console.info('Succeeded in starting ability.'); 473}).catch((err: BusinessError) => { 474 console.error(`Failed to start ability. Code is ${err.code}, message is ${err.message}`); 475}) 476``` 477 478 479### Cold Starting UIAbility 480 481In cold start mode, obtain the parameters from the initiator UIAbility through the **onCreate()** callback of the target UIAbility. Then, in the **onWindowStageCreate()** callback of the target UIAbility, parse the **want** parameter passed by the EntryAbility to obtain the URL of the page to be loaded, and pass the URL to the **windowStage.loadContent()** method. 482 483 484```ts 485import AbilityConstant from '@ohos.app.ability.AbilityConstant'; 486import UIAbility from '@ohos.app.ability.UIAbility'; 487import Want from '@ohos.app.ability.Want'; 488import window from '@ohos.window'; 489 490export default class FuncAbility extends UIAbility { 491 funcAbilityWant: Want | undefined = undefined; 492 493 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { 494 // Receive the parameters passed by the initiator UIAbility. 495 this.funcAbilityWant = want; 496 } 497 498 onWindowStageCreate(windowStage: window.WindowStage) { 499 // Main window is created. Set a main page for this UIAbility. 500 let url = 'pages/Index'; 501 if (this.funcAbilityWant?.parameters?.router && this.funcAbilityWant.parameters.router === 'funcA') { 502 url = 'pages/Second'; 503 } 504 windowStage.loadContent(url, (err, data) => { 505 // ... 506 }); 507 } 508} 509``` 510 511### Hot Starting UIAbility 512 513If the target UIAbility has been started, the initialization logic is not executed again. Instead, the **onNewWant()** lifecycle callback is directly triggered. To implement redirection, parse the required parameters in **onNewWant()**. 514 515An example scenario is as follows: 516 5171. A user opens the SMS application. The UIAbility instance of the SMS application is started, and the home page of the application is displayed. 5182. The user returns to the home screen, and the SMS application switches to the background. 5193. The user opens the Contacts application and finds a contact. 5204. The user touches the SMS button next to the contact. The UIAbility instance of the SMS application is restarted. 5215. Since the UIAbility instance of the SMS application has been started, the **onNewWant()** callback of the UIAbility is triggered, and the initialization logic such as **onCreate()** and **onWindowStageCreate()** is skipped. 522 523Figure 1 Hot starting the target UIAbility 524 525 526The development procedure is as follows: 527 5281. When the UIAbility instance of the SMS application is cold started, call [getUIContext()](../reference/apis/js-apis-window.md#getuicontext10) in the **onWindowStageCreate()** lifecycle callback to obtain the [UIContext](../reference/apis/js-apis-arkui-UIContext.md). 529 530 ```ts 531 import AbilityConstant from '@ohos.app.ability.AbilityConstant'; 532 import UIAbility from '@ohos.app.ability.UIAbility'; 533 import Want from '@ohos.app.ability.Want'; 534 import window from '@ohos.window'; 535 536 import { Router, UIContext } from '@ohos.arkui.UIContext'; 537 538 export default class EntryAbility extends UIAbility { 539 funcAbilityWant: Want | undefined = undefined; 540 uiContext: UIContext | undefined = undefined; 541 542 // ... 543 544 onWindowStageCreate(windowStage: window.WindowStage) { 545 // Main window is created. Set a main page for this UIAbility. 546 let url = 'pages/Index'; 547 if (this.funcAbilityWant?.parameters?.router && this.funcAbilityWant.parameters.router === 'funcA') { 548 url = 'pages/Second'; 549 } 550 551 windowStage.loadContent(url, (err, data) => { 552 if (err.code) { 553 return; 554 } 555 556 let windowClass: window.Window; 557 windowStage.getMainWindow((err, data) => { 558 if (err.code) { 559 console.error(`Failed to obtain the main window. Code is ${err.code}, message is ${err.message}`); 560 return; 561 } 562 windowClass = data; 563 this.uiContext = windowClass.getUIContext(); 564 }) 565 }); 566 } 567 } 568 ``` 569 5702. Parse the **want** parameter passed in the **onNewWant()** callback of the UIAbility of the SMS application, call [getRouter()](../reference/apis/js-apis-arkui-UIContext.md#getrouter) in the **UIContext** class to obtain a [Router](../reference/apis/js-apis-arkui-UIContext.md#router) instance, and specify the target page. When the UIAbility instance of the SMS application is started again, the specified page of the UIAbility instance of the SMS application is displayed. 571 572 ```ts 573 import AbilityConstant from '@ohos.app.ability.AbilityConstant'; 574 import UIAbility from '@ohos.app.ability.UIAbility'; 575 import Want from '@ohos.app.ability.Want'; 576 import { Router, UIContext } from '@ohos.arkui.UIContext'; 577 import { BusinessError } from '@ohos.base'; 578 579 export default class EntryAbility extends UIAbility { 580 funcAbilityWant: Want | undefined = undefined; 581 uiContext: UIContext | undefined = undefined; 582 583 onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam) { 584 if (want?.parameters?.router && want.parameters.router === 'funcA') { 585 let funcAUrl = 'pages/Second'; 586 if (this.uiContext) { 587 let router: Router = this.uiContext.getRouter(); 588 router.pushUrl({ 589 url: funcAUrl 590 }).catch((err: BusinessError) => { 591 console.error(`Failed to push url. Code is ${err.code}, message is ${err.message}`); 592 }) 593 } 594 } 595 } 596 597 // ... 598 } 599 ``` 600 601> **NOTE** 602> 603> When the [launch type of the target UIAbility](uiability-launch-type.md) is set to **multiton**, a new instance is created each time the target UIAbility is started. In this case, the [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback will not be invoked. 604 605 606## Using Call to Implement UIAbility Interaction (for System Applications Only) 607 608Call is an extension of the UIAbility capability. It enables the UIAbility to be invoked by and communicate with external systems. The UIAbility invoked can be either started in the foreground or created and run in the background. You can use the call to implement data sharing between two UIAbility instances (CallerAbility and CalleeAbility) through IPC. 609 610The core API used for the call is **startAbilityByCall()**, which differs from **startAbility()** in the following ways: 611 612- **startAbilityByCall()** supports UIAbility launch in the foreground and background, whereas **startAbility()** supports UIAbility launch in the foreground only. 613 614- The CallerAbility can use the caller object returned by **startAbilityByCall()** to communicate with the CalleeAbility, but **startAbility()** does not provide the communication capability. 615 616Call is usually used in the following scenarios: 617 618- Communicating with the CalleeAbility 619 620- Starting the CalleeAbility in the background 621 622 623**Table 1** Terms used in the call 624 625| **Term**| Description| 626| -------- | -------- | 627| CallerAbility| UIAbility that triggers the call.| 628| CalleeAbility | UIAbility invoked by the call.| 629| Caller | Object returned by **startAbilityByCall** and used by the CallerAbility to communicate with the CalleeAbility.| 630| Callee | Object held by the CalleeAbility to communicate with the CallerAbility.| 631 632The following figure shows the call process. 633 634**Figure 1** Call process 635 636 637 638- The CallerAbility uses **startAbilityByCall** to obtain a caller object and uses **call()** of the caller object to send data to the CalleeAbility. 639 640- The CalleeAbility, which holds a callee object, uses **on()** of the callee object to register a callback. This callback is invoked when the CalleeAbility receives data from the CallerAbility. 641 642> **NOTE** 643> - Currently, only system applications can use the call. 644> 645> - The launch type of the CalleeAbility must be **singleton**. 646> 647> - Both local (intra-device) and cross-device calls are supported. The following describes how to initiate a local call. For details about how to initiate a cross-device call, see [Using Cross-Device Call](hop-multi-device-collaboration.md#using-cross-device-call). 648 649 650### Available APIs 651 652The following table describes the main APIs used for the call. For details, see [AbilityContext](../reference/apis/js-apis-app-ability-uiAbility.md#caller). 653 654**Table 2** Call APIs 655 656| API| Description| 657| -------- | -------- | 658| startAbilityByCall(want: Want): Promise<Caller> | Starts a UIAbility in the foreground (through the **want** configuration) or background (default) and obtains the caller object for communication with the UIAbility. For details, see [AbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartabilitybycall) or [ServiceExtensionContext](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartabilitybycall).| 659| on(method: string, callback: CalleeCallBack): void | Callback invoked when the CalleeAbility registers a method.| 660| off(method: string): void | Callback invoked when the CalleeAbility deregisters a method.| 661| call(method: string, data: rpc.Parcelable): Promise<void> | Sends agreed parcelable data to the CalleeAbility.| 662| callWithResult(method: string, data: rpc.Parcelable): Promise<rpc.MessageSequence> | Sends agreed parcelable data to the CalleeAbility and obtains the agreed parcelable data returned by the CalleeAbility.| 663| release(): void | Releases the caller object.| 664| on(type: "release", callback: OnReleaseCallback): void | Callback invoked when the caller object is released.| 665 666The implementation of using the call for UIAbility interaction involves two parts: 667 668- [Creating a CalleeAbility](#creating-a-calleeability) 669 670- [Accessing the CalleeAbility](#accessing-the-calleeability) 671 672 673### Creating a CalleeAbility 674 675For the CalleeAbility, implement the callback to receive data and the methods to marshal and unmarshal data. When data needs to be received, use **on()** to register a listener. When data does not need to be received, use **off()** to deregister the listener. 676 6771. Configure the launch type of the CalleeAbility. 678 679 For example, set the launch type of the CalleeAbility to **singleton**. For details, see [UIAbility Component Launch Type](uiability-launch-type.md). 680 6812. Import the **UIAbility** module. 682 683 ```ts 684 import UIAbility from '@ohos.app.ability.UIAbility'; 685 ``` 686 6873. Define the agreed parcelable data. 688 689 The data formats sent and received by the CallerAbility and CalleeAbility must be consistent. In the following example, the data formats are number and string. 690 691 692 ```ts 693 import rpc from '@ohos.rpc'; 694 695 export default class MyParcelable { 696 num: number = 0; 697 str: string = ''; 698 699 constructor(num: number, string: string) { 700 this.num = num; 701 this.str = string; 702 } 703 704 marshalling(messageSequence: rpc.MessageSequence) { 705 messageSequence.writeInt(this.num); 706 messageSequence.writeString(this.str); 707 return true; 708 } 709 710 unmarshalling(messageSequence: rpc.MessageSequence) { 711 this.num = messageSequence.readInt(); 712 this.str = messageSequence.readString(); 713 return true; 714 } 715 } 716 ``` 717 7184. Implement **Callee.on** and **Callee.off**. 719 720 The time to register a listener for the CalleeAbility depends on your application. The data sent and received before the listener is registered and that after the listener is deregistered are not processed. In the following example, the **MSG_SEND_METHOD** listener is registered in **onCreate** of the UIAbility and deregistered in **onDestroy**. After receiving parcelable data, the application processes the data and returns the data result. You need to implement processing based on service requirements. The sample code is as follows: 721 722 723 ```ts 724 import AbilityConstant from '@ohos.app.ability.AbilityConstant'; 725 import UIAbility from '@ohos.app.ability.UIAbility'; 726 import Want from '@ohos.app.ability.Want'; 727 import rpc from '@ohos.rpc'; 728 import { BusinessError } from '@ohos.base'; 729 import MyParcelable from './MyParcelable'; 730 731 const TAG: string = '[CalleeAbility]'; 732 const MSG_SEND_METHOD: string = 'CallSendMsg'; 733 734 function sendMsgCallback(data: rpc.MessageSequence) { 735 console.info('CalleeSortFunc called'); 736 737 // Obtain the parcelable data sent by the CallerAbility. 738 let receivedData: MyParcelable = new MyParcelable(0, ''); 739 data.readParcelable(receivedData); 740 console.info(`receiveData[${receivedData.num}, ${receivedData.str}]`); 741 let num: number = receivedData.num; 742 743 // Process the data. 744 // Return the parcelable data result to the CallerAbility. 745 return new MyParcelable(num + 1, `send ${receivedData.str} succeed`) as rpc.Parcelable; 746 } 747 748 export default class CalleeAbility extends UIAbility { 749 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { 750 try { 751 this.callee.on(MSG_SEND_METHOD, sendMsgCallback); 752 } catch (err) { 753 let code = (err as BusinessError).code; 754 let message = (err as BusinessError).message; 755 console.error(`Failed to register. Code is ${code}, message is ${message}`); 756 } 757 } 758 759 onDestroy() { 760 try { 761 this.callee.off(MSG_SEND_METHOD); 762 } catch (err) { 763 let code = (err as BusinessError).code; 764 let message = (err as BusinessError).message; 765 console.error(`Failed to unregister. Code is ${code}, message is ${message}`); 766 } 767 } 768 } 769 ``` 770 771 772### Accessing the CalleeAbility 773 7741. Import the **UIAbility** module. 775 776 ```ts 777 import UIAbility from '@ohos.app.ability.UIAbility'; 778 ``` 779 7802. Obtain the caller interface. 781 782 The **UIAbilityContext** attribute implements **startAbilityByCall** to obtain the caller object for communication. The following example uses **this.context** to obtain the **UIAbilityContext**, uses **startAbilityByCall** to start the CalleeAbility, obtain the caller object, and register the **onRelease** listener of the CallerAbility. You need to implement processing based on service requirements. 783 784 785 ```ts 786 import UIAbility from '@ohos.app.ability.UIAbility'; 787 import { Caller } from '@ohos.app.ability.UIAbility'; 788 import { BusinessError } from '@ohos.base'; 789 790 export default class CallerAbility extends UIAbility { 791 caller: Caller | undefined = undefined; 792 793 // Register the onRelease() listener of the CallerAbility. 794 private regOnRelease(caller: Caller) { 795 try { 796 caller.on('release', (msg: string) => { 797 console.info(`caller onRelease is called ${msg}`); 798 }) 799 console.info('Succeeded in registering on release.'); 800 } catch (err) { 801 let code = (err as BusinessError).code; 802 let message = (err as BusinessError).message; 803 console.error(`Failed to caller register on release. Code is ${code}, message is ${message}`); 804 } 805 } 806 807 async onButtonGetCaller() { 808 try { 809 this.caller = await this.context.startAbilityByCall({ 810 bundleName: 'com.samples.CallApplication', 811 abilityName: 'CalleeAbility' 812 }); 813 if (this.caller === undefined) { 814 console.info('get caller failed') 815 return; 816 } 817 console.info('get caller success') 818 this.regOnRelease(this.caller) 819 } catch (err) { 820 let code = (err as BusinessError).code; 821 let message = (err as BusinessError).message; 822 console.error(`Failed to get caller. Code is ${code}, message is ${message}`); 823 } 824 } 825 } 826 ```