• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Cross-Thread Embedded Component (IsolatedComponent, for System Applications Only)
2
3The **IsolatedComponent** is a tool for building isolated components, enabling you to create independent and reusable components that can be used across different applications without conflicts.
4
5Each **IsolatedComponent** exists independently with its own scope and lifecycle, not sharing state or data with other components. This facilitates reuse across applications, reducing repetitive development efforts.
6
7## Basic Concepts
8
9[IsolatedComponent](../reference/apis-arkui/arkui-ts/ts-container-isolated-component-sys.md): a component designed to embed and display a UI provided by an independent .abc file within the current page, with the displayed content executed in a restricted Worker thread.
10
11This component is primarily used in modular development scenarios requiring hot updates for .abc files.
12
13## Constraints
14
151. The .abc file must pass [VerifyAbc](../reference/apis-ability-kit/js-apis-bundleManager-sys.md#bundlemanagerverifyabc11) verification before use.
16
172. Constructor parameter updates are not supported; only the initial input is effective.
18
193. Nesting of **IsolatedComponent** components is not supported.
20
214. The main thread and the restricted Worker thread handle layout rendering asynchronously, which can lead to desynchronization in page changes caused by layout alterations or rotations.
22
235. Event passing between the main thread and the restricted Worker thread is managed asynchronously, and there is no support for event bubbling between threads. As a result, UI interactions between threads may encounter event conflicts.
24
256. When an independent .abc file is embedded into the host process using the **IsolatedComponent**, its content is fully open to the host, which can operate on the content. Therefore, this feature should be disabled in security-sensitive scenarios.
26
277. The independent .abc file runs in a restricted Worker thread, ensuring relative security and not affecting the main thread.
28
29## Scenario Example
30
31This example demonstrates the basic usage of the **IsolatedComponent** component. The sample application's **bundleName** is **"com.example.isolateddemo"**, and the component uses the .abc file and an extension page from the same application as the embedded content.
32
33**Importing the Core Module**
34
35When using the **IsolatedComponent**, first import the **@kit.AbilityKit** module, which provides the necessary functionality for building isolated components, including key APIs like **bundleManager**.
36
37As a core component of Ability Kit, **bundleManager** provides the capability to manage application packages, serving as the foundation for building the **IsolatedComponent**. Importing this module enables the use of its APIs to create and manage isolated components, ensuring data and resource isolation between different components and enhancing application security.
38
39```ts
40import { bundleManager } from '@kit.AbilityKit';
41```
42
43**Managing Permissions**
44
45When using the **IsolatedComponent**, properly configure the [requestPermissions](../security/AccessToken/declare-permissions.md) tag, which is crucial for ensuring the secure operation of components in restricted environments. This configuration allows you to specify the permissions required by the component, enabling fine-grained permission management.
46
47In restricted mode, the **IsolatedComponent** does not have the capability to execute dynamic code by default. By adding the **requestPermissions** tag in the **module.json5** configuration file, you enable the component to be authorized to execute dynamically delivered Ark bytecode under specific conditions.
48
49```json
50"requestPermissions": [
51  {
52    "name": "ohos.permission.RUN_DYN_CODE",
53    "usedScene": {
54      "abilities": [
55        "EntryAbility"
56      ],
57      "when": "inuse"
58    }
59  }
60]
61```
62
63**Restricted Worker**
64
65A restricted [Worker](../reference/apis-arkts/js-apis-worker.md) thread runs in an isolated environment. This isolation ensures memory isolation between the restricted Worker thread and other threads or components, preventing mutual interference or security issues.
66
67In the scenario where the **IsolatedComponent** is used, components often need to dynamically load external HAP resources. The restricted Worker thread ensures security through the following mechanisms:
68
69- [Sandbox path](../file-management/app-sandbox-directory.md) validation
70
71  **abcPath** points to a secure directory verified by the system, preventing malicious code injection.
72
73- Communication control
74
75  Only standardized message events are allowed for communication between the main thread and the Worker thread, with direct data sharing prohibited.
76
77- Exception isolation
78
79  Errors within the Worker thread can be handled controllably through the **onerror** event and do not cause the main application to crash.
80
81```ts
82// OhCardWorker.ets
83import { worker, ThreadWorkerGlobalScope, MessageEvents, ErrorEvent } from '@kit.ArkTS';
84const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
85
86workerPort.onmessage = (e: MessageEvents) => {}
87workerPort.onmessageerror = (e: MessageEvents) => {}
88workerPort.onerror = (e: ErrorEvent) => {}
89```
90<!--deprecated_code_no_check-->
91```ts
92IsolatedComponent({
93  want: {
94    "parameters": {
95      // Resource path
96      "resourcePath": `${getContext(this).filesDir}/${this.fileName}.hap`,
97      // Verified sandbox path for the .abc file
98      "abcPath": `/abcs${getContext(this).filesDir}/${this.fileName}`,
99      // Entry path for the page to be displayed
100      "entryPoint": `${this.bundleName}/entry/ets/pages/extension`,
101    }
102  },
103  // Restricted Worker thread
104  worker: new worker.RestrictedWorker("entry/ets/workers/OhCardWorker.ets")
105})
106```
107
108The **IsolatedComponent** achieves dynamic component loading and isolated execution through the **want** and **worker** properties, which together form the security boundary. Properly setting these properties is key to ensuring the secure operation of the component.
109
110The entry page file **ets/pages/extension.ets** running in the restricted Worker thread contains the following reference content:
111
112```ts
113@Entry
114@Component
115struct Extension {
116  @State message: string = 'Hello World';
117
118  build() {
119    RelativeContainer() {
120      Text(this.message)
121        .id('HelloWorld')
122        .fontSize(50)
123        .fontWeight(FontWeight.Bold)
124        .alignRules({
125          center: { anchor: '__container__', align: VerticalAlign.Center },
126          middle: { anchor: '__container__', align: HorizontalAlign.Center }
127        })
128    }
129    .height('100%')
130    .width('100%')
131  }
132}
133```
134
135**Sample Application Code**
136
137The following example shows the content of the home page file **ets/pages/Index.ets** loaded by EntryAbility (UIAbility) in the application.
138
139```ts
140import { worker } from '@kit.ArkTS';
141import { bundleManager, common } from '@kit.AbilityKit';
142import { BusinessError } from '@kit.BasicServicesKit';
143
144// Verify the .abc file and copy it to the specified sandbox path.
145function VerifyAbc(abcPaths: Array<string>, deleteOriginalFiles: boolean) {
146  try {
147    bundleManager.verifyAbc(abcPaths, deleteOriginalFiles, (err) => {
148      if (err) {
149        console.error("VerifyAbc failed, error message: " + err.message);
150      } else {
151        console.info("VerifyAbc successfully.");
152      }
153    });
154  } catch (err) {
155    let message = (err as BusinessError).message;
156    console.error("VerifyAbc failed, error message: " + message);
157  }
158}
159
160@Entry
161@Component
162struct Index {
163  @State isShow: boolean = false;
164  @State resourcePath: string = "";
165  @State abcPath: string = "";
166  @State entryPoint: string = "";
167  @State context: Context = this.getUIContext().getHostContext() as common.UIAbilityContext;
168  // .abc file name
169  private fileName: string = "modules";
170  // Bundle name of the application to which the .abc file belongs
171  private bundleName: string = "com.example.isolateddemo";
172  // Restricted Worker thread
173  private worker ?: worker.RestrictedWorker = new worker.RestrictedWorker("entry/ets/workers/OhCardWorker.ets");
174
175  build() {
176    Row() {
177      Column({ space: 20 }) {
178        // 1. Verify the .abc file.
179        Button("verifyAbc").onClick(() => {
180          let abcFilePath = `${this.context.filesDir}/${this.fileName}.abc`;
181          console.log("abcFilePath: " + abcFilePath);
182          VerifyAbc([abcFilePath], false);
183        }).height(100).width(200)
184
185        // 2. Display the IsolatedComponent.
186        Button("showIsolatedComponent").onClick(() => {
187          if (!this.isShow) {
188            // Resource path
189            this.resourcePath = `${this.context.filesDir}/${this.fileName}.hap`;
190            // Verified sandbox path for the .abc file
191            this.abcPath = `/abcs${this.context.filesDir}/${this.fileName}`;
192            // Entry path for the page to be displayed
193            this.entryPoint = `${this.bundleName}/entry/ets/pages/extension`;
194            this.isShow = true;
195          }
196        }).height(100).width(200)
197
198        if (this.isShow) {
199          IsolatedComponent({
200            want: {
201              "parameters": {
202                "resourcePath": this.resourcePath,
203                "abcPath": this.abcPath,
204                "entryPoint": this.entryPoint
205              }
206            },
207            worker: this.worker
208          })
209            .width(300)
210            .height(300)
211            .onError((err) => {
212              console.info("onError : " + JSON.stringify(err));
213            })
214        }
215      }
216      .width('100%')
217    }
218    .height('100%')
219  }
220}
221```
222
223**Expected Results**
224
2251. Build the HAP in DevEco Studio and install it on the device.
226
2272. Upload the **modules.abc** file generated by the application to the application sandbox path **/data/app/el2/100/base/com.example.isolateddemo/haps/entry/files** using DevEco Studio or the hdc tool. The reference command for the hdc tool is as follows:
228
229```bash
230hdc file send modules.abc /data/app/el2/100/base/com.example.isolateddemo/haps/entry/files/
231```
232
2333. Open the application page and click the **verifyAbc** button to verify the .abc file. The log "VerifyAbc successfully" should be output.
234
235![en-us_image_0000001746521386](figures/en-us_image_0000001746521386.jpg)
236
237![en-us_image_0000001502381065](figures/en-us_image_0000001502381065.png)
238
2394. Click the **showIsolatedComponent** button to display the **IsolatedComponent** with the content "Hello World."
240