1# UIExtensionAbility 2 3## 概述 4 5[UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md)是UI类型的ExtensionAbility,常用于有进程隔离诉求的系统弹窗、状态栏、胶囊等模块化开发的场景。有嵌入式显示与系统弹窗两种形式。 6- 嵌入式显示启动需要与[UIExtensionComponent](../reference/apis-arkui/arkui-ts/ts-container-ui-extension-component-sys.md)一起配合使用,开发者可以在UIAbility的页面中通过UIExtensionComponent嵌入提供方应用的UIExtensionAbility提供的UI。UIExtensionAbility会在独立于UIAbility的进程中运行,完成其页面的布局和渲染。 7- 系统弹窗启动形式需要调用指定接口[requestModalUIExtensionAbility](../reference/apis-ability-kit/js-apis-inner-application-serviceExtensionContext-sys.md#serviceextensioncontextrequestmodaluiextension11)或调用应用封装的指定接口启动UIExtensionAbility。 8 9## 约束限制 10- 当前"sys/commonUI"、"sysDialog"和"sysPicker"类型的UIExtensionAbility仅支持系统应用使用,更详细的UIExtensionAbility类型介绍及对应权限管控可参见:[module.json5配置文件](../quick-start/module-configuration-file.md)。 11- UIExtensionAbility仅支持拥有前台窗口的应用拉起,处于后台运行的应用无法拉起UIExtensionAbility。 12 13## 生命周期 14[UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md)提供了[onCreate](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#oncreate)、[onSessionCreate](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#onsessioncreate)、[onSessionDestroy](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#onsessiondestroy)、[onForeground](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#onforeground)、[onBackground](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#onbackground)和[onDestroy](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#ondestroy)生命周期回调,根据需要重写对应的回调方法。 15 16- **onCreate**:当UIExtensionAbility创建时回调,执行初始化业务逻辑操作。 17- **onSessionCreate**:当UIExtensionAbility界面内容对象创建后调用。 18- **onSessionDestroy**:当UIExtensionAbility界面内容对象销毁后调用。 19- **onForeground**:当UIExtensionAbility从后台转到前台时触发。 20- **onBackground**:当UIExtensionAbility从前台转到后台时触发。 21- **onDestroy**:当UIExtensionAbility销毁时回调,可以执行资源清理等操作。 22 23## 选择合适的UIExtensionAbility进程模型 24[UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md)支持多实例,每个嵌入式显示对应一个UIExtensionAbility实例。多实例场景下默认是多进程,可配置多进程模型。 25当应用中存在多个UIExtensionAbility实例,这些实例可以为多个独立进程,也可以共用同一个进程,还可以分为多组、同组实例共用同一个进程。通过[module.json5](../quick-start/module-configuration-file.md)配置文件中的extensionProcessMode字段,即可为选择对应的进程模型,三种模型对比如下: 26| 进程模型 | extensionProcessMode字段配置 | 说明 | 27| --------| --------| --------| 28| 同一bundle中所有UIExtensionAbility共进程 |bundle| UIExtensionAbility实例之间的通信无需跨IPC通信;实例之间的状态不独立,会存在相互影响。| 29| 相同name的UIExtensionAbility共进程 | type |将同UIExtensionAbility类配置在同一个进程下,便于应用针对UIExtensionAbility类型对实例进行管理。| 30| 每个UIExtensionAbility为独立进程 | instance | UIExtensionAbility实例之间的状态不会彼此影响,安全性更高;实例之间只能通过跨进程进行通信。 | 31### Bundle中的所有UIExtensionAbility共进程 32同一个bundle下的[UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md)配置在同一个进程中,便于多实例间的通信。需要关注的是,各个实例之间的状态会彼此影响,当进程中的一个实例异常退出,将导致进程中所有的实例也都会退出。 33 34**图1** bundle模型配置示意图 35 36 37 38**Index.ets示例代码如下:** 39```ts 40import { BusinessError } from '@kit.BasicServicesKit'; 41 42@Entry 43@Component 44struct Index { 45 @State message: string = 'UIExtension UserA'; 46 private myProxy: UIExtensionProxy | undefined = undefined; 47 48 build() { 49 Row() { 50 Column() { 51 Text(this.message) 52 .fontSize(30) 53 .size({ width: '100%', height: '50' }) 54 .fontWeight(FontWeight.Bold) 55 .textAlign(TextAlign.Center) 56 57 UIExtensionComponent( 58 { 59 bundleName: 'com.samples.uiextensionability', 60 abilityName: 'UIExtensionProvider', 61 moduleName: 'entry', 62 parameters: { 63 'ability.want.params.uiExtensionType': 'sys/commonUI', 64 } 65 }) 66 .onRemoteReady((proxy) => { 67 this.myProxy = proxy; 68 }) 69 .onReceive((data) => { 70 this.message = JSON.stringify(data); 71 }) 72 .onTerminated((terminateInfo: TerminationInfo) => { 73 // 被拉起的UIExtensionAbility通过调用terminateSelfWithResult或者terminateSelf正常退出时,触发本回调函数。 74 // 回调返回UIExtensionAbility正常退出时的返回结果,包含结果码code和Want数据。 75 this.message = `terminate code: ${terminateInfo.code}, want: ${terminateInfo.want}`; 76 }) 77 .onError((error: BusinessError) => { 78 // 被拉起的UIExtensionAbility在运行过程中发生异常时,触发本回调函数。 79 // 回调返回UIExtensionAbility发生异常时返回的错误码和错误信息。 80 this.message = `error code: ${error.code}, error msg: ${error.message}`; 81 }) 82 .offset({ x: 0, y: 10 }) 83 .size({ width: 300, height: 300 }) 84 .border({ 85 width: 5, 86 color: 0x317AF7, 87 radius: 10, 88 style: BorderStyle.Dotted 89 }) 90 91 UIExtensionComponent( 92 { 93 bundleName: 'com.samples.uiextension2', 94 abilityName: 'UIExtensionProviderB', 95 moduleName: 'entry', 96 parameters: { 97 'ability.want.params.uiExtensionType': 'sys/commonUI', 98 } 99 }) 100 .onRemoteReady((proxy) => { 101 this.myProxy = proxy; 102 }) 103 .onReceive((data) => { 104 this.message = JSON.stringify(data); 105 }) 106 .onTerminated((terminateInfo: TerminationInfo) => { 107 // 被拉起的UIExtensionAbility通过调用terminateSelfWithResult或者terminateSelf正常退出时,触发本回调函数。 108 // 回调返回UIExtensionAbility正常退出时的返回结果,包含结果码code和Want数据。 109 this.message = `terminate code: ${terminateInfo.code}, want: ${terminateInfo.want}`; 110 }) 111 .onError((error: BusinessError) => { 112 // 被拉起的UIExtensionAbility在运行过程中发生异常时,触发本回调函数。 113 // 回调返回UIExtensionAbility发生异常时返回的错误码和错误信息。 114 this.message = `error code: ${error.code}, error msg: ${error.message}`; 115 }) 116 .offset({ x: 0, y: 50 }) 117 .size({ width: 300, height: 300 }) 118 .border({ 119 width: 5, 120 color: 0x317AF7, 121 radius: 10, 122 style: BorderStyle.Dotted 123 }) 124 } 125 .width('100%') 126 } 127 .height('100%') 128 } 129} 130``` 131**图2** 根据上述代码,生成的Index页面如下: 132 133 134 135采用该进程模型,进程名格式为: 136process name [{bundleName}:{UIExtensionAbility的类型}] 137例如,process name [com.ohos.intentexecutedemo:xxx]。 138 139**图3** 进程模型展示 140 141 142 143### 同UIExtensionAbility类的所有UIExtensionAbility共进程 144根据[UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md)类进行分配进程,拉起多个同样的UIExtensionAbility实例时,这些实例将配置在同一个进程中。将同UIExtensionAbility类配置在同一个进程下,方便应用针对UIExtensionAbility类型对实例进行管理。 145 146**图4** type模型配置示意图 147 148 149 150**Index.ets示例代码如下:** 151```ts 152import { BusinessError } from '@kit.BasicServicesKit'; 153 154@Entry 155@Component 156struct Index { 157 @State message: string = 'UIExtension User'; 158 private myProxy: UIExtensionProxy | undefined = undefined; 159 160 build() { 161 Row() { 162 Column() { 163 Text(this.message) 164 .fontSize(30) 165 .size({ width: '100%', height: '50' }) 166 .fontWeight(FontWeight.Bold) 167 .textAlign(TextAlign.Center) 168 169 UIExtensionComponent( 170 { 171 bundleName: 'com.samples.uiextensionability', 172 abilityName: 'UIExtensionProviderA', 173 moduleName: 'entry', 174 parameters: { 175 'ability.want.params.uiExtensionType': 'sys/commonUI', 176 } 177 }) 178 .onRemoteReady((proxy) => { 179 this.myProxy = proxy; 180 }) 181 .onReceive((data) => { 182 this.message = JSON.stringify(data); 183 }) 184 .onTerminated((terminateInfo: TerminationInfo) => { 185 // 被拉起的UIExtensionAbility通过调用terminateSelfWithResult或者terminateSelf正常退出时,触发本回调函数。 186 // 回调返回UIExtensionAbility正常退出时的返回结果,包含结果码code和Want数据。 187 this.message = `terminate code: ${terminateInfo.code}, want: ${terminateInfo.want}`; 188 }) 189 .onError((error: BusinessError) => { 190 // 被拉起的UIExtensionAbility在运行过程中发生异常时,触发本回调函数。 191 // 回调返回UIExtensionAbility发生异常时返回的错误码和错误信息。 192 this.message = `error code: ${error.code}, error msg: ${error.message}`; 193 }) 194 .offset({ x: 0, y: 10 }) 195 .size({ width: 300, height: 300 }) 196 .border({ 197 width: 5, 198 color: 0x317AF7, 199 radius: 10, 200 style: BorderStyle.Dotted 201 }) 202 203 UIExtensionComponent( 204 { 205 bundleName: 'com.samples.uiextensionability', 206 abilityName: 'UIExtensionProviderB', 207 moduleName: 'entry', 208 parameters: { 209 'ability.want.params.uiExtensionType': 'sys/commonUI', 210 } 211 }) 212 .onRemoteReady((proxy) => { 213 this.myProxy = proxy; 214 }) 215 .onReceive((data) => { 216 this.message = JSON.stringify(data); 217 }) 218 .onTerminated((terminateInfo: TerminationInfo) => { 219 // 被拉起的UIExtensionAbility通过调用terminateSelfWithResult或者terminateSelf正常退出时,触发本回调函数。 220 // 回调返回UIExtensionAbility正常退出时的返回结果,包含结果码code和Want数据。 221 this.message = `terminate code: ${terminateInfo.code}, want: ${terminateInfo.want}`; 222 }) 223 .onError((error: BusinessError) => { 224 // 被拉起的UIExtensionAbility在运行过程中发生异常时,触发本回调函数。 225 // 回调返回UIExtensionAbility发生异常时返回的错误码和错误信息。 226 this.message = `error code: ${error.code}, error msg: ${error.message}`; 227 }) 228 .offset({ x: 0, y: 50 }) 229 .size({ width: 300, height: 300 }) 230 .border({ 231 width: 5, 232 color: 0x317AF7, 233 radius: 10, 234 style: BorderStyle.Dotted 235 }) 236 } 237 .width('100%') 238 } 239 .height('100%') 240 } 241} 242``` 243**图5** 根据上述代码,生成的Index页面如下: 244 245 246 247采用该进程模型,进程名格式为: 248process name [{bundleName}:{UIExtensionAbility名}] 249例如,process name [com.ohos.intentexecutedemo:xxx]。 250 251**图6** 进程模型展示 252 253 254 255### UIExtensionAbility实例独立进程 256根据[UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md)实例进行分配进程,配置了instance的UIExtensionAbility实例,将每个实例独立一个进程。独立进程的场景下,UIExtensionAbility实例之间只能通过跨进程进行通信,但实例之间的状态不会彼此影响,安全性更高。 257 258**图7** instance模型配置示意图 259 260 261 262 263**Index.ets示例代码如下:** 264```ts 265import { BusinessError } from '@kit.BasicServicesKit'; 266 267@Entry 268@Component 269struct Index { 270 @State message: string = 'UIExtension User' 271 private myProxy: UIExtensionProxy | undefined = undefined; 272 273 build() { 274 Row() { 275 Column() { 276 Text(this.message) 277 .fontSize(30) 278 .size({ width: '100%', height: '50' }) 279 .fontWeight(FontWeight.Bold) 280 .textAlign(TextAlign.Center) 281 282 UIExtensionComponent( 283 { 284 bundleName: 'com.samples.uiextensionability', 285 abilityName: 'UIExtensionProvider', 286 moduleName: 'entry', 287 parameters: { 288 'ability.want.params.uiExtensionType': 'sys/commonUI', 289 } 290 }) 291 .onRemoteReady((proxy) => { 292 this.myProxy = proxy; 293 }) 294 .onReceive((data) => { 295 this.message = JSON.stringify(data); 296 }) 297 .onTerminated((terminateInfo: TerminationInfo) => { 298 // 被拉起的UIExtensionAbility通过调用terminateSelfWithResult或者terminateSelf正常退出时,触发本回调函数。 299 // 回调返回UIExtensionAbility正常退出时的返回结果,包含结果码code和Want数据。 300 this.message = `terminate code: ${terminateInfo.code}, want: ${terminateInfo.want}`; 301 }) 302 .onError((error: BusinessError) => { 303 // 被拉起的UIExtensionAbility在运行过程中发生异常时,触发本回调函数。 304 // 回调返回UIExtensionAbility发生异常时返回的错误码和错误信息。 305 this.message = `error code: ${error.code}, error msg: ${error.message}`; 306 }) 307 .offset({ x: 0, y: 10 }) 308 .size({ width: 300, height: 300 }) 309 .border({ 310 width: 5, 311 color: 0x317AF7, 312 radius: 10, 313 style: BorderStyle.Dotted 314 }) 315 316 UIExtensionComponent( 317 { 318 bundleName: 'com.samples.uiextensionability', 319 abilityName: 'UIExtensionProvider', 320 moduleName: 'entry', 321 parameters: { 322 'ability.want.params.uiExtensionType': 'sys/commonUI', 323 } 324 }) 325 .onRemoteReady((proxy) => { 326 this.myProxy = proxy; 327 }) 328 .onReceive((data) => { 329 this.message = JSON.stringify(data); 330 }) 331 .onTerminated((terminateInfo: TerminationInfo) => { 332 // 被拉起的UIExtensionAbility通过调用terminateSelfWithResult或者terminateSelf正常退出时,触发本回调函数。 333 // 回调返回UIExtensionAbility正常退出时的返回结果,包含结果码code和Want数据。 334 this.message = `terminate code: ${terminateInfo.code}, want: ${terminateInfo.want}`; 335 }) 336 .onError((error: BusinessError) => { 337 // 被拉起的UIExtensionAbility在运行过程中发生异常时,触发本回调函数。 338 // 回调返回UIExtensionAbility发生异常时返回的错误码和错误信息。 339 this.message = `error code: ${error.code}, error msg: ${error.message}`; 340 }) 341 .offset({ x: 0, y: 50 }) 342 .size({ width: 300, height: 300 }) 343 .border({ 344 width: 5, 345 color: 0x317AF7, 346 radius: 10, 347 style: BorderStyle.Dotted 348 }) 349 } 350 .width('100%') 351 } 352 .height('100%') 353 } 354} 355``` 356**图8** 根据上述代码,生成的Index页面如下: 357 358 359 360采用该进程模型,进程名格式为: 361process name [{bundleName}:{UIExtensionAbility的类型}: {实例后缀}] 362例如,process name [com.ohos.intentexecutedemo:xxx:n]。 363 364**图9** 进程模型展示 365 366 367 368UIExtensionAbility通过[UIExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-uiExtensionContext.md)和[UIExtensionContentSession](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionContentSession.md)提供相关能力。本文描述中称被启动的UIExtensionAbility为提供方,称启动UIExtensionAbility的[UIExtensionComponent](../reference/apis-arkui/arkui-ts/ts-container-ui-extension-component-sys.md)组件为使用方。 369 370## 开发步骤 371 372为了便于表述,本例中将提供[UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md)能力的一方称为提供方,将启动UIExtensionAbility的一方称为使用方,本例中使用方通过[UIExtensionComponent](../reference/apis-arkui/arkui-ts/ts-container-ui-extension-component-sys.md)容器启动UIExtensionAbility。系统弹框形式的使用方开发示例可参考文档:[requestModalUIExtension](../reference/apis-ability-kit/js-apis-inner-application-serviceExtensionContext-sys.md#serviceextensioncontextrequestmodaluiextension11)。 373 374### 开发UIExtensionAbility提供方 375 376开发者在实现一个[UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md)提供方时,需要在DevEco Studio工程中手动新建一个UIExtensionAbility,具体步骤如下。 377 3781. 在工程Module对应的ets目录下,右键选择“New > Directory”,新建一个目录并命名为uiextensionability。 379 3802. 在uiextensionability目录,右键选择“New > File”,新建一个.ets文件并命名为UIExtensionAbility.ets。 381 3823. 打开UIExtensionAbility.ets,导入UIExtensionAbility的依赖包,自定义类继承UIExtensionAbility并实现[onCreate](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#oncreate)、[onSessionCreate](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#onsessioncreate)、[onSessionDestroy](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#onsessiondestroy)、[onForeground](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#onforeground)、[onBackground](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#onbackground)和[onDestroy](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#ondestroy)生命周期回调。 383 384 ```ts 385 import { Want, UIExtensionAbility, UIExtensionContentSession } from '@kit.AbilityKit'; 386 387 const TAG: string = '[testTag] UIExtAbility'; 388 389 export default class UIExtAbility extends UIExtensionAbility { 390 onCreate() { 391 console.log(TAG, `onCreate`); 392 } 393 394 onForeground() { 395 console.log(TAG, `onForeground`); 396 } 397 398 onBackground() { 399 console.log(TAG, `onBackground`); 400 } 401 402 onDestroy() { 403 console.log(TAG, `onDestroy`); 404 } 405 406 onSessionCreate(want: Want, session: UIExtensionContentSession) { 407 console.log(TAG, `onSessionCreate, want: ${JSON.stringify(want)}}`); 408 let storage: LocalStorage = new LocalStorage(); 409 storage.setOrCreate('session', session); 410 session.loadContent('pages/Extension', storage); 411 } 412 413 onSessionDestroy(session: UIExtensionContentSession) { 414 console.log(TAG, `onSessionDestroy`); 415 } 416 } 417 ``` 418 4194. [UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md)的[onSessionCreate](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md#onsessioncreate)中加载了入口页面文件pages/extension.ets, 并在entry\src\main\resources\base\profile\main_pages.json文件中添加"pages/Extension"声明,extension.ets内容如下。 420 421 ```ts 422 import { UIExtensionContentSession } from '@kit.AbilityKit'; 423 424 const TAG: string = `[testTag] ExtensionPage`; 425 426 @Entry() 427 @Component 428 struct Extension { 429 @State message: string = `UIExtension provider`; 430 localStorage: LocalStorage | undefined = this.getUIContext().getSharedLocalStorage(); 431 private session: UIExtensionContentSession | undefined = this.localStorage?.get<UIExtensionContentSession>('session'); 432 433 onPageShow() { 434 console.info(TAG, 'show'); 435 } 436 437 build() { 438 Row() { 439 Column() { 440 Text(this.message) 441 .fontSize(30) 442 .fontWeight(FontWeight.Bold) 443 .textAlign(TextAlign.Center) 444 445 Button("send data") 446 .width('80%') 447 .type(ButtonType.Capsule) 448 .margin({ top: 20 }) 449 .onClick(() => { 450 this.session?.sendData({ "data": 543321 }); 451 }) 452 453 Button("terminate self") 454 .width('80%') 455 .type(ButtonType.Capsule) 456 .margin({ top: 20 }) 457 .onClick(() => { 458 this.session?.terminateSelf(); 459 this.localStorage?.clear(); 460 }) 461 462 Button("terminate self with result") 463 .width('80%') 464 .type(ButtonType.Capsule) 465 .margin({ top: 20 }) 466 .onClick(() => { 467 this.session?.terminateSelfWithResult({ 468 resultCode: 0, 469 want: { 470 bundleName: "com.example.uiextensiondemo", 471 parameters: { "result": 123456 } 472 } 473 }) 474 }) 475 } 476 } 477 .height('100%') 478 } 479 } 480 ``` 481 4825. 在工程Module对应的[module.json5配置文件](../quick-start/module-configuration-file.md)中注册[UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md),type标签需要设置为UIExtensionAbility中配置的对应类型,srcEntry标签表示当前UIExtensionAbility组件所对应的代码路径。extensionProcessMode标签标识多实例的进程模型,此处以"bundle"为例。 483 484 ```json 485 { 486 "module": { 487 "extensionAbilities": [ 488 { 489 "name": "UIExtensionProvider", 490 "srcEntry": "./ets/uiextensionability/UIExtensionAbility.ets", 491 "description": "UIExtensionAbility", 492 "type": "sys/commonUI", 493 "exported": true, 494 "extensionProcessMode": "bundle" 495 }, 496 ] 497 } 498 } 499 ``` 500## 开发UIExtensionAbility使用方 501 502开发者可以在[UIAbility](../reference/apis-ability-kit/js-apis-app-ability-uiAbility.md)的页面中通过[UIExtensionComponent](../reference/apis-arkui/arkui-ts/ts-container-ui-extension-component-sys.md)容器加载自己应用内的[UIExtensionAbility](../reference/apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md)。 503如在首页文件:pages/Index.ets中添加如下内容。 504 505```ts 506import { BusinessError } from '@kit.BasicServicesKit'; 507 508@Entry 509@Component 510struct Index { 511 @State message: string = 'UIExtension User'; 512 private myProxy: UIExtensionProxy | undefined = undefined; 513 514 build() { 515 Row() { 516 Column() { 517 Text(this.message) 518 .fontSize(30) 519 .size({ width: '100%', height: '50' }) 520 .fontWeight(FontWeight.Bold) 521 .textAlign(TextAlign.Center) 522 523 UIExtensionComponent( 524 { 525 bundleName: 'com.example.uiextensiondemo', 526 abilityName: 'UIExtensionProvider', 527 moduleName: 'entry', 528 parameters: { 529 'ability.want.params.uiExtensionType': 'sys/commonUI', 530 } 531 }) 532 .onRemoteReady((proxy) => { 533 this.myProxy = proxy; 534 }) 535 .onReceive((data) => { 536 this.message = JSON.stringify(data); 537 }) 538 .onTerminated((terminateInfo: TerminationInfo) => { 539 // 被拉起的UIExtensionAbility通过调用terminateSelfWithResult或者terminateSelf正常退出时,触发本回调函数。 540 // 回调返回UIExtensionAbility正常退出时的返回结果,包含结果码code和Want数据。 541 this.message = `terminate code: ${terminateInfo.code}, want: ${terminateInfo.want}`; 542 }) 543 .onError((error: BusinessError) => { 544 // 被拉起的UIExtensionAbility在运行过程中发生异常时,触发本回调函数。 545 // 回调返回UIExtensionAbility发生异常时返回的错误码和错误信息。 546 this.message = `error code: ${error.code}, error msg: ${error.message}`; 547 }) 548 .offset({ x: 0, y: 30 }) 549 .size({ width: 300, height: 300 }) 550 .border({ 551 width: 5, 552 color: 0x317AF7, 553 radius: 10, 554 style: BorderStyle.Dotted 555 }) 556 557 Button("sendData") 558 .type(ButtonType.Capsule) 559 .offset({ x: 0, y: 60 }) 560 .width('80%') 561 .type(ButtonType.Capsule) 562 .margin({ 563 top: 20 564 }) 565 .onClick(() => { 566 this.myProxy?.send({ 567 "data": 123456, 568 "message": "data from component" 569 }) 570 }) 571 } 572 .width('100%') 573 } 574 .height('100%') 575 } 576} 577```