1# UIExtensionComponent (系统接口) 2 3UIExtensionComponent用于支持在本页面内嵌入其他应用提供的UI。展示的内容在另外一个进程中运行,本应用并不参与其中的布局和渲染。 4 5通常用于有进程隔离诉求的模块化开发场景。 6 7> **说明:** 8> 9> 该组件从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 10> 11> 本模块为系统接口。 12 13## 使用约束 14 15本组件不支持预览。 16 17被拉起的Ability必须是带UI的Ability扩展,如何实现带UI的Ability扩展请参考[实现带UI的Ability扩展](../../apis-ability-kit/js-apis-app-ability-uiExtensionAbility.md)。 18 19必须显示设置组件宽高为非0有效值。 20 21## 子组件 22 23无 24 25## 接口 26 27UIExtensionComponent(want: Want, options?: UIExtensionOptions) 28 29**参数:** 30 31| 参数名 | 参数类型 | 必填 | 参数描述 | 32| --------------------- | ---------------------------------------------------------- | ---- | ------------------ | 33| want | [Want](../../apis-ability-kit/js-apis-app-ability-want.md) | 是 | 要加载的Ability。 | 34| options<sup>11+</sup> | [UIExtensionOptions](#uiextensionoptions11) | 否 | 需要传递的构造项。 | 35 36## 属性 37 38支持[通用属性](ts-universal-attributes-size.md)。 39 40## 事件 41 42不支持[通用事件](ts-universal-events-click.md)。 43 44将事件经过坐标转换后传递给对端Ability处理。 45 46支持以下事件: 47 48### onRemoteReady 49 50onRemoteReady(callback: [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<UIExtensionProxy>) 51 52UIExtensionAbility连接完成时的回调,之后可使用proxy向被拉起的Ability发送数据。 53 54**参数:** 55 56| 参数名 | 类型 | 说明 | 57| ---------------------------- | ------ | ------------------------------------------------------------ | 58| proxy | UIExtensionProxy | 用于向对端Ability发送数据。 | 59 60### onReceive 61 62onReceive(callback: [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<{ [key: string]: Object }>) 63 64收到被拉起的Ability发送的数据时触发的回调。 65 66**参数:** 67 68| 参数名 | 类型 | 说明 | 69| ---------------------------- | ------ | ------------------------------------------------------------ | 70| data | { [key: string]: Object } | 收到来自对端Ability的数据。 | 71 72### onResult 73 74onResult(callback: [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<{code: number; want?: Want}>) 75 76被拉起的Ability扩展调用terminateSelfWithResult时会先触发本回调函数,再触发OnRelease。 77 78本回调内可处理对端Ability的结果数据,可参考[AbilityResult](../../apis-as/js-apis-inner-ability-abilityResult.md)。 79 80**参数:** 81 82| 参数名 | 类型 | 说明 | 83| ---------------------------- | ------ | ------------------------------------------------------------ | 84| code | number | 收到来自对端Ability的处理結果code。 | 85| want | Want | 收到来自对端Ability的处理結果[Want](../../apis-ability-kit/js-apis-app-ability-want.md)。 | 86 87### onRelease 88 89onRelease(callback: [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<number>) 90 91用于处理被拉起的Ability销毁时的回调。 92 93被拉起的Ability扩展调用terminateSelfWithResult或者terminateSelf时会触发本回调,此时releaseCode为0,即正常销毁。 94 95被拉起的Ability扩展意外Crash或被kill时,触发本回调,此时releaseCode为1。 96 97**参数:** 98 99| 参数名 | 类型 | 说明 | 100| ---------------------------- | ------ | ------------------------------------------------------------ | 101| releaseCode | number | 对端Ability销毁时的code,0为正常销毁,1为异常销毁。 | 102 103### onError 104 105onError(callback:[ErrorCallback](../../apis-basic-services-kit/js-apis-base.md#errorcallback)) 106 107被拉起的Ability扩展在运行过程中发生异常时触发本回调。可通过回调参数中的code、name和message获取错误信息并做处理。 108 109**参数:** 110 111| 参数名 | 类型 | 说明 | 112| ---------------------------- | ------ | ------------------------------------------------------------ | 113| err | [BusinessError](../../apis-basic-services-kit/js-apis-base.md#businesserror) | 报错信息。 | 114 115## UIExtensionOptions<sup>11+</sup> 116用于在UIExtensionComponent进行构造的时传递可选的构造参数。 117 118**参数:** 119 120| 参数名 | 参数类型 | 必填 | 参数描述 | 121| ---- | ---------------------------------------- | ---- | --------------- | 122| isTransferringCaller | boolean | 否 | 在使用UIExtensionComponent嵌套时,设置当前UIExtensionComponent是否转发上一级的Caller信息。</br> 默认值:false。 | 123 124## UIExtensionProxy 125 126用于在双方建立连接成功后,组件使用方向被拉起的Ability发送数据、订阅和取消订阅注册。 127 128### send 129 130send(data: { [key: string]: Object }): void 131 132用于在双方建立连接成功后,组件使用方向被拉起的Ability发送数据的场景,提供异步发送数据。 133 134**系统能力:** SystemCapability.ArkUI.ArkUI.Full 135 136**参数:** 137 138| 参数名 | 参数类型 | 必填 | 参数描述 | 139| ---- | ---------------------------------------- | ---- | --------------- | 140| data | { [key: string]: Object } | 是 | 异步发送给被拉起的扩展Ability的数据。 | 141 142### sendSync<sup>11+</sup> 143 144sendSync(data: { [key: string]: Object }): { [key: string]: Object } 145 146用于在双方建立连接成功后,组件使用方向被拉起的Ability发送数据的场景,提供同步发送数据。 147 148**系统能力:** SystemCapability.ArkUI.ArkUI.Full 149 150**参数:** 151 152| 参数名 | 参数类型 | 必填 | 参数描述 | 153| ---- | ---------------------------------------- | ---- | --------------- | 154| data | { [key: string]: Object } | 是 | 同步发送给被拉起的扩展Ability的数据。 | 155 156**返回值:** 157 158| 类型 | 描述 | 159| ---- | ----| 160|{ [key: string]: Object } | 扩展Ability回复的数据。 | 161 162**错误码:** 163 164| 错误号 | 描述 | 165| ---- | ----| 166| 100011 | 扩展Ability未注册同步回调 | 167| 100012 | 数据发送失败 | 168 169### on('asyncReceiverRegister')<sup>11+</sup> 170 171on(type: 'asyncReceiverRegister', callback: (proxy: UIExtensionProxy) => void): void 172 173用于在双方建立连接成功后,组件使用方订阅被拉起的Ability发生异步注册的场景。 174 175**系统能力:** SystemCapability.ArkUI.ArkUI.Full 176 177**参数:** 178 179| 参数名 | 参数类型 |必填 | 参数描述 | 180| ------ | -------- |---- | ------- | 181| type | string | 是 | 代表订阅扩展Ability发生异步注册回调。 | 182| callback | (proxy: UIExtensionProxy) => void | 是 | 订阅扩展Ability注册setReceiveDataCallback后触发的回调。 | 183 184### on('syncReceiverRegister')<sup>11+</sup> 185 186on(type: 'syncReceiverRegister', callback: (proxy: UIExtensionProxy) => void): void 187 188用于在双方建立连接成功后,组件使用方订阅被拉起的Ability发生同步注册的场景。 189 190**系统能力:** SystemCapability.ArkUI.ArkUI.Full 191 192**参数:** 193 194| 参数名 | 参数类型 |必填 | 参数描述 | 195| ------ | -------- |---- | ------- | 196| type | string | 是 | 订阅扩展Ability发生同步注册回调。 | 197| callback | (proxy: UIExtensionProxy) => void | 是 | 扩展Ability注册setReceiveDataForResultCallback后触发的回调。 | 198 199### off('asyncReceiverRegister')<sup>11+</sup> 200 201off(type: 'asyncReceiverRegister', callback?: (proxy: UIExtensionProxy) => void): void 202 203用于在双方建立连接成功后,组件使用方取消订阅被拉起的Ability发生异步注册的场景。 204 205**系统能力:** SystemCapability.ArkUI.ArkUI.Full 206 207**参数:** 208 209| 参数名 | 参数类型 | 必填 | 参数描述 | 210| ------ | -------- | ----- | ------- | 211| type | string | 是 | 取消订阅扩展Ability发生异步注册回调。 | 212| callback | (proxy: UIExtensionProxy) => void | 否 | 为空代表取消订阅所有扩展Ability异步注册后触发回调。<br> 非空代表取消订阅异步对应回调。 | 213 214### off('syncReceiverRegister')<sup>11+</sup> 215 216off(type: 'syncReceiverRegister', callback?: (proxy: UIExtensionProxy) => void): void 217 218用于在双方建立连接成功后,组件使用方取消订阅被拉起的Ability发生同步注册的场景。 219 220**系统能力:** SystemCapability.ArkUI.ArkUI.Full 221 222**参数:** 223 224| 参数名 | 参数类型 | 必填 | 参数描述 | 225| ------ | -------- | ----- | ------- | 226| type | string | 是 | 取消订阅扩展Ability发生同步注册回调。 | 227| callback | (proxy: UIExtensionProxy) => void | 否 | 为空代表取消订阅所有扩展Ability同步注册后触发回调<br> 非空代表取消订阅同步对应回调。 | 228 229## 示例 230 231本示例仅展示组件使用的方法和扩展的Ability,实际运行需在设备中安装bundleName为"com.example.uiextensionprovider",abilityName为"UIExtensionProvider"的Ability扩展。 232 233```ts 234// 组件使用示例: 235@Entry 236@Component 237struct Second { 238 @State message1: string = 'Hello World 1' 239 @State message2: string = 'Hello World 2' 240 @State message3: string = 'Hello World 3' 241 @State visible: Visibility = Visibility.Hidden 242 @State wid: number = 300 243 @State hei: number = 300 244 private proxy: UIExtensionProxy | null = null; 245 246 247 build() { 248 Row() { 249 Column() { 250 Text(this.message1).fontSize(30) 251 Text(this.message2).fontSize(30) 252 Text(this.message3).fontSize(30) 253 UIExtensionComponent({ 254 bundleName : "com.example.newdemo", 255 abilityName: "UIExtensionProvider", 256 parameters: { 257 "ability.want.params.uiExtensionType": "dialog" 258 } 259 }) 260 .width(this.wid) 261 .height(this.hei) 262 .border({width: 5, color: Color.Blue}) 263 .onResult((data)=>{ 264 this.message1 = data['want'] ? JSON.stringify(data['want']['bundleName']) : ""; 265 }) 266 .onRelease((code)=>{ 267 this.message2 = "release code : " + code 268 }) 269 .onReceive((data) => { 270 console.info('Lee onReceive, for test') 271 this.message3 = JSON.stringify(data['data']) 272 }) 273 .onRemoteReady((proxy) => { 274 console.info('onRemoteReady, for test') 275 this.proxy = proxy 276 277 this.proxy.on("syncReceiverRegister", syncRegisterCallback1); 278 // this.proxy.on("syncReceiverRegister", syncRegisterCallback2); 279 280 281 // this.proxy.off("syncReceiverRegister"); 282 283 // this.proxy.off("syncReceiverRegister", (proxy) => { 284 // console.info("off invoke for test, type is syncReceiverRegister"); 285 // }); 286 287 this.proxy.on("asyncReceiverRegister", (proxy1) => { 288 console.info("on invoke for test, type is asyncReceiverRegister"); 289 }); 290 // 291 // this.proxy.off("asyncReceiverRegister"); 292 }) 293 294 Button("点击向UIExtensionAbility发送数据").onClick(() => { 295 if (this.proxy != undefined) { 296 this.proxy.send({data: "你好1"}) 297 298 try { 299 let re = this.proxy.sendSync({data: "你好2"}) 300 console.info("for test, re=" + JSON.stringify(re)); 301 } catch (err) { 302 console.error(`sendSync failed for test. errCode=${err.code}, msg=${err.message}`); 303 } 304 } 305 }) 306 } 307 .width('100%') 308 } 309 .height('100%') 310 } 311} 312 313function syncRegisterCallback1(proxy: UIExtensionProxy) { 314 console.info("on invoke for test, syncRegisterCallback1, type is syncReceiverRegister"); 315} 316 317function syncRegisterCallback2(proxy: UIExtensionProxy) { 318 console.info("on invoke for test, syncRegisterCallback2, type is syncReceiverRegister"); 319} 320``` 321 322```ts 323// 扩展入口文件UIExtensionProvider.ts 324import UIExtensionAbility from '@ohos.app.ability.UIExtensionAbility' 325import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession' 326import Want from '@ohos.app.ability.Want'; 327const TAG: string = '[UIExtAbility]' 328export default class UIExtAbility extends UIExtensionAbility { 329 330 onCreate() { 331 console.log(TAG, `UIExtAbility onCreate`) 332 } 333 334 onForeground() { 335 console.log(TAG, `UIExtAbility onForeground`) 336 } 337 338 onBackground() { 339 console.log(TAG, `UIExtAbility onBackground`) 340 } 341 342 onDestroy() { 343 console.log(TAG, `UIExtAbility onDestroy`) 344 } 345 346 onSessionCreate(want: Want, session: UIExtensionContentSession) { 347 console.log(TAG, `UIExtAbility onSessionCreate, want: ${JSON.stringify(want)}`) 348 let param: Record<string, UIExtensionContentSession> = { 349 'session': session 350 }; 351 let storage: LocalStorage = new LocalStorage(param); 352 session.loadContent('pages/extension', storage); 353 } 354 355 onSessionDestroy(session: UIExtensionContentSession) { 356 console.log(TAG, `UIExtAbility onSessionDestroy`) 357 } 358} 359``` 360 361```ts 362// 扩展Ability入口页面文件extension.ets 363import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession'; 364import router from '@ohos.router'; 365 366let storage = LocalStorage.getShared() 367AppStorage.setOrCreate('message', 'UIExtensionAbility') 368 369@Entry(storage) 370@Component 371struct Extension { 372 @StorageLink('message') storageLink: string = ''; 373 private session: UIExtensionContentSession | undefined = storage.get<UIExtensionContentSession>('session'); 374 375 onPageShow() { 376 if (this.session != undefined) { 377 this.session.setReceiveDataCallback((data)=> { 378 this.storageLink = JSON.stringify(data) 379 console.info("invoke for test, handle callback set by setReceiveDataCallback successfully"); 380 }) 381 382 this.session.setReceiveDataForResultCallback(func1) 383 } 384 } 385 386 build() { 387 Row() { 388 Column() { 389 Text(this.storageLink) 390 .fontSize(20) 391 .fontWeight(FontWeight.Bold) 392 Button("点击向Component发送数据").onClick(()=>{ 393 if (this.session != undefined) { 394 this.session.sendData({"data": 543321}) 395 console.info('send 543321, for test') 396 } 397 }) 398 Button("terminate").onClick(()=> { 399 if (this.session != undefined) { 400 this.session.terminateSelf(); 401 } 402 storage.clear() 403 }) 404 Button("terminate with result").onClick(()=>{ 405 if (this.session != undefined) { 406 this.session.terminateSelfWithResult({ 407 resultCode: 0, 408 want: { 409 bundleName: "myBundleName", 410 parameters: { "result": 123456 } 411 } 412 }) 413 } 414 storage.clear() 415 }) 416 417 Button("点击跳转").onClick(()=> { 418 router.pushUrl({url: 'pages/hello'}) 419 }) 420 } 421 } 422 .height('100%') 423 } 424} 425function func1(data: Record<string, Object>): Record<string, Object> { 426 let linkToMsg: SubscribedAbstractProperty<string> = AppStorage.link('message'); 427 linkToMsg.set(JSON.stringify(data)) 428 console.info("invoke for test, handle callback set by setReceiveDataForResultCallback successfully"); 429 return data; 430} 431 432``` 433