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 236 237 238 2394. Click the **showIsolatedComponent** button to display the **IsolatedComponent** with the content "Hello World." 240