• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# IsolatedComponent (系统接口)
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @dutie123-->
5<!--Designer: @lmleon-->
6<!--Tester: @fredyuan0912-->
7<!--Adviser: @HelloCrease-->
8
9IsolatedComponent用于支持在本页面内嵌入显示独立Abc(.abc文件)提供的UI,展示的内容在受限worker线程中运行。
10
11通常用于有Abc热更新(可动态替换Isolated加载的abc文件,无需通过重新安装应用的方式实现内容更新)诉求的模块化开发场景。
12
13> **说明:**
14>
15> 该组件从API Version 12开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
16>
17> 本模块为系统接口。
18
19## 使用约束
20
21**规格约束**
22
231、本组件不支持预览。
24
252、Abc需要[VerifyAbc](../../apis-ability-kit/js-apis-bundleManager-sys.md#bundlemanagerverifyabc11)校验通过之后才可以使用于当前组件。
26
273、不支持构造参数更新,仅首次传入有效。
28
294、不支持IsolatedComponent组件嵌套场景。
30
31**体验约束**
32
331、创建IsolatedComponent组件时,受限worker线程加载Abc布局渲染存在一定耗时,在此等待期间显示IsolatedComponent组件的背景色。
34
352、主线程与受限worker线程之间布局渲染是异步处理,布局变化、旋转等导致的页面变化存在不同步现象。
36
373、主线程与受限worker线程之间事件传递是异步处理,不支持线程之间的事件冒泡,线程之间的UI交互存在事件冲突现象。
38
39**安全约束**
40
411、独立Abc通过IsolatedComponent组件嵌入式显示在宿主进程,即可说明其Abc内容完全向宿主开放,宿主有权操作独立Abc的内容,对此安全敏感场景禁用。
42
432、独立Abc运行在受限worker可保证相对安全,独立Abc内容不影响主线程。
44
45## 子组件
46
4748
49## 接口
50
51IsolatedComponent(options: IsolatedOptions)
52
53创建IsolatedComponent组件,用于显示受限worker运行的Abc。
54
55**系统接口:** 此接口为系统接口。
56
57**系统能力:** SystemCapability.ArkUI.ArkUI.Full
58
59**参数:**
60
61| 参数名                | 类型                                                   | 必填 | 说明           |
62| --------------------- | ---------------------------------------------------------- | ---- | ------------------ |
63| options | [IsolatedOptions](#isolatedoptions)                | 是   | 需要传递的构造项。 |
64
65## IsolatedOptions
66
67用于在IsolatedComponent进行构造的时候,传递可选的构造参数。
68
69**系统接口:** 此接口为系统接口。
70
71**系统能力:** SystemCapability.ArkUI.ArkUI.Full
72
73| 名称  | 类型       | 只读 | 可选 | 说明 |
74| ---- | ------------ | ---- | ---- | --------------- |
75| want | [Want](../../apis-ability-kit/js-apis-app-ability-want.md) | 否 | 否 | 要加载的Abc信息。 |
76| worker | [RestrictedWorker](../../apis-arkts/js-apis-worker-sys.md#restrictedworker11) | 否 | 否 | 运行Abc的受限worker。 |
77
78## 属性
79仅支持[width](ts-universal-attributes-size.md#width)、[height](ts-universal-attributes-size.md#height)、[backgroundColor](ts-universal-attributes-background.md#backgroundcolor)通用属性。
80
81## 事件
82
83不支持[通用事件](ts-component-general-events.md)。
84
85将事件经过坐标转换后异步传递给受限worker线程处理。
86
87支持以下事件:
88
89### onError
90
91onError(callback:ErrorCallback)
92
93被拉起的Ability扩展在运行过程中发生异常时触发本回调。可通过回调参数中的code、name和message获取错误信息并做处理。
94
95**系统接口:** 此接口为系统接口。
96
97**系统能力:** SystemCapability.ArkUI.ArkUI.Full
98
99**参数:**
100
101| 参数名                | 类型                                                   | 必填 | 说明           |
102| --------------------- | ---------------------------------------------------------- | ---- | ------------------ |
103| callback | [ErrorCallback](../../apis-basic-services-kit/js-apis-base.md#errorcallback)                | 是   | 报错信息。 |
104
105## 示例(加载IsolatedComponent)
106
107本示例展示`IsolatedComponent`组件的基础使用方式,示例应用的`bundleName`为"com.example.isolateddemo",并使用本应用的Abc文件和extension页面作为嵌入展示的内容。构建应用项目后,具体测试步骤如下:
1081. 在DevEco Studio上编译构建生成hap包,并安装到设备上;
1092. 将本应用构建生成的modules.abc文件通过DevEco Studio或[hdc工具](../../../dfx/hdc.md)上传至应用沙箱路径`/data/app/el2/100/base/com.example.isolateddemo/haps/entry/files`下;
1103. 打开应用页面,点击"verifyAbc"按钮进行校验,输出"VerifyAbc successfully"日志;
1114. 点击"showIsolatedComponent"按钮,显示`IsolatedComponent`组件,内容为"Hello World"。
112
113- 受限worker脚本`ets/workers/OhCardWorker.ets`的内容如下:
114  ```ts
115  // OhCardWorker.ets
116  import { worker, ThreadWorkerGlobalScope, MessageEvents, ErrorEvent } from '@kit.ArkTS';
117
118  const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
119
120  workerPort.onmessage = (e: MessageEvents) => {
121  }
122  workerPort.onmessageerror = (e: MessageEvents) => {
123  }
124  workerPort.onerror = (e: ErrorEvent) => {
125  }
126  ```
127
128- 示例应用中`EntryAbility(UIAbility)`加载首页文件`ets/pages/Index.ets`的内容如下:
129  ```ts
130  import { worker } from '@kit.ArkTS';
131  import { bundleManager, common } from '@kit.AbilityKit';
132  import { BusinessError } from '@kit.BasicServicesKit';
133
134  // 对abc文件进行校验,并拷贝到指定沙箱路径下
135  function VerifyAbc(abcPaths: Array<string>, deleteOriginalFiles: boolean) {
136    try {
137      bundleManager.verifyAbc(abcPaths, deleteOriginalFiles, (err) => {
138        if (err) {
139          console.error("VerifyAbc failed, error message: " + err.message);
140        } else {
141          console.info("VerifyAbc successfully.");
142        }
143      });
144    } catch (err) {
145      let message = (err as BusinessError).message;
146      console.error("VerifyAbc failed, error message: " + message);
147    }
148  }
149
150  @Entry
151  @Component
152  struct Index {
153    @State isShow: boolean = false;
154    @State resourcePath: string = "";
155    @State abcPath: string = "";
156    @State entryPoint: string = "";
157    @State context: Context = this.getUIContext().getHostContext() as common.UIAbilityContext;
158    // abc文件名
159    private fileName: string = "modules";
160    // abc文件所属应用的bundleName
161    private bundleName: string = "com.example.isolateddemo";
162    // 受限worker
163    private worker ?: worker.RestrictedWorker = new worker.RestrictedWorker("entry/ets/workers/OhCardWorker.ets");
164
165    build() {
166      Row() {
167        Column() {
168          // 1.调用verifyAbc接口校验abc文件
169          Button("verifyAbc").onClick(() => {
170            let abcFilePath = `${this.context.filesDir}/${this.fileName}.abc`;
171            console.info("abcFilePath: " + abcFilePath);
172            VerifyAbc([abcFilePath], false);
173          }).height(100).width(100)
174
175          // 2.显示IsolatedComponent
176          Button("showIsolatedComponent").onClick(() => {
177            if (!this.isShow) {
178              // 资源路径
179              this.resourcePath = `${this.context.filesDir}/${this.fileName}.hap`;
180              // abc文件校验后的沙箱路径
181              this.abcPath = `/abcs${this.context.filesDir}/${this.fileName}`;
182              // 需要显示页面的入口路径
183              this.entryPoint = `${this.bundleName}/entry/ets/pages/extension`;
184              this.isShow = true;
185            }
186          }).height(100).width(100)
187
188          if (this.isShow) {
189            IsolatedComponent({
190              want: {
191                "parameters": {
192                  "resourcePath": this.resourcePath,
193                  "abcPath": this.abcPath,
194                  "entryPoint": this.entryPoint
195                }
196              },
197              worker: this.worker
198            })
199              .width(300)
200              .height(300)
201              .onError((err) => {
202                console.error("onError : " + JSON.stringify(err));
203              })
204          }
205        }
206        .width('100%')
207      }
208      .height('100%')
209    }
210  }
211  ```
212
213- 在受限worker线程中运行的入口页面文件`ets/pages/extension.ets`,需要在`resources/base/profile/main_pages.json`文件中配置该页面路径,其中内容如下:
214  ```ts
215  @Entry
216  @Component
217  struct Extension {
218    @State message: string = 'Hello World';
219
220    build() {
221      RelativeContainer() {
222        Text(this.message)
223          .id('HelloWorld')
224          .fontSize(50)
225          .fontWeight(FontWeight.Bold)
226          .alignRules({
227            center: { anchor: '__container__', align: VerticalAlign.Center },
228            middle: { anchor: '__container__', align: HorizontalAlign.Center }
229          })
230      }
231      .height('100%')
232      .width('100%')
233    }
234  }
235  ```
236
237- 在`module.json5`配置文件中增加`requestPermissions`标签,允许在受限模式下执行动态下发的方舟字节码:
238  ```json
239  "requestPermissions": [
240    {
241      "name": "ohos.permission.RUN_DYN_CODE",
242      "usedScene": {
243        "abilities": [
244          "EntryAbility"
245        ],
246        "when": "inuse"
247      }
248    }
249  ]
250  ```