1# UIExtensionComponent (System API) 2 3**UIExtensionComponent** is used to embed UIs provided by other applications in the local application UI. The embedded content runs in another process, and the local application does not participate in its layout and rendering. 4 5This component is usually used in modular development scenarios where process isolation is required. 6 7> **NOTE** 8> 9> This component is supported since API version 10. Updates will be marked with a superscript to indicate their earliest API version. 10> 11> The APIs provided by this component are system APIs. 12 13## Restrictions 14 15This component does not support preview. 16 17The ability to be started must be a UIExtensionAbility, an extension ability with UI. For details about how to implement a UIExtensionAbility, see [@ohos.app.ability.UIExtensionAbility (Base Class for ExtensionAbilities with UI)](../../apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md). 18 19The width and height of the component must be set to non-zero valid values. 20 21## Child Components 22 23Not supported 24 25## APIs 26 27UIExtensionComponent(want: Want, options?: UIExtensionOptions) 28 29**Parameters** 30 31| Name | Type | Mandatory| Description | 32| --------------------- | ---------------------------------------------------------- | ---- | ------------------ | 33| want | [Want](../../apis-ability-kit/js-apis-app-ability-want.md) | Yes | Ability to start. | 34| options<sup>11+</sup> | [UIExtensionOptions](#uiextensionoptions11) | No | Construction parameters to be transferred.| 35 36## Attributes 37 38The [universal attributes](ts-universal-attributes-size.md) are supported. 39 40## Events 41 42The [universal events](ts-universal-events-click.md) are not supported. 43 44The events are passed to the remote UIExtensionAbility for processing after coordinate conversion. 45 46The following events are supported: 47 48### onRemoteReady 49 50onRemoteReady(callback: [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<UIExtensionProxy>) 51 52Invoked when the connection to the remote UIExtensionAbility is set up, that is, the UIExtensionAbility is ready to receive data through the proxy. 53 54**Parameters** 55 56| Name | Type | Description | 57| ---------------------------- | ------ | ------------------------------------------------------------ | 58| proxy | UIExtensionProxy | Proxy used to send data to the remote UIExtensionAbility. | 59 60### onReceive 61 62onReceive(callback: [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<{ [key: string]: Object }>) 63 64Invoked when the data sent by the started UIExtensionAbility is received. 65 66**Parameters** 67 68| Name | Type | Description | 69| ---------------------------- | ------ | ------------------------------------------------------------ | 70| data | { [key: string]: Object } | Data from the remote UIExtensionAbility. | 71 72### onResult<sup>(deprecated)</sup> 73 74onResult(callback: [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<{code: number; want?: Want}>) 75 76Invoked when the started UIExtensionAbility calls **terminateSelfWithResult**. After this callback is invoked, **OnRelease** is invoked. 77 78The result data of the remote UIExtensionAbility can be processed in this callback. For details, see [AbilityResult](../../apis-ability-kit/js-apis-inner-ability-abilityResult.md). 79 80> **NOTE** 81> This API is supported since API version 10 and deprecated since API version 12. You are advised to use [onTerminated](#onterminated12) instead. 82 83**Parameters** 84 85| Name | Type | Description | 86| ---------------------------- | ------ | ------------------------------------------------------------ | 87| code | number | Result code from the remote UIExtensionAbility. | 88| want | Want | [Want](../../apis-ability-kit/js-apis-app-ability-want.md) of the result from the remote UIExtensionAbility.| 89 90### onRelease<sup>(deprecated)</sup> 91 92onRelease(callback: [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<number>) 93 94Invoked when the started UIExtensionAbility is destroyed. 95 96If the UIExtensionAbility is destroyed correctly by calling **terminateSelfWithResult** or **terminateSelf**, the value of **releaseCode** is **0**. 97 98If the UIExtensionAbility is destroyed because it crashes or is forced stopped, the value of **releaseCode** is **1**. 99 100> **NOTE** 101> This API is supported since API version 10 and deprecated since API version 12. You are advised to use [onTerminated](#onterminated12) or [onError](#onerror) instead. 102 103**Parameters** 104 105| Name | Type | Description | 106| ---------------------------- | ------ | ------------------------------------------------------------ | 107| releaseCode | number | Code that indicates how the remote UIExtensionAbility is destroyed. The value **0** means normal destruction, and **1** means abnormal destruction. | 108 109### onError 110 111onError(callback:[ErrorCallback](../../apis-basic-services-kit/js-apis-base.md#errorcallback)) 112 113Invoked when an exception occurs during the running of the UIExtensionAbility. You can obtain the error information based on the **code**, **name**, and **message** parameters in the callback and rectify the exception accordingly. 114 115**Parameters** 116 117| Name | Type | Description | 118| ---------------------------- | ------ | ------------------------------------------------------------ | 119| err | [BusinessError](../../apis-basic-services-kit/js-apis-base.md#businesserror) | Error information. | 120 121### onTerminated<sup>12+<sup> 122 123onTerminated(callback: Callback<TerminationInfo>) 124 125Called when the started UIExtensionAbility is terminated by calling **terminateSelfWithResult** or **terminateSelf**. 126 127**Parameters** 128 129| Name | Type | Description | 130| ------- | ------ | ---------------------------------------------------------------------------------------- | 131| callback | [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<[TerminationInfo](#terminationinfo12)> | Callback used to return the result from the UIExtensionAbility.| 132 133> **NOTE** 134> 135> - If the UIExtensionAbility is terminated by calling **terminateSelfWithResult**, the carried information is passed as arguments into the callback function. 136> - If the UIExtensionAbility is terminated by calling **terminateSelf**, the input parameters **code** and **want** in the callback function are at their default values: **0** and **undefined**, respectively. 137 138### TerminationInfo<sup>12+<sup> 139 140Represents the result returned when the UIExtensionAbility that has been started exits properly by calling **terminateSelfWithResult** or **terminateSelf**. 141 142| Name | Type | Description | 143| ------- | ------ | --------------------------------------------------- | 144| code | number | Result code returned when the UIExtensionAbility exits.| 145| want | [Want](../../apis-ability-kit/js-apis-app-ability-want.md) | Data returned when the UIExtensionAbility exits. | 146 147## UIExtensionOptions<sup>11+</sup> 148Describes the optional construction parameters during **UIExtensionComponent** construction. 149 150**Parameters** 151 152| Name | Type | Mandatory| Description | 153| ---- | ---------------------------------------- | ---- | --------------- | 154| isTransferringCaller | boolean | No | Whether the UIExtensionComponent forwards the upper-level caller information when it is used for nesting.<br> Default value: **false**| 155| placeholder<sup>12+<sup> | [ComponentContent](../js-apis-arkui-ComponentContent.md) | No | Placeholder to be displayed before the UIExtensionComponent establishes a connection with the UIExtensionAbility.| 156| dpiFollowStrategy<sup>12+<sup> | [DpiFollowStrategy](ts-container-ui-extension-component-sys.md#dpifollowstrategy12) | No | Whether the DPI settings follow the host or UIExtensionAbility.<br> Default value: **FOLLOW_UI_EXTENSION_ABILITY_DPI**| 157 158## DpiFollowStrategy<sup>12+</sup> 159 160| Name | Description | 161| -------------------------------- | --------------- | 162| FOLLOW_HOST_DPI | The DPI settings follow the host.| 163| FOLLOW_UI_EXTENSION_ABILITY_DPI | The DPI settings follow the UIExtensionAbility.| 164 165## UIExtensionProxy 166 167Implements a **UIExtensionProxy** instance for the component host to send data to, subscribe to, or unsubscribe from the started UIExtensionAbility through the connection established between the two parties. 168 169### send 170 171send(data: { [key: string]: Object }): void 172 173Asynchronously sends data from the component host to the started UIExtensionAbility through the connection established between the two parties. 174 175**System capability**: SystemCapability.ArkUI.ArkUI.Full 176 177**Parameters** 178 179| Name | Type | Mandatory | Description | 180| ---- | ---------------------------------------- | ---- | --------------- | 181| data | { [key: string]: Object } | Yes | Data to be asynchronously sent to the started UIExtensionAbility.| 182 183### sendSync<sup>11+</sup> 184 185sendSync(data: { [key: string]: Object }): { [key: string]: Object } 186 187Synchronously sends data from the component host to the started UIExtensionAbility through the connection established between the two parties. 188 189**System capability**: SystemCapability.ArkUI.ArkUI.Full 190 191**Parameters** 192 193| Name | Type | Mandatory | Description | 194| ---- | ---------------------------------------- | ---- | --------------- | 195| data | { [key: string]: Object } | Yes | Data to be synchronously sent to the started UIExtensionAbility.| 196 197**Return value** 198 199| Type| Description| 200| ---- | ----| 201|{ [key: string]: Object } | Data returned by the UIExtensionAbility.| 202 203**Error codes** 204 205| ID| Description| 206| ---- | ----| 207| 100011 | UIExtensionAbility not registered.| 208| 100012 | Failed to send data.| 209 210### on('asyncReceiverRegister')<sup>11+</sup> 211 212on(type: 'asyncReceiverRegister', callback: (proxy: UIExtensionProxy) => void): void 213 214Subscribes to asynchronous registration of the started UIExtensionAbility through the connection established between the component host and UIExtensionAbility. 215 216**System capability**: SystemCapability.ArkUI.ArkUI.Full 217 218**Parameters** 219 220| Name | Type|Mandatory| Description| 221| ------ | -------- |---- | ------- | 222| type | string | Yes| Event type. The value is fixed at **'asyncReceiverRegister'**.| 223| callback | (proxy: UIExtensionProxy) => void | Yes| Callback used to return the result.| 224 225### on('syncReceiverRegister')<sup>11+</sup> 226 227on(type: 'syncReceiverRegister', callback: (proxy: UIExtensionProxy) => void): void 228 229Subscribes to synchronous registration of the started UIExtensionAbility through the connection established between the component host and UIExtensionAbility. 230 231**System capability**: SystemCapability.ArkUI.ArkUI.Full 232 233**Parameters** 234 235| Name | Type|Mandatory| Description| 236| ------ | -------- |---- | ------- | 237| type | string | Yes| Event type. The value is fixed at **'syncReceiverRegister'**.| 238| callback | (proxy: UIExtensionProxy) => void | Yes| Callback used to return the result.| 239 240### off('asyncReceiverRegister')<sup>11+</sup> 241 242off(type: 'asyncReceiverRegister', callback?: (proxy: UIExtensionProxy) => void): void 243 244Unsubscribes from asynchronous registration of the started UIExtensionAbility through the connection established between the component host and UIExtensionAbility. 245 246**System capability**: SystemCapability.ArkUI.ArkUI.Full 247 248**Parameters** 249 250| Name | Type| Mandatory| Description| 251| ------ | -------- | ----- | ------- | 252| type | string | Yes| Event type. The value is fixed at **'asyncReceiverRegister'**.| 253| callback | (proxy: UIExtensionProxy) => void | No| Callback used for unsubscription.<br> If this parameter is not set, this API unsubscribes from all callbacks corresponding to **type**.| 254 255### off('syncReceiverRegister')<sup>11+</sup> 256 257off(type: 'syncReceiverRegister', callback?: (proxy: UIExtensionProxy) => void): void 258 259Unsubscribes from synchronous registration of the started UIExtensionAbility through the connection established between the component host and UIExtensionAbility. 260 261**System capability**: SystemCapability.ArkUI.ArkUI.Full 262 263**Parameters** 264 265| Name | Type| Mandatory| Description| 266| ------ | -------- | ----- | ------- | 267| type | string | Yes| Event type. The value is fixed at **'syncReceiverRegister'**.| 268| callback | (proxy: UIExtensionProxy) => void | No| Callback used for unsubscription.<br> If this parameter is not set, this API unsubscribes from all callbacks corresponding to **type**.| 269 270## Example 271 272This example shows only the method used by the component and the UIExtensionAbility. For the code to run properly, you need to install the ability whose **bundleName** is **"com.example.uiextensionprovider"** and **abilityName** is **"UIExtensionProvider"** on the device. 273 274```ts 275// Component usage example: 276import { ComponentContent } from '@kit.ArkUI'; 277class Params { 278} 279@Builder 280function LoadingBuilder(params: Params) { 281 Column() { 282 LoadingProgress() 283 .color(Color.Blue) 284 } 285} 286@Entry 287@Component 288struct Second { 289 @State message1: string = 'Hello World 1' 290 @State message2: string = 'Hello World 2' 291 @State message3: string = 'Hello World 3' 292 @State visible: Visibility = Visibility.Hidden 293 @State wid: number = 300 294 @State hei: number = 300 295 private proxy: UIExtensionProxy | null = null; 296 private contentNode = new ComponentContent(this.getUIContext(), wrapBuilder(LoadingBuilder), new Params); 297 298 299 build() { 300 Row() { 301 Column() { 302 Text(this.message1).fontSize(30) 303 Text(this.message2).fontSize(30) 304 Text(this.message3).fontSize(30) 305 UIExtensionComponent({ 306 bundleName : "com.example.newdemo", 307 abilityName: "UIExtensionProvider", 308 parameters: { 309 "ability.want.params.uiExtensionType": "dialog" 310 }}, 311 { 312 placeholder: this.contentNode 313 }) 314 .width(this.wid) 315 .height(this.hei) 316 .border({width: 5, color: Color.Blue}) 317 .onReceive((data) => { 318 console.info('Lee onReceive, for test') 319 this.message3 = JSON.stringify(data['data']) 320 }) 321 .onTerminated((info) => { 322 console.info('onTerminated: code =' + info.code + ', want = ' + JSON.stringify(info.want)); 323 }) 324 .onRemoteReady((proxy) => { 325 console.info('onRemoteReady, for test') 326 this.proxy = proxy 327 328 this.proxy.on("syncReceiverRegister", syncRegisterCallback1); 329 // this.proxy.on("syncReceiverRegister", syncRegisterCallback2); 330 331 332 // this.proxy.off("syncReceiverRegister"); 333 334 // this.proxy.off("syncReceiverRegister", (proxy) => { 335 // console.info("off invoke for test, type is syncReceiverRegister"); 336 // }); 337 338 this.proxy.on("asyncReceiverRegister", (proxy1) => { 339 console.info("on invoke for test, type is asyncReceiverRegister"); 340 }); 341 // 342 // this.proxy.off("asyncReceiverRegister"); 343 }) 344 345 Button("Send to UIExtensionAbility").onClick(() => { 346 if (this.proxy != undefined) { 347 this.proxy.send({data: "Hello 1"}) 348 349 try { 350 let re = this.proxy.sendSync({data: "Hello 2"}) 351 console.info("for test, re=" + JSON.stringify(re)); 352 } catch (err) { 353 console.error(`sendSync failed for test. errCode=${err.code}, msg=${err.message}`); 354 } 355 } 356 }) 357 } 358 .width('100%') 359 } 360 .height('100%') 361 } 362} 363 364function syncRegisterCallback1(proxy: UIExtensionProxy) { 365 console.info("on invoke for test, syncRegisterCallback1, type is syncReceiverRegister"); 366} 367 368function syncRegisterCallback2(proxy: UIExtensionProxy) { 369 console.info("on invoke for test, syncRegisterCallback2, type is syncReceiverRegister"); 370} 371``` 372 373```ts 374// Extension entry point file UIExtensionProvider.ts 375import { UIExtensionAbility, UIExtensionContentSession, Want } from '@kit.AbilityKit'; 376 377const TAG: string = '[UIExtAbility]' 378export default class UIExtAbility extends UIExtensionAbility { 379 380 onCreate() { 381 console.log(TAG, `UIExtAbility onCreate`) 382 } 383 384 onForeground() { 385 console.log(TAG, `UIExtAbility onForeground`) 386 } 387 388 onBackground() { 389 console.log(TAG, `UIExtAbility onBackground`) 390 } 391 392 onDestroy() { 393 console.log(TAG, `UIExtAbility onDestroy`) 394 } 395 396 onSessionCreate(want: Want, session: UIExtensionContentSession) { 397 console.log(TAG, `UIExtAbility onSessionCreate, want: ${JSON.stringify(want)}`) 398 let param: Record<string, UIExtensionContentSession> = { 399 'session': session 400 }; 401 let storage: LocalStorage = new LocalStorage(param); 402 session.loadContent('pages/extension', storage); 403 } 404 405 onSessionDestroy(session: UIExtensionContentSession) { 406 console.log(TAG, `UIExtAbility onSessionDestroy`) 407 } 408} 409``` 410 411```ts 412// Entry page file of the Extension Ability: extension.ets 413import { UIExtensionContentSession } from '@kit.AbilityKit'; 414import { router } from '@kit.ArkUI'; 415 416let storage = LocalStorage.getShared() 417AppStorage.setOrCreate('message', 'UIExtensionAbility') 418 419@Entry(storage) 420@Component 421struct Extension { 422 @StorageLink('message') storageLink: string = ''; 423 private session: UIExtensionContentSession | undefined = storage.get<UIExtensionContentSession>('session'); 424 425 onPageShow() { 426 if (this.session != undefined) { 427 this.session.setReceiveDataCallback((data)=> { 428 this.storageLink = JSON.stringify(data) 429 console.info("invoke for test, handle callback set by setReceiveDataCallback successfully"); 430 }) 431 432 this.session.setReceiveDataForResultCallback(func1) 433 } 434 } 435 436 build() { 437 Row() { 438 Column() { 439 Text(this.storageLink) 440 .fontSize(20) 441 .fontWeight(FontWeight.Bold) 442 Button("Send to Component").onClick(()=>{ 443 if (this.session != undefined) { 444 this.session.sendData({"data": 543321}) 445 console.info('send 543321, for test') 446 } 447 }) 448 Button("terminate").onClick(()=> { 449 if (this.session != undefined) { 450 this.session.terminateSelf(); 451 } 452 storage.clear() 453 }) 454 Button("terminate with result").onClick(()=>{ 455 if (this.session != undefined) { 456 this.session.terminateSelfWithResult({ 457 resultCode: 0, 458 want: { 459 bundleName: "myBundleName", 460 parameters: { "result": 123456 } 461 } 462 }) 463 } 464 storage.clear() 465 }) 466 467 Button("Redirect").onClick(()=> { 468 router.pushUrl({url: 'pages/hello'}) 469 }) 470 } 471 } 472 .height('100%') 473 } 474} 475function func1(data: Record<string, Object>): Record<string, Object> { 476 let linkToMsg: SubscribedAbstractProperty<string> = AppStorage.link('message'); 477 linkToMsg.set(JSON.stringify(data)) 478 console.info("invoke for test, handle callback set by setReceiveDataForResultCallback successfully"); 479 return data; 480} 481 482``` 483