1# 使用通过UIServiceExtensionAbility实现的系统悬浮窗 2 3<!--Kit: Ability Kit--> 4<!--Subsystem: Ability--> 5<!--Owner: @zhangyafei-echo--> 6<!--Designer: @li-weifeng2--> 7<!--Tester: @lixueqing513--> 8<!--Adviser: @huipeizi--> 9 10## 概述 11 12UIServiceExtensionAbility组件是带用户界面(UI)的扩展服务组件。系统应用可以通过UIServiceExtensionAbility组件实现一个具有特定功能、带UI的服务能力,并将其UI服务开放给其他三方应用调用。 13 14本文描述中称被启动的UIServiceExtensionAbility组件为服务端,称UIServiceExtensionAbility组件的启动方为客户端。 15 16应用可以通过启动和连接两种形式使用UIServiceExtensionAbility组件: 17- 通过[UIExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-uiExtensionContext.md)调用[startUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#startuiserviceextensionability14)方法启动UIServiceExtensionAbility。 18- 通过[UIAbilityContext](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md)、[UIExtensionContext](../reference/apis-ability-kit/js-apis-inner-application-uiExtensionContext.md)调用[connectUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#connectuiserviceextensionability14)方法连接UIServiceExtensionAbility。 19 20## 约束限制 21 22- 当前仅支持2in1设备。 23 24- 三方应用需要在前台获焦的情况下才能连接系统提供的UIServiceExtensionAbility组件。 25 26- UIServiceExtensionAbility组件的生命周期与绑定的窗口强关联,窗口销毁后UIServiceExtensionAbility组件也一起销毁。 27 28 29## 启动UIServiceExtensionAbility组件 30 31应用通过[startUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#startuiserviceextensionability14)方法启动一个UIServiceExtensionAbility组件。UIServiceExtensionAbility组件启动后,其生命周期独立于客户端,即使客户端已经销毁,该后台服务仍可继续运行,窗口创建失败或销毁后该服务会被销毁。 32 33 34如下示例通过startUIServiceExtensionAbility方法启动一个UIServiceExtensionAbility组件,示例中的context的获取方式请参见[获取UIAbility的上下文信息](uiability-usage.md#获取uiability的上下文信息)。 35 36```ts 37import { common, Want } from '@kit.AbilityKit'; 38import { BusinessError } from '@kit.BasicServicesKit'; 39 40@Entry 41@Component 42struct Index { 43 build() { 44 Column() { 45 Row() { 46 // 创建启动按钮 47 Button('start UIServiceExtensionAbility') 48 .enabled(true) 49 .onClick(() => { 50 let context = this.getUIContext().getHostContext() as common.UIAbilityContext; 51 let startWant: Want = { 52 bundleName: 'com.acts.uiserviceextensionability', // 仅作为示例代码,需要替换为实际的UIServiceExtensionAbility组件的包名。 53 abilityName: 'UiServiceExtAbility', // 仅作为示例代码,需要替换为实际的UIServiceExtensionAbility组件名称。 54 }; 55 try { 56 // 启动UIServiceExtensionAbility组件 57 context.startUIServiceExtensionAbility(startWant).then(() => { 58 console.info('startUIServiceExtensionAbility success.'); 59 }).catch((error: BusinessError) => { 60 console.error(`startUIServiceExtensionAbility failed, err code: ${error.code}, err msg: ${error.message}.`); 61 }); 62 } catch (err) { 63 let code = (err as BusinessError).code; 64 let msg = (err as BusinessError).message; 65 console.error(`startUIServiceExtensionAbility failed, err code: ${code}, err msg: ${msg}.`); 66 } 67 }) 68 } 69 } 70 } 71} 72``` 73 74## 客户端连接服务端 75 76 客户端通过[connectUIServiceExtensionAbility()](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#connectuiserviceextensionability14)连接服务端,获取并保存[UIServiceProxy](../reference/apis-ability-kit/js-apis-inner-application-uiserviceproxy.md)对象。通过该proxy对象的[sendData()](../reference/apis-ability-kit/js-apis-inner-application-uiserviceproxy.md#uiserviceproxysenddata)方法发送数据给服务端。服务端通过UIServiceExtensionAbility类onData()(系统接口)方法接收客户端数据。 77 78如下示例通过connectUIServiceExtensionAbility方法连接一个UIServiceExtensionAbility组件,示例中的context的获取方式请参见[获取UIAbility的上下文信息](uiability-usage.md#获取uiability的上下文信息) 79 80```ts 81import { common, Want } from '@kit.AbilityKit'; 82import { BusinessError } from '@kit.BasicServicesKit'; 83 84@Entry 85@Component 86struct Index { 87 comProxy: common.UIServiceProxy | null = null; 88 connectCallback: common.UIServiceExtensionConnectCallback = { 89 onData: (data: Record<string, Object>) => { 90 console.info(`data received, data: ${JSON.stringify(data)}.`); 91 }, 92 onDisconnect: () => { 93 console.info(`onDisconnect.`); 94 } 95 } 96 97 build() { 98 Column() { 99 Row() { 100 // 创建连接按钮 101 Button('connect ability') 102 .enabled(true) 103 .onClick(() => { 104 let context = this.getUIContext().getHostContext() as common.UIAbilityContext; 105 let startWant: Want = { 106 bundleName: 'com.acts.uiserviceextensionability', // 仅作为示例代码,需要替换为实际的UIServiceExtensionAbility组件的包名。 107 abilityName: 'UiServiceExtAbility', // 仅作为示例代码,需要替换为实际的UIServiceExtensionAbility组件名称。 108 }; 109 try { 110 // 连接UIServiceExtensionAbility组件 111 context.connectUIServiceExtensionAbility(startWant, this.connectCallback) 112 .then((proxy: common.UIServiceProxy) => { 113 this.comProxy = proxy; 114 let formData: Record<string, string> = { 115 'test': 'test' 116 }; 117 try { 118 this.comProxy.sendData(formData); 119 } catch (err) { 120 let code = (err as BusinessError).code; 121 let msg = (err as BusinessError).message; 122 console.error(`sendData failed, err code:${code}, err msg:${msg}.`); 123 } 124 }) 125 .catch((err: BusinessError) => { 126 console.error(`connectUIServiceExtensionAbility failed, err code: ${err.code}, err msg: ${err.message}.`); 127 }); 128 } catch (err) { 129 let code = (err as BusinessError).code; 130 let msg = (err as BusinessError).message; 131 console.error(`connectUIServiceExtensionAbility failed, err code:${code}, err msg:${msg}.`); 132 } 133 }) 134 } 135 } 136 } 137} 138```