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 47无 48 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 ```