• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# PluginComponent (系统接口)
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @dutie123-->
5<!--Designer: @lmleon-->
6<!--Tester: @fredyuan0912-->
7<!--Adviser: @HelloCrease-->
8
9提供外部应用组件嵌入式显示功能,即外部应用提供的UI可在本应用内显示。如需通过跨进程通信实现更新,请参考[@ohos.pluginComponent](../js-apis-plugincomponent.md)。
10
11
12>  **说明:**
13>
14>  - 该组件从API Version 9开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
15>
16>  - 本模块系统接口。
17
18## 子组件
19
2021
22
23## 接口
24
25PluginComponent(options: PluginComponentOptions)
26
27创建插件组件,用于显示外部应用提供的UI。
28
29**系统接口:** 此接口为系统接口。
30
31**系统能力:** SystemCapability.ArkUI.ArkUI.Full
32
33**参数:**
34
35| 参数名  | 类型                                                     | 必填 | 说明                                                     |
36| ------- | ----------------------------------------------------------- | ---- | ------------------------------------------------------------ |
37| options | [PluginComponentOptions](#plugincomponentoptions18类型说明) | 是   | 定义用于构造插件组件的选项。 |
38
39## PluginComponentOptions<sup>18+</sup>类型说明
40
41定义用于构造插件组件的选项。
42
43> **说明:**
44>
45> 为规范匿名对象的定义,API 18版本修改了此处的元素定义。其中,保留了历史匿名对象的起始版本信息,会出现外层元素@since版本号高于内层元素版本号的情况,但这不影响接口的使用。
46
47**系统接口:** 此接口为系统接口。
48
49**系统能力:** SystemCapability.ArkUI.ArkUI.Full
50
51| 参数       | 类型   | 描述                        |
52| ---------- | ------ | --------------------------- |
53| template<sup>9+</sup>   | [PluginComponentTemplate](#plugincomponenttemplate9类型说明) | 组件模板,用于跟提供方定义的组件绑定。                |
54| data<sup>9+</sup>       | any    | 传给插件组件提供方使用的数据。 |
55
56## PluginComponentTemplate<sup>9+</sup>类型说明
57
58**系统接口:** 此接口为系统接口。
59
60**系统能力:** SystemCapability.ArkUI.ArkUI.Full
61
62| 参数       | 类型   | 描述                        |
63| ---------- | ------ | --------------------------- |
64| source     | string | 组件模板名。                |
65| bundleName | string | 提供方Ability的bundleName。 |
66
67## 属性
68
69必须显式设置组件宽高为非0有效值。
70
71**说明:**
72
73  模板支持两种提供方式:
74* 1.使用绝对路径进行资源提供:source字段填写模板绝对路径,bundleName不需要填写。仅适用于不需要加载资源的单独模板页面,不建议使用。
75* 2.通过应用包进行资源提供:bundleName字段需要填写应用包名;source字段填写相对hap包的模板相对路径,对于多hap场景,通过“相对路径&模块名称”的方式进行hap包的确认。
76
77  例如:{source: 'pages/PluginProviderExample.ets&entry', bundleName: 'com.example.provider'}
78
79  仅对FA模型支持source字段填写AbilityName、bundleName字段填写应用包名的方式进行资源提供。
80
81  例如:{source: 'plugin', bundleName: 'com.example.provider'}
82
83
84## 事件
85
86支持[绑定手势方法](ts-gesture-settings.md),并分发给提供方页面,在提供方页面内部处理。
87
88除支持[通用事件](ts-component-general-events.md),还支持以下事件:
89
90### onComplete
91
92onComplete(callback:&nbsp;VoidCallback)
93
94组件加载完成时触发回调。
95
96**系统接口:** 此接口为系统接口。
97
98**系统能力:** SystemCapability.ArkUI.ArkUI.Full
99
100**参数:**
101
102| 参数名  | 类型                                                     | 必填 | 说明                                                     |
103| ------- | ----------------------------------------------------------- | ---- | ------------------------------------------------------------ |
104| callback | [VoidCallback](../../apis-basic-services-kit/js-apis-base.md#callback) | 是   | 回调函数,组件加载完成时触发的回调。 |
105
106### onError
107
108onError(callback:&nbsp;PluginErrorCallback)
109
110组件加载错误时触发回调。
111
112**系统接口:** 此接口为系统接口。
113
114**系统能力:** SystemCapability.ArkUI.ArkUI.Full
115
116**参数:**
117
118| 参数名    | 类型                                                         | 必填 | 说明                                            |
119| --------- | ------------------------------------------------------------ | ---- | ----------------------------------------------- |
120| callback  | [PluginErrorCallback](#pluginerrorcallback18类型说明)          | 是   | 发生错误时调用回调。 |
121
122## PluginErrorCallback<sup>18+</sup>类型说明
123
124发生错误时调用回调。
125
126**系统接口:** 此接口为系统接口。
127
128**系统能力:** SystemCapability.ArkUI.ArkUI.Full
129
130| 参数     | 类型               | 描述                        |
131| -------- | ------------------ | --------------------------- |
132| info     | [PluginErrorData](#pluginerrordata18类型说明)  | 发生错误时提供的数据。 |
133
134## PluginErrorData<sup>18+</sup>类型说明
135
136发生错误时提供的数据。
137
138> **说明:**
139>
140> 为规范匿名对象的定义,API 18版本修改了此处的元素定义。其中,保留了历史匿名对象的起始版本信息,会出现外层元素@since版本号高于内层元素版本号的情况,但这不影响接口的使用。
141
142**系统接口:** 此接口为系统接口。
143
144**系统能力:** SystemCapability.ArkUI.ArkUI.Full
145
146| 参数       | 类型   | 描述                        |
147| ---------- | ------ | -------------------------- |
148| errcode<sup>9+</sup>    | number | 错误码。                    |
149| msg<sup>9+</sup>        | string | 错误信息。                  |
150
151错误码1为默认错误码,错误信息和处理建议详见下表:
152
153| 错误信息   | 描述                        | 处理建议 |
154| ------ | -------------------------- | ----------------- |
155| package path is empty. | 包路径为空。 | 检查PluginComponentTemplate参数中source字段是否有误。  |
156| Query Active OsAccountIds failed! | 获取激活的用户ID失败。 | 检查Account服务是否异常,或检查应用是否具备用户ID查询权限。    |
157| Template source is empty. | 模板source为空。 | 检查PluginComponentTemplate参数中source字段是否有误。  |
158| Bms bundleManager is nullptr. | 获取BundleManager失败。 |  检查BMS服务是否异常,或检查应用是否具备ohos.permission.GET_BUNDLE_INFO_PRIVILEGED,ohos.permission.GET_BUNDLE_INFO,ohos.permission.REQUIRE_FORM权限。                  |
159| App bundleName is empty. | 应用包名为空。  | 检查PluginComponentTemplate参数中bundleName字段是否有误。                   |
160| Bms get bundleName failed! | 获取包名失败。  |  检查PluginComponentTemplate参数中bundleName字段是否有误,或检查bundleName字段对应的包是否已正确安装,或检查BMS服务是否异常,或检查应用是否具备ohos.permission.GET_BUNDLE_INFO_PRIVILEGED,ohos.permission.GET_BUNDLE_INFO,ohos.permission.REQUIRE_FORM权限。                |
161| Bms moduleResPaths is empty. | 插件包moduleResPaths属性为空。 |  检查bundleName字段对应的包的moduleResPaths属性是否异常,或检查BMS服务是否异常                   |
162| Bms get hapPath failed! Cannot find hap according to BundleName and ModuleName! | 获取hapPath失败。  |   检查PluginComponentTemplate参数中bundleName字段是否有误,检查bundleName字段对应的模块是否已正确安装。               |
163
164
165## 示例(加载PluginComponent)
166
167本示例展示`PluginComponent`组件的基础使用方式,需要创建一个`bundleName`为"com.example.user"的[使用方应用](#组件使用方),和一个`bundleName`为"com.example.provider"的[提供方应用](#组件提供方)。应用项目构建完成后,具体测试步骤如下:
1681. 将两个应用的hap包安装到设备上;
1692. 打开使用方应用页面,使用方与提供方内容都正确显示;
1703. 分别点击使用方的“Register Push Listener”按钮和提供方的“Register Request Listener”按钮注册监听;
1714. 点击使用方的“Request”按钮向提供方发送事件,日志中打印“onRequestListener”相关信息;
1725. 点击提供方的“Push”按钮向使用方发送事件,日志中打印“onPushListener”相关信息。
173
174### 组件使用方
175
176使用方应用的`bundleName`为"com.example.user",包含一个页面。
177- `EntryAbility(UIAbility)`加载入口页面文件`ets/pages/Index.ets`,`Index.ets`内容如下:
178  ```ts
179  import plugin from "./plugin_component";
180
181  interface Info {
182    errcode: number,
183    msg: string
184  }
185
186  @Entry
187  @Component
188  struct PluginUserExample {
189    build() {
190      Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
191        Text('Hello World')
192          .fontSize(50)
193          .fontWeight(FontWeight.Bold)
194        Button('Register Push Listener')
195          .fontSize(30)
196          .width(400)
197          .height(100)
198          .margin({ top: 20 })
199          .onClick(() => {
200            plugin.onListener();
201            console.info("Button('Register Push Listener')");
202          })
203        Button('Request')
204          .fontSize(50)
205          .width(400)
206          .height(100)
207          .margin({ top: 20 })
208          .onClick(() => {
209            plugin.Request();
210            console.info("Button('Request')");
211          })
212        PluginComponent({
213          // 提供方
214          template: { source: 'pages/Index.ets&entry', bundleName: 'com.example.provider' },
215          data: { 'countDownStartValue': 'new countDownStartValue' }
216        }).size({ width: 500, height: 350 })
217          .onComplete(() => {
218            console.info("onComplete");
219          })
220          .onError((info: Info) => {
221            console.error("onError" + info.errcode + ":" + info.msg);
222          })
223      }
224      .width('100%')
225      .height('100%')
226    }
227  }
228  ```
229- 根据模型类型,将对应的[Plugin组件工具代码](#plugin组件工具)拷贝至项目的`ets/pages/plugin_component.js`文件中。
230- 在`module.json5`配置文件中增加`requestPermissions`标签,允许使用方查询其他应用信息:
231  ```json
232  "requestPermissions": [
233    {
234      "name": "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED",
235      "usedScene": {
236        "abilities": [
237          "EntryAbility"
238        ],
239        "when": "inuse"
240      }
241    }
242  ]
243  ```
244
245### 组件提供方
246
247提供方应用的`bundleName`为"com.example.provider",包含一个页面。
248- `EntryAbility(UIAbility)`加载入口页面文件`ets/pages/Index.ets`,`Index.ets`内容如下:
249  ```ts
250  import plugin from "./plugin_component";
251
252  @Entry
253  @Component
254  struct PluginProviderExample {
255    @State message: string = 'no click!';
256
257    build() {
258      Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
259        Button('Register Request Listener')
260          .fontSize(30)
261          .width(400)
262          .height(100)
263          .margin({ top: 20 })
264          .onClick(() => {
265            plugin.onListener();
266            console.info("Button('Register Request Listener')");
267          })
268        Button('Push')
269          .fontSize(30)
270          .width(400)
271          .height(100)
272          .margin({ top: 20 })
273          .onClick(() => {
274            plugin.Push();
275            this.message = "Button('Push')";
276            console.info("Button('Push')");
277          })
278        Text(this.message)
279          .height(150)
280          .fontSize(30)
281          .padding(5)
282          .margin(5)
283      }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 })
284    }
285  }
286  ```
287- 根据模型类型,将对应的[Plugin组件工具代码](#plugin组件工具)拷贝至项目的`ets/pages/plugin_component.js`文件中。
288
289### Plugin组件工具
290
291Plugin组件工具,用于使用方与提供方之间进行通信。需要根据模型类型选择对应代码,并拷贝至项目中。
292
293#### FA模型
294```js
295// 当前示例代码仅适用于FA模型
296import pluginComponentManager from '@ohos.pluginComponent'
297
298var providerBundleName = 'com.example.provider'
299var providerAbilityName = 'com.example.provider.EntryAbility'
300var providerName = 'Index'
301
302// push事件监听
303function onPushListener(source, template, data, extraData) {
304    console.info("onPushListener template.source=" + template.source)
305    console.info("onPushListener template.ability=" + template.ability)
306    console.info("onPushListener data=" + JSON.stringify(data))
307    console.info("onPushListener extraData=" + JSON.stringify(extraData))
308}
309
310// request事件监听
311function onRequestListener(source, name, data)
312{
313    console.info("onRequestListener name=" + name);
314    console.info("onRequestListener data=" + JSON.stringify(data));
315    return {template:"pluginTemplate", data:data};
316}
317
318export default {
319    // 注册监听事件
320    onListener() {
321        pluginComponentManager.on("push", onPushListener)
322        pluginComponentManager.on("request", onRequestListener)
323    },
324    Push() {
325        // 组件提供方主动发送事件,want: 提供方信息
326        pluginComponentManager.push(
327            {
328                want: {
329                    bundleName: providerBundleName,
330                    abilityName: providerAbilityName,
331                },
332                name: providerName,
333                data: {
334                    "key_1": "plugin component push data",
335                    "key_2": 12345
336                },
337                extraData: {
338                    "extra_str": "this is push event"
339                },
340                jsonPath: "",
341            },
342            (err, data) => {
343                console.info("push_callback: push ok!");
344            }
345        )
346    },
347    Request() {
348        // 组件使用方主动发送事件,want: 提供方信息
349        pluginComponentManager.request({
350            want: {
351                bundleName: providerBundleName,
352                abilityName: providerAbilityName,
353            },
354            name: providerName,
355            data: {
356                "key_1": "plugin component request data",
357                "key_2": 67890
358            },
359            jsonPath: "",
360        },
361            (err, data) => {
362                console.info("request_callback: componentTemplate.ability=" + data.componentTemplate.ability)
363                console.info("request_callback: componentTemplate.source=" + data.componentTemplate.source)
364                console.info("request_callback: data=" + JSON.stringify(data.data))
365                console.info("request_callback: extraData=" + JSON.stringify(data.extraData))
366            }
367        )
368    }
369}
370```
371
372#### Stage模型
373```js
374// 当前示例代码仅适用于Stage模型
375import pluginComponentManager from '@ohos.pluginComponent'
376
377var userBundleName = 'com.example.user'
378var userAbilityName = 'com.example.user.EntryAbility'
379var providerBundleName = 'com.example.provider'
380var providerAbilityName = 'com.example.provider.EntryAbility'
381var providerName = 'Index'
382
383// push事件监听
384function onPushListener(source, template, data, extraData) {
385    console.info("onPushListener template.source=" + template.source)
386    console.info("onPushListener template.ability=" + template.ability)
387    console.info("onPushListener data=" + JSON.stringify(data))
388    console.info("onPushListener extraData=" + JSON.stringify(extraData))
389}
390
391// request事件监听
392function onRequestListener(source, name, data) {
393    console.info("onRequestListener name=" + name)
394    console.info("onRequestListener data=" + JSON.stringify(data))
395    return { template: "pluginTemplate", data: data }
396}
397
398export default {
399    // 注册监听事件
400    onListener() {
401        pluginComponentManager.on("push", onPushListener)
402        pluginComponentManager.on("request", onRequestListener)
403    },
404    Push() {
405        // 组件提供方主动发送事件,owner:使用方,target:提供方
406        pluginComponentManager.push(
407            {
408                owner: {
409                    bundleName: userBundleName,
410                    abilityName: userAbilityName,
411                },
412                target: {
413                    bundleName: providerBundleName,
414                    abilityName: providerAbilityName,
415                },
416                name: providerName,
417                data: {
418                    "key_1": "plugin component push data",
419                    "key_2": 12345
420                },
421                extraData: {
422                    "extra_str": "this is push event"
423                },
424                jsonPath: "",
425            },
426            (err, data) => {
427                console.info("push_callback: push ok!");
428            }
429        )
430    },
431    Request() {
432        // 组件使用方主动发送事件,owner:使用方,target:提供方
433        pluginComponentManager.request({
434            owner: {
435                bundleName: userBundleName,
436                abilityName: userAbilityName,
437            },
438            target: {
439                bundleName: providerBundleName,
440                abilityName: providerAbilityName,
441            },
442            name: providerName,
443            data: {
444                "key_1": "plugin component request data",
445                "key_2": 67890
446            },
447            jsonPath: "",
448        },
449            (err, data) => {
450                console.info("request_callback: componentTemplate.ability=" + data.componentTemplate.ability)
451                console.info("request_callback: componentTemplate.source=" + data.componentTemplate.source)
452                console.info("request_callback: data=" + JSON.stringify(data.data))
453                console.info("request_callback: extraData=" + JSON.stringify(data.extraData))
454            }
455        )
456    }
457}
458```
459