1e41f4b71Sopenharmony_ci# UIExtensionAbility 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci## Overview 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ci[UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md) is an ExtensionAbility component of the UI type. It is usually used in modular development scenarios where process isolation is required, for example, system dialog boxes, status bars, and capsules. There are two forms: embedded and system pop-ups. 6e41f4b71Sopenharmony_ci- The UIExtensionAbility in embedded mode must be used together with the [\<UIExtensionComponent>](../reference/apis-arkui/arkui-ts/ts-container-ui-extension-component-sys.md). Specifically, with the \<UIExtensionComponent>, you can embed the UI provided by the UIExtensionAbility of another application into a UIAbility of your application. The UIExtensionAbility runs in a process independent of the UIAbility for UI layout and rendering. 7e41f4b71Sopenharmony_ci- To start the UIExtensionAbility in system pop-up mode, call [requestModalUIExtensionAbility](../reference/apis-ability-kit/js-apis-inner-application-serviceExtensionContext-sys.md#serviceextensioncontextrequestmodaluiextension11) or the specified interface encapsulated in the application. 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ci## Constraints 10e41f4b71Sopenharmony_ci- Currently, the UIExtensionAbility of the **sys/commonUI**, **sysDialog**, and **sysPicker** types can be used only by system applications. For details about the UIExtensionAbility types and corresponding permission control, see the [module.json5 file](../quick-start/module-configuration-file.md). 11e41f4b71Sopenharmony_ci- The UIExtensionAbility can be started only by applications that are running in the foreground. 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ci## Lifecycle 14e41f4b71Sopenharmony_ciThe [UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md) class provides the lifecycle callbacks [onCreate](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#uiextensionabilityoncreate), [onSessionCreate](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#uiextensionabilityonsessioncreate), [onSessionDestroy](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#uiextensionabilityonsessiondestroy), [onForeground](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#uiextensionabilityonforeground), [onBackground](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#uiextensionabilityonbackground), and [onDestroy](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#uiextensionabilityondestroy). You must override them as required. 15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ci- **onCreate**: called to initialize the service logic when a UIExtensionAbility is created. 17e41f4b71Sopenharmony_ci- **onSessionCreate**: called when a **UIExtensionContentSession** instance is created for the UIExtensionAbility. 18e41f4b71Sopenharmony_ci- **onSessionDestroy**: called when a **UIExtensionContentSession** instance is destroyed for the UIExtensionAbility. 19e41f4b71Sopenharmony_ci- **onForeground**: called when the UIExtensionAbility is switched from the background to the foreground. 20e41f4b71Sopenharmony_ci- **onBackground**: called when the UIExtensionAbility is switched from the foreground to the background. 21e41f4b71Sopenharmony_ci- **onDestroy**: called to clear resources when the UIExtensionAbility is destroyed. 22e41f4b71Sopenharmony_ci 23e41f4b71Sopenharmony_ci## Selecting a Proper Process Model for the UIExtensionAbility 24e41f4b71Sopenharmony_ciThe [UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md) supports the multiton pattern. Each embedded UI corresponds to a UIExtensionAbility instance. In the multiton scenario, the multi-process model is used by default. 25e41f4b71Sopenharmony_ci 26e41f4b71Sopenharmony_ciWhen multiple UIExtensionAbility instances exist in an application, these instances can run in independent processes or share one process. They can also be grouped, and each group share one process. You can select a process model based on the **extensionProcessMode** field in the [module.json5](../quick-start/module-configuration-file.md) file. The table below describes the comparison between the process models. 27e41f4b71Sopenharmony_ci| Process Model| extensionProcessMode Field Value| Description| 28e41f4b71Sopenharmony_ci| --------| --------| --------| 29e41f4b71Sopenharmony_ci| One process for all UIExtensionAbility instances in the same bundle|bundle| The UIExtensionAbility instances do not need to communicate with each other across IPCs. Their statuses are dependent and affect each other.| 30e41f4b71Sopenharmony_ci| One process for all UIExtensionAbility instances with the same name| type |The UIExtensionAbility instances of the same type are configured in the same process so that your application can manage them by type.| 31e41f4b71Sopenharmony_ci| One process for each UIExtensionAbility instance| instance | The UIExtensionAbility instances communicate with each other only across IPCs. Their statuses do not affect each other, which is more secure.| 32e41f4b71Sopenharmony_ci### One Process for All UIExtensionAbility Instances in the Bundle 33e41f4b71Sopenharmony_ciThe [UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md) instances of the same bundle are configured in a process. This makes communication between multiple instances easier. However, the status of these instances affects each other. When an instance in the process exits abnormally, all instances in the process exit. 34e41f4b71Sopenharmony_ci 35e41f4b71Sopenharmony_ci**Figure 1** Bundle-based process model configuration 36e41f4b71Sopenharmony_ci 37e41f4b71Sopenharmony_ci 38e41f4b71Sopenharmony_ci 39e41f4b71Sopenharmony_ciThe sample code of **Index.ets** is as follows: 40e41f4b71Sopenharmony_ci```ts 41e41f4b71Sopenharmony_ci@Entry 42e41f4b71Sopenharmony_ci@Component 43e41f4b71Sopenharmony_cistruct Index { 44e41f4b71Sopenharmony_ci @State message: string = 'UIExtension UserA'; 45e41f4b71Sopenharmony_ci private myProxy: UIExtensionProxy | undefined = undefined; 46e41f4b71Sopenharmony_ci 47e41f4b71Sopenharmony_ci build() { 48e41f4b71Sopenharmony_ci Row() { 49e41f4b71Sopenharmony_ci Column() { 50e41f4b71Sopenharmony_ci Text(this.message) 51e41f4b71Sopenharmony_ci .fontSize(30) 52e41f4b71Sopenharmony_ci .size({ width: '100%', height: '50' }) 53e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 54e41f4b71Sopenharmony_ci .textAlign(TextAlign.Center) 55e41f4b71Sopenharmony_ci 56e41f4b71Sopenharmony_ci UIExtensionComponent( 57e41f4b71Sopenharmony_ci { 58e41f4b71Sopenharmony_ci bundleName: 'com.samples.uiextensionability', 59e41f4b71Sopenharmony_ci abilityName: 'UIExtensionProvider', 60e41f4b71Sopenharmony_ci moduleName: 'entry', 61e41f4b71Sopenharmony_ci parameters: { 62e41f4b71Sopenharmony_ci 'ability.want.params.uiExtensionType': 'sys/commonUI', 63e41f4b71Sopenharmony_ci } 64e41f4b71Sopenharmony_ci }) 65e41f4b71Sopenharmony_ci .onRemoteReady((proxy) => { 66e41f4b71Sopenharmony_ci this.myProxy = proxy; 67e41f4b71Sopenharmony_ci }) 68e41f4b71Sopenharmony_ci .onReceive((data) => { 69e41f4b71Sopenharmony_ci this.message = JSON.stringify(data); 70e41f4b71Sopenharmony_ci }) 71e41f4b71Sopenharmony_ci .onResult((data) => { 72e41f4b71Sopenharmony_ci this.message = JSON.stringify(data); 73e41f4b71Sopenharmony_ci }) 74e41f4b71Sopenharmony_ci .onRelease((code) => { 75e41f4b71Sopenharmony_ci this.message = "release code:" + code; 76e41f4b71Sopenharmony_ci }) 77e41f4b71Sopenharmony_ci .offset({ x: 0, y: 10 }) 78e41f4b71Sopenharmony_ci .size({ width: 300, height: 300 }) 79e41f4b71Sopenharmony_ci .border({ width: 5, color: 0x317AF7, radius: 10, style: BorderStyle.Dotted }) 80e41f4b71Sopenharmony_ci 81e41f4b71Sopenharmony_ci UIExtensionComponent( 82e41f4b71Sopenharmony_ci { 83e41f4b71Sopenharmony_ci bundleName: 'com.samples.uiextension2', 84e41f4b71Sopenharmony_ci abilityName: 'UIExtensionProviderB', 85e41f4b71Sopenharmony_ci moduleName: 'entry', 86e41f4b71Sopenharmony_ci parameters: { 87e41f4b71Sopenharmony_ci 'ability.want.params.uiExtensionType': 'sys/commonUI', 88e41f4b71Sopenharmony_ci } 89e41f4b71Sopenharmony_ci }) 90e41f4b71Sopenharmony_ci .onRemoteReady((proxy) => { 91e41f4b71Sopenharmony_ci this.myProxy = proxy; 92e41f4b71Sopenharmony_ci }) 93e41f4b71Sopenharmony_ci .onReceive((data) => { 94e41f4b71Sopenharmony_ci this.message = JSON.stringify(data); 95e41f4b71Sopenharmony_ci }) 96e41f4b71Sopenharmony_ci .onResult((data) => { 97e41f4b71Sopenharmony_ci this.message = JSON.stringify(data); 98e41f4b71Sopenharmony_ci }) 99e41f4b71Sopenharmony_ci .onRelease((code) => { 100e41f4b71Sopenharmony_ci this.message = "release code:" + code; 101e41f4b71Sopenharmony_ci }) 102e41f4b71Sopenharmony_ci .offset({ x: 0, y: 50 }) 103e41f4b71Sopenharmony_ci .size({ width: 300, height: 300 }) 104e41f4b71Sopenharmony_ci .border({ width: 5, color: 0x317AF7, radius: 10, style: BorderStyle.Dotted }) 105e41f4b71Sopenharmony_ci } 106e41f4b71Sopenharmony_ci .width('100%') 107e41f4b71Sopenharmony_ci } 108e41f4b71Sopenharmony_ci .height('100%') 109e41f4b71Sopenharmony_ci } 110e41f4b71Sopenharmony_ci} 111e41f4b71Sopenharmony_ci``` 112e41f4b71Sopenharmony_ci**Figure 2** Index page generated based on the preceding code 113e41f4b71Sopenharmony_ci 114e41f4b71Sopenharmony_ci 115e41f4b71Sopenharmony_ci 116e41f4b71Sopenharmony_ciIf this process model is used, the process name format is as follows: 117e41f4b71Sopenharmony_ci 118e41f4b71Sopenharmony_ciprocess name [{bundleName}:{UIExtensionAbility type}] 119e41f4b71Sopenharmony_ci 120e41f4b71Sopenharmony_ciExample: process name [com.ohos.intentexecutedemo:xxx] 121e41f4b71Sopenharmony_ci 122e41f4b71Sopenharmony_ci**Figure 3** Bundle-based process model 123e41f4b71Sopenharmony_ci 124e41f4b71Sopenharmony_ci 125e41f4b71Sopenharmony_ci 126e41f4b71Sopenharmony_ci### One Process for All UIExtensionAbility Instances of the Same Type 127e41f4b71Sopenharmony_ciProcesses are allocated based on the [UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md) type. Multiple UIExtensionAbility instances of the same type are configured in the same process so that your application can manage the instances by type. 128e41f4b71Sopenharmony_ci 129e41f4b71Sopenharmony_ci**Figure 4** Type-based process model configuration 130e41f4b71Sopenharmony_ci 131e41f4b71Sopenharmony_ci 132e41f4b71Sopenharmony_ci 133e41f4b71Sopenharmony_ciThe sample code of **Index.ets** is as follows: 134e41f4b71Sopenharmony_ci```ts 135e41f4b71Sopenharmony_ci@Entry 136e41f4b71Sopenharmony_ci@Component 137e41f4b71Sopenharmony_cistruct Index { 138e41f4b71Sopenharmony_ci @State message: string = 'UIExtension User'; 139e41f4b71Sopenharmony_ci private myProxy: UIExtensionProxy | undefined = undefined; 140e41f4b71Sopenharmony_ci 141e41f4b71Sopenharmony_ci build() { 142e41f4b71Sopenharmony_ci Row() { 143e41f4b71Sopenharmony_ci Column() { 144e41f4b71Sopenharmony_ci Text(this.message) 145e41f4b71Sopenharmony_ci .fontSize(30) 146e41f4b71Sopenharmony_ci .size({ width: '100%', height: '50' }) 147e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 148e41f4b71Sopenharmony_ci .textAlign(TextAlign.Center) 149e41f4b71Sopenharmony_ci 150e41f4b71Sopenharmony_ci UIExtensionComponent( 151e41f4b71Sopenharmony_ci { 152e41f4b71Sopenharmony_ci bundleName: 'com.samples.uiextensionability', 153e41f4b71Sopenharmony_ci abilityName: 'UIExtensionProviderA', 154e41f4b71Sopenharmony_ci moduleName: 'entry', 155e41f4b71Sopenharmony_ci parameters: { 156e41f4b71Sopenharmony_ci 'ability.want.params.uiExtensionType': 'sys/commonUI', 157e41f4b71Sopenharmony_ci } 158e41f4b71Sopenharmony_ci }) 159e41f4b71Sopenharmony_ci .onRemoteReady((proxy) => { 160e41f4b71Sopenharmony_ci this.myProxy = proxy; 161e41f4b71Sopenharmony_ci }) 162e41f4b71Sopenharmony_ci .onReceive((data) => { 163e41f4b71Sopenharmony_ci this.message = JSON.stringify(data); 164e41f4b71Sopenharmony_ci }) 165e41f4b71Sopenharmony_ci .onResult((data) => { 166e41f4b71Sopenharmony_ci this.message = JSON.stringify(data); 167e41f4b71Sopenharmony_ci }) 168e41f4b71Sopenharmony_ci .onRelease((code) => { 169e41f4b71Sopenharmony_ci this.message = "release code:" + code; 170e41f4b71Sopenharmony_ci }) 171e41f4b71Sopenharmony_ci .offset({ x: 0, y: 10 }) 172e41f4b71Sopenharmony_ci .size({ width: 300, height: 300 }) 173e41f4b71Sopenharmony_ci .border({ width: 5, color: 0x317AF7, radius: 10, style: BorderStyle.Dotted }) 174e41f4b71Sopenharmony_ci 175e41f4b71Sopenharmony_ci UIExtensionComponent( 176e41f4b71Sopenharmony_ci { 177e41f4b71Sopenharmony_ci bundleName: 'com.samples.uiextensionability', 178e41f4b71Sopenharmony_ci abilityName: 'UIExtensionProviderB', 179e41f4b71Sopenharmony_ci moduleName: 'entry', 180e41f4b71Sopenharmony_ci parameters: { 181e41f4b71Sopenharmony_ci 'ability.want.params.uiExtensionType': 'sys/commonUI', 182e41f4b71Sopenharmony_ci } 183e41f4b71Sopenharmony_ci }) 184e41f4b71Sopenharmony_ci .onRemoteReady((proxy) => { 185e41f4b71Sopenharmony_ci this.myProxy = proxy; 186e41f4b71Sopenharmony_ci }) 187e41f4b71Sopenharmony_ci .onReceive((data) => { 188e41f4b71Sopenharmony_ci this.message = JSON.stringify(data); 189e41f4b71Sopenharmony_ci }) 190e41f4b71Sopenharmony_ci .onResult((data) => { 191e41f4b71Sopenharmony_ci this.message = JSON.stringify(data); 192e41f4b71Sopenharmony_ci }) 193e41f4b71Sopenharmony_ci .onRelease((code) => { 194e41f4b71Sopenharmony_ci this.message = "release code:" + code; 195e41f4b71Sopenharmony_ci }) 196e41f4b71Sopenharmony_ci .offset({ x: 0, y: 50 }) 197e41f4b71Sopenharmony_ci .size({ width: 300, height: 300 }) 198e41f4b71Sopenharmony_ci .border({ width: 5, color: 0x317AF7, radius: 10, style: BorderStyle.Dotted }) 199e41f4b71Sopenharmony_ci } 200e41f4b71Sopenharmony_ci .width('100%') 201e41f4b71Sopenharmony_ci } 202e41f4b71Sopenharmony_ci .height('100%') 203e41f4b71Sopenharmony_ci } 204e41f4b71Sopenharmony_ci} 205e41f4b71Sopenharmony_ci``` 206e41f4b71Sopenharmony_ci**Figure 5** Index page generated based on the preceding code 207e41f4b71Sopenharmony_ci 208e41f4b71Sopenharmony_ci 209e41f4b71Sopenharmony_ci 210e41f4b71Sopenharmony_ciIf this process model is used, the process name format is as follows: 211e41f4b71Sopenharmony_ci 212e41f4b71Sopenharmony_ciprocess name [{bundleName}:{UIExtensionAbility name}] 213e41f4b71Sopenharmony_ci 214e41f4b71Sopenharmony_ciExample: process name [com.ohos.intentexecutedemo:xxx] 215e41f4b71Sopenharmony_ci 216e41f4b71Sopenharmony_ci**Figure 6** Type-based process model 217e41f4b71Sopenharmony_ci 218e41f4b71Sopenharmony_ci 219e41f4b71Sopenharmony_ci 220e41f4b71Sopenharmony_ci### One Process for Each UIExtensionAbility Instance 221e41f4b71Sopenharmony_ciProcesses are allocated based on the [UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md) instance. That is, each UIExtensionAbility instance has an independent process. In this mode, UIExtensionAbility instances can communicate with each other only through IPCs. However, their statuses do not affect each other, improving security. 222e41f4b71Sopenharmony_ci 223e41f4b71Sopenharmony_ci**Figure 7** Instance-specific process model configuration 224e41f4b71Sopenharmony_ci 225e41f4b71Sopenharmony_ci 226e41f4b71Sopenharmony_ci 227e41f4b71Sopenharmony_ci 228e41f4b71Sopenharmony_ciThe sample code of **Index.ets** is as follows: 229e41f4b71Sopenharmony_ci```ts 230e41f4b71Sopenharmony_ci@Entry 231e41f4b71Sopenharmony_ci@Component 232e41f4b71Sopenharmony_cistruct Index { 233e41f4b71Sopenharmony_ci @State message: string = 'UIExtension User' 234e41f4b71Sopenharmony_ci private myProxy: UIExtensionProxy | undefined = undefined; 235e41f4b71Sopenharmony_ci 236e41f4b71Sopenharmony_ci build() { 237e41f4b71Sopenharmony_ci Row() { 238e41f4b71Sopenharmony_ci Column() { 239e41f4b71Sopenharmony_ci Text(this.message) 240e41f4b71Sopenharmony_ci .fontSize(30) 241e41f4b71Sopenharmony_ci .size({ width: '100%', height: '50' }) 242e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 243e41f4b71Sopenharmony_ci .textAlign(TextAlign.Center) 244e41f4b71Sopenharmony_ci 245e41f4b71Sopenharmony_ci UIExtensionComponent( 246e41f4b71Sopenharmony_ci { 247e41f4b71Sopenharmony_ci bundleName: 'com.samples.uiextensionability', 248e41f4b71Sopenharmony_ci abilityName: 'UIExtensionProvider', 249e41f4b71Sopenharmony_ci moduleName: 'entry', 250e41f4b71Sopenharmony_ci parameters: { 251e41f4b71Sopenharmony_ci 'ability.want.params.uiExtensionType': 'sys/commonUI', 252e41f4b71Sopenharmony_ci } 253e41f4b71Sopenharmony_ci }) 254e41f4b71Sopenharmony_ci .onRemoteReady((proxy) => { 255e41f4b71Sopenharmony_ci this.myProxy = proxy; 256e41f4b71Sopenharmony_ci }) 257e41f4b71Sopenharmony_ci .onReceive((data) => { 258e41f4b71Sopenharmony_ci this.message = JSON.stringify(data); 259e41f4b71Sopenharmony_ci }) 260e41f4b71Sopenharmony_ci .onResult((data) => { 261e41f4b71Sopenharmony_ci this.message = JSON.stringify(data); 262e41f4b71Sopenharmony_ci }) 263e41f4b71Sopenharmony_ci .onRelease((code) => { 264e41f4b71Sopenharmony_ci this.message = "release code:" + code; 265e41f4b71Sopenharmony_ci }) 266e41f4b71Sopenharmony_ci .offset({ x: 0, y: 10 }) 267e41f4b71Sopenharmony_ci .size({ width: 300, height: 300 }) 268e41f4b71Sopenharmony_ci .border({ width: 5, color: 0x317AF7, radius: 10, style: BorderStyle.Dotted }) 269e41f4b71Sopenharmony_ci 270e41f4b71Sopenharmony_ci UIExtensionComponent( 271e41f4b71Sopenharmony_ci { 272e41f4b71Sopenharmony_ci bundleName: 'com.samples.uiextensionability', 273e41f4b71Sopenharmony_ci abilityName: 'UIExtensionProvider', 274e41f4b71Sopenharmony_ci moduleName: 'entry', 275e41f4b71Sopenharmony_ci parameters: { 276e41f4b71Sopenharmony_ci 'ability.want.params.uiExtensionType': 'sys/commonUI', 277e41f4b71Sopenharmony_ci } 278e41f4b71Sopenharmony_ci }) 279e41f4b71Sopenharmony_ci .onRemoteReady((proxy) => { 280e41f4b71Sopenharmony_ci this.myProxy = proxy; 281e41f4b71Sopenharmony_ci }) 282e41f4b71Sopenharmony_ci .onReceive((data) => { 283e41f4b71Sopenharmony_ci this.message = JSON.stringify(data); 284e41f4b71Sopenharmony_ci }) 285e41f4b71Sopenharmony_ci .onResult((data) => { 286e41f4b71Sopenharmony_ci this.message = JSON.stringify(data); 287e41f4b71Sopenharmony_ci }) 288e41f4b71Sopenharmony_ci .onRelease((code) => { 289e41f4b71Sopenharmony_ci this.message = "release code:" + code; 290e41f4b71Sopenharmony_ci }) 291e41f4b71Sopenharmony_ci .offset({ x: 0, y: 50 }) 292e41f4b71Sopenharmony_ci .size({ width: 300, height: 300 }) 293e41f4b71Sopenharmony_ci .border({ width: 5, color: 0x317AF7, radius: 10, style: BorderStyle.Dotted }) 294e41f4b71Sopenharmony_ci } 295e41f4b71Sopenharmony_ci .width('100%') 296e41f4b71Sopenharmony_ci } 297e41f4b71Sopenharmony_ci .height('100%') 298e41f4b71Sopenharmony_ci } 299e41f4b71Sopenharmony_ci} 300e41f4b71Sopenharmony_ci``` 301e41f4b71Sopenharmony_ci**Figure 8** Index page generated based on the preceding code 302e41f4b71Sopenharmony_ci 303e41f4b71Sopenharmony_ci 304e41f4b71Sopenharmony_ci 305e41f4b71Sopenharmony_ciIf this process model is used, the process name format is as follows: 306e41f4b71Sopenharmony_ci 307e41f4b71Sopenharmony_ciprocess name [{bundleName}: {UIExtensionAbility type}: {instance suffix}] 308e41f4b71Sopenharmony_ci 309e41f4b71Sopenharmony_ciExample: process name [com.ohos.intentexecutedemo:xxx:n] 310e41f4b71Sopenharmony_ci 311e41f4b71Sopenharmony_ci**Figure 9** Instance-specific process model 312e41f4b71Sopenharmony_ci 313e41f4b71Sopenharmony_ci 314e41f4b71Sopenharmony_ci 315e41f4b71Sopenharmony_ciThe UIExtensionAbility provides related capabilities through the [UIExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-uiExtensionContext.md) and [UIExtensionContentSession](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionContentSession.md). In this document, the started UIExtensionAbility is called the provider, and the [UIExtensionComponent](../reference/apis-arkui/arkui-ts/ts-container-ui-extension-component-sys.md) that starts the UIExtensionAbility is called the client. 316e41f4b71Sopenharmony_ci 317e41f4b71Sopenharmony_ci## How to Develop 318e41f4b71Sopenharmony_ci 319e41f4b71Sopenharmony_ci For details about how to develop a system dialog box, see [requestModalUIExtension](../reference/apis-ability-kit/js-apis-inner-application-serviceExtensionContext-sys.md#serviceextensioncontextrequestmodaluiextension11). 320e41f4b71Sopenharmony_ci 321e41f4b71Sopenharmony_ci### Developing the UIExtensionAbility Provider 322e41f4b71Sopenharmony_ci 323e41f4b71Sopenharmony_ciTo implement a provider, create a [UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md) in DevEco Studio as follows: 324e41f4b71Sopenharmony_ci 325e41f4b71Sopenharmony_ci1. In the **ets** directory of the **Module** project, right-click and choose **New > Directory** to create a directory named **uiextensionability**. 326e41f4b71Sopenharmony_ci 327e41f4b71Sopenharmony_ci2. Right-click the **uiextensionability** directory, and choose **New > File** to create a file named **UIExtensionAbility.ets**. 328e41f4b71Sopenharmony_ci 329e41f4b71Sopenharmony_ci3. Open the **UIExtensionAbility.ets** file and import its dependencies. Customize a class that inherits from **UIExtensionAbility** and implement the lifecycle callbacks [onCreate](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#uiextensionabilityoncreate), [onSessionCreate](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#uiextensionabilityonsessioncreate), [onSessionDestroy](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#uiextensionabilityonsessiondestroy), [onForeground](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#uiextensionabilityonforeground), [onBackground](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#uiextensionabilityonbackground), and [onDestroy](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#uiextensionabilityondestroy). 330e41f4b71Sopenharmony_ci 331e41f4b71Sopenharmony_ci ```ts 332e41f4b71Sopenharmony_ci import { Want, UIExtensionAbility, UIExtensionContentSession } from '@kit.AbilityKit'; 333e41f4b71Sopenharmony_ci 334e41f4b71Sopenharmony_ci const TAG: string = '[testTag] UIExtAbility'; 335e41f4b71Sopenharmony_ci 336e41f4b71Sopenharmony_ci export default class UIExtAbility extends UIExtensionAbility { 337e41f4b71Sopenharmony_ci onCreate() { 338e41f4b71Sopenharmony_ci console.log(TAG, `onCreate`); 339e41f4b71Sopenharmony_ci } 340e41f4b71Sopenharmony_ci 341e41f4b71Sopenharmony_ci onForeground() { 342e41f4b71Sopenharmony_ci console.log(TAG, `onForeground`); 343e41f4b71Sopenharmony_ci } 344e41f4b71Sopenharmony_ci 345e41f4b71Sopenharmony_ci onBackground() { 346e41f4b71Sopenharmony_ci console.log(TAG, `onBackground`); 347e41f4b71Sopenharmony_ci } 348e41f4b71Sopenharmony_ci 349e41f4b71Sopenharmony_ci onDestroy() { 350e41f4b71Sopenharmony_ci console.log(TAG, `onDestroy`); 351e41f4b71Sopenharmony_ci } 352e41f4b71Sopenharmony_ci 353e41f4b71Sopenharmony_ci onSessionCreate(want: Want, session: UIExtensionContentSession) { 354e41f4b71Sopenharmony_ci console.log(TAG, `onSessionCreate, want: ${JSON.stringify(want)}}`); 355e41f4b71Sopenharmony_ci let storage: LocalStorage = new LocalStorage(); 356e41f4b71Sopenharmony_ci storage.setOrCreate('session', session); 357e41f4b71Sopenharmony_ci session.loadContent('pages/Extension', storage); 358e41f4b71Sopenharmony_ci } 359e41f4b71Sopenharmony_ci 360e41f4b71Sopenharmony_ci onSessionDestroy(session: UIExtensionContentSession) { 361e41f4b71Sopenharmony_ci console.log(TAG, `onSessionDestroy`); 362e41f4b71Sopenharmony_ci } 363e41f4b71Sopenharmony_ci } 364e41f4b71Sopenharmony_ci ``` 365e41f4b71Sopenharmony_ci 366e41f4b71Sopenharmony_ci4. Write the entry page file **pages/extension.ets**, which will be loaded in [onSessionCreate](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#uiextensionabilityonsessioncreate) of the [UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md), and declare "pages/Extension" in the **entry\src\main\resources\base\profile\main_pages.json** file. The content of **extension.ets** is as follows: 367e41f4b71Sopenharmony_ci 368e41f4b71Sopenharmony_ci ```ts 369e41f4b71Sopenharmony_ci import { UIExtensionContentSession } from '@kit.AbilityKit'; 370e41f4b71Sopenharmony_ci 371e41f4b71Sopenharmony_ci let storage = LocalStorage.GetShared(); 372e41f4b71Sopenharmony_ci const TAG: string = `[testTag] ExtensionPage`; 373e41f4b71Sopenharmony_ci 374e41f4b71Sopenharmony_ci @Entry(storage) 375e41f4b71Sopenharmony_ci @Component 376e41f4b71Sopenharmony_ci struct Extension { 377e41f4b71Sopenharmony_ci @State message: string = `UIExtension provider`; 378e41f4b71Sopenharmony_ci private session: UIExtensionContentSession | undefined = storage.get<UIExtensionContentSession>('session'); 379e41f4b71Sopenharmony_ci 380e41f4b71Sopenharmony_ci onPageShow() { 381e41f4b71Sopenharmony_ci console.info(TAG, 'show'); 382e41f4b71Sopenharmony_ci } 383e41f4b71Sopenharmony_ci 384e41f4b71Sopenharmony_ci build() { 385e41f4b71Sopenharmony_ci Row() { 386e41f4b71Sopenharmony_ci Column() { 387e41f4b71Sopenharmony_ci Text(this.message) 388e41f4b71Sopenharmony_ci .fontSize(30) 389e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 390e41f4b71Sopenharmony_ci .textAlign(TextAlign.Center) 391e41f4b71Sopenharmony_ci 392e41f4b71Sopenharmony_ci Button("send data") 393e41f4b71Sopenharmony_ci .width('80%') 394e41f4b71Sopenharmony_ci .type(ButtonType.Capsule) 395e41f4b71Sopenharmony_ci .margin({ top: 20 }) 396e41f4b71Sopenharmony_ci .onClick(() => { 397e41f4b71Sopenharmony_ci this.session?.sendData({ "data": 543321 }); 398e41f4b71Sopenharmony_ci }) 399e41f4b71Sopenharmony_ci 400e41f4b71Sopenharmony_ci Button("terminate self") 401e41f4b71Sopenharmony_ci .width('80%') 402e41f4b71Sopenharmony_ci .type(ButtonType.Capsule) 403e41f4b71Sopenharmony_ci .margin({ top: 20 }) 404e41f4b71Sopenharmony_ci .onClick(() => { 405e41f4b71Sopenharmony_ci this.session?.terminateSelf(); 406e41f4b71Sopenharmony_ci storage.clear(); 407e41f4b71Sopenharmony_ci }) 408e41f4b71Sopenharmony_ci 409e41f4b71Sopenharmony_ci Button("terminate self with result") 410e41f4b71Sopenharmony_ci .width('80%') 411e41f4b71Sopenharmony_ci .type(ButtonType.Capsule) 412e41f4b71Sopenharmony_ci .margin({ top: 20 }) 413e41f4b71Sopenharmony_ci .onClick(() => { 414e41f4b71Sopenharmony_ci this.session?.terminateSelfWithResult({ 415e41f4b71Sopenharmony_ci resultCode: 0, 416e41f4b71Sopenharmony_ci want: { 417e41f4b71Sopenharmony_ci bundleName: "com.example.uiextensiondemo", 418e41f4b71Sopenharmony_ci parameters: { "result": 123456 } 419e41f4b71Sopenharmony_ci } 420e41f4b71Sopenharmony_ci }) 421e41f4b71Sopenharmony_ci }) 422e41f4b71Sopenharmony_ci } 423e41f4b71Sopenharmony_ci } 424e41f4b71Sopenharmony_ci .height('100%') 425e41f4b71Sopenharmony_ci } 426e41f4b71Sopenharmony_ci } 427e41f4b71Sopenharmony_ci ``` 428e41f4b71Sopenharmony_ci 429e41f4b71Sopenharmony_ci5. Register the [UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md) in the [module.json5 file](../quick-start/module-configuration-file.md) of the module. Set **type** to that configured for the UIExtensionAbility and **srcEntry** to the code path of the UIExtensionAbility. The **extensionProcessMode** field identifies the multiton process model. Here, **bundle** is used as an example. 430e41f4b71Sopenharmony_ci 431e41f4b71Sopenharmony_ci ```json 432e41f4b71Sopenharmony_ci { 433e41f4b71Sopenharmony_ci "module": { 434e41f4b71Sopenharmony_ci "extensionAbilities": [ 435e41f4b71Sopenharmony_ci { 436e41f4b71Sopenharmony_ci "name": "UIExtensionProvider", 437e41f4b71Sopenharmony_ci "srcEntry": "./ets/uiextensionability/UIExtensionAbility.ets", 438e41f4b71Sopenharmony_ci "description": "UIExtensionAbility", 439e41f4b71Sopenharmony_ci "type": "sys/commonUI", 440e41f4b71Sopenharmony_ci "exported": true, 441e41f4b71Sopenharmony_ci "extensionProcessMode": "bundle" 442e41f4b71Sopenharmony_ci }, 443e41f4b71Sopenharmony_ci ] 444e41f4b71Sopenharmony_ci } 445e41f4b71Sopenharmony_ci } 446e41f4b71Sopenharmony_ci ``` 447e41f4b71Sopenharmony_ci## Developing the UIExtensionAbility Client 448e41f4b71Sopenharmony_ci 449e41f4b71Sopenharmony_ciYou can load the [UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md) in the application through the [UIExtensionComponent](../reference/apis-arkui/arkui-ts/ts-container-ui-extension-component-sys.md) on the [UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md) page. For example, add the following content to the home page file **pages/Index.ets**: 450e41f4b71Sopenharmony_ci 451e41f4b71Sopenharmony_ci```ts 452e41f4b71Sopenharmony_ci@Entry 453e41f4b71Sopenharmony_ci@Component 454e41f4b71Sopenharmony_cistruct Index { 455e41f4b71Sopenharmony_ci @State message: string = 'UIExtension User'; 456e41f4b71Sopenharmony_ci private myProxy: UIExtensionProxy | undefined = undefined; 457e41f4b71Sopenharmony_ci 458e41f4b71Sopenharmony_ci build() { 459e41f4b71Sopenharmony_ci Row() { 460e41f4b71Sopenharmony_ci Column() { 461e41f4b71Sopenharmony_ci Text(this.message) 462e41f4b71Sopenharmony_ci .fontSize(30) 463e41f4b71Sopenharmony_ci .size({ width: '100%', height: '50' }) 464e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 465e41f4b71Sopenharmony_ci .textAlign(TextAlign.Center) 466e41f4b71Sopenharmony_ci 467e41f4b71Sopenharmony_ci UIExtensionComponent( 468e41f4b71Sopenharmony_ci { 469e41f4b71Sopenharmony_ci bundleName: 'com.example.uiextensiondemo', 470e41f4b71Sopenharmony_ci abilityName: 'UIExtensionProvider', 471e41f4b71Sopenharmony_ci moduleName: 'entry', 472e41f4b71Sopenharmony_ci parameters: { 473e41f4b71Sopenharmony_ci 'ability.want.params.uiExtensionType': 'sys/commonUI', 474e41f4b71Sopenharmony_ci } 475e41f4b71Sopenharmony_ci }) 476e41f4b71Sopenharmony_ci .onRemoteReady((proxy) => { 477e41f4b71Sopenharmony_ci this.myProxy = proxy; 478e41f4b71Sopenharmony_ci }) 479e41f4b71Sopenharmony_ci .onReceive((data) => { 480e41f4b71Sopenharmony_ci this.message = JSON.stringify(data); 481e41f4b71Sopenharmony_ci }) 482e41f4b71Sopenharmony_ci .onResult((data) => { 483e41f4b71Sopenharmony_ci this.message = JSON.stringify(data); 484e41f4b71Sopenharmony_ci }) 485e41f4b71Sopenharmony_ci .onRelease((code) => { 486e41f4b71Sopenharmony_ci this.message = "release code:" + code; 487e41f4b71Sopenharmony_ci }) 488e41f4b71Sopenharmony_ci .offset({ x: 0, y: 30 }) 489e41f4b71Sopenharmony_ci .size({ width: 300, height: 300 }) 490e41f4b71Sopenharmony_ci .border({ width: 5, color: 0x317AF7, radius: 10, style: BorderStyle.Dotted }) 491e41f4b71Sopenharmony_ci 492e41f4b71Sopenharmony_ci Button("sendData") 493e41f4b71Sopenharmony_ci .type(ButtonType.Capsule) 494e41f4b71Sopenharmony_ci .offset({ x: 0, y: 60 }) 495e41f4b71Sopenharmony_ci .width('80%') 496e41f4b71Sopenharmony_ci .type(ButtonType.Capsule) 497e41f4b71Sopenharmony_ci .margin({ 498e41f4b71Sopenharmony_ci top: 20 499e41f4b71Sopenharmony_ci }) 500e41f4b71Sopenharmony_ci .onClick(() => { 501e41f4b71Sopenharmony_ci this.myProxy?.send({ 502e41f4b71Sopenharmony_ci "data": 123456, 503e41f4b71Sopenharmony_ci "message": "data from component" 504e41f4b71Sopenharmony_ci }) 505e41f4b71Sopenharmony_ci }) 506e41f4b71Sopenharmony_ci } 507e41f4b71Sopenharmony_ci .width('100%') 508e41f4b71Sopenharmony_ci } 509e41f4b71Sopenharmony_ci .height('100%') 510e41f4b71Sopenharmony_ci } 511e41f4b71Sopenharmony_ci} 512e41f4b71Sopenharmony_ci``` 513