1# HAR 2<!--Kit: Ability Kit--> 3<!--Subsystem: BundleManager--> 4<!--Owner: @wanghang904--> 5<!--Designer: @hanfeng6--> 6<!--Tester: @kongjing2--> 7<!--Adviser: @Brilliantry_Rui--> 8 9HAR(Harmony Archive)是静态共享包,可以包含代码、C++库、资源和配置文件。通过HAR可以实现多个模块或多个工程共享ArkUI组件、资源等相关代码。 10 11## 使用场景 12- 支持应用内共享,也可以作为二方库(SDK)、三方库(SDK)发布后供其他应用使用。 13- 作为二方库(SDK),发布到[OHPM私仓](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-ohpm-repo),供公司内部其他应用使用。 14- 作为三方库(SDK),发布到[OHPM中心仓](https://ohpm.openharmony.cn/#/cn/home),供其他应用使用。 15 16## 约束限制 17 18- HAR不支持在设备上单独安装或运行,只能作为应用模块的依赖项被引用。 19- HAR不支持在配置文件中声明[ExtensionAbility](../application-models/extensionability-overview.md)组件。从API version 14开始,支持在配置文件中声明[UIAbility](../application-models/uiability-overview.md)组件,配置UIAbility的方法参考[在模块中添加Ability](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-add-new-ability#section18658758104318),拉起HAR中UIAbility的方式与[启动应用内的UIAbility](../application-models/uiability-intra-device-interaction.md)方法相同。 20> **说明:** 21> 22> 如果使用[startAbility](../reference/apis-ability-kit/js-apis-inner-application-uiAbilityContext.md#startability)接口拉起HAR中的UIAbility,接口参数中的moduleName取值需要为依赖该HAR的[HAP](hap-package.md)/[HSP](in-app-hsp.md)的moduleName。 23- HAR不支持在配置文件中声明[pages](./module-configuration-file.md#pages标签)页面,但是可以包含pages页面,并通过[Navigation跳转](../ui/arkts-navigation-navigation.md#路由操作)的方式进行跳转。 24- HAR不支持引用AppScope目录中的资源。在编译构建时,AppScope中的内容不会打包到HAR中,因此会导致HAR资源引用失败。 25- 由于HSP仅支持应用内共享,如果HAR依赖了HSP,则该HAR文件仅支持应用内共享,不支持发布到二方仓或三方仓供其他应用使用,否则会导致编译失败。 26- 多包(HAP/HSP)引用相同的HAR时,会造成多包间代码和资源的重复拷贝,从而导致应用包变大。 27- HAR可以依赖其他HAR或者HSP,但不支持循环依赖,也不支持依赖传递。 28- HAP引用HAR时,在编译构建过程中系统会自动合并两者的权限配置。因此开发者无需在HAP和HAR中重复申请相同权限。 29 30> **说明:** 31> 32> 循环依赖:例如有三个HAR,HAR-A、HAR-B和HAR-C,循环依赖指HAR-A依赖HAR-B,HAR-B依赖HAR-C,HAR-C又依赖HAR-A。 33> 34> 依赖传递:例如有三个HAR,HAR-A、HAR-B和HAR-C,依赖关系是HAR-A依赖HAR-B,HAR-B依赖HAR-C。不支持传递依赖指HAR-A可以使用HAR-B的方法和组件,但是HAR-A不能直接使用HAR-C的方法和组件。 35 36 37## 创建 38开发者可以通过DevEco Studio创建一个用于调用C++代码的HAR模块,创建过程中需要在Configure New Module界面中开启Enable native。详见[创建库模块](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-har#section643521083015)。 39 40 41## 开发 42 43介绍如何导出HAR的ArkUI组件、接口、资源,供其他应用或当前应用的其他模块引用。 44 45Index.ets文件是HAR导出声明文件的入口,HAR需要导出的接口,统一在Index.ets文件中导出。Index.ets文件是DevEco Studio默认自动生成的,开发者也可以自定义,在模块的oh-package.json5文件中的main字段配置入口声明文件,配置如下所示: 46```json 47{ 48 "main": "Index.ets" 49} 50``` 51> **说明:** 52> 53> HAR在和宿主应用一起编译时,会把HAR的代码直接编译到宿主应用中,HAR包是一个编译中间态产物,不是最终的运行实体。运行时,HAR运行的身份信息是其宿主应用,系统会以宿主应用的版本做行为区分。如果需要在HAR中区分宿主应用的版本做不同的行为区分,可以调用[getBundleInfoForSelf](../reference/apis-ability-kit/js-apis-bundleManager.md#bundlemanagergetbundleinfoforself)接口,获取宿主应用的targetVersion,然后根据不同的targetVersion,做不同的逻辑处理。 54 55### 导出ArkUI组件 56通过`export`导出ArkUI组件,示例如下: 57```ts 58// library/src/main/ets/components/mainpage/MainPage.ets 59@Component 60export struct MainPage { 61 @State message: string = 'HAR MainPage'; 62 63 build() { 64 Column() { 65 Row() { 66 Text(this.message) 67 .fontSize(32) 68 .fontWeight(FontWeight.Bold) 69 } 70 .margin({ top: '32px' }) 71 .height(56) 72 .width('624px') 73 74 Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center, alignContent: FlexAlign.Center }) { 75 Column() { 76 Image($r('app.media.pic_empty')).width('33%') 77 Text($r('app.string.empty')) 78 .fontSize(14) 79 .fontColor($r('app.color.text_color')) 80 } 81 }.width('100%') 82 .height('90%') 83 } 84 .width('100%') 85 .height('100%') 86 .backgroundColor($r('app.color.page_background')) 87 } 88} 89``` 90HAR对外暴露的接口,在Index.ets导出文件中声明如下所示: 91```ts 92// library/Index.ets 93export { MainPage } from './src/main/ets/components/mainpage/MainPage'; 94``` 95### 导出类和方法 96通过`export`导出类和方法,支持导出多个类和方法,示例如下所示: 97```ts 98// library/src/main/ets/test.ets 99export class Log { 100 static info(msg: string) { 101 console.info(msg); 102 } 103} 104 105export function func() { 106 return 'har func'; 107} 108 109export function func2() { 110 return 'har func2'; 111} 112``` 113HAR对外暴露的接口,在Index.ets导出文件中声明如下所示: 114```ts 115// library/Index.ets 116export { Log, func, func2 } from './src/main/ets/test'; 117``` 118 119### 导出native方法 120在HAR中也可以包含C++编写的so。对于so中的native方法,HAR通过以下方式导出,以导出liblibrary.so的加法接口add为例: 121```ts 122// library/src/main/ets/utils/nativeTest.ets 123import native from 'liblibrary.so'; 124 125export function nativeAdd(a: number, b: number): number { 126 let result: number = native.add(a, b); 127 return result; 128} 129``` 130HAR对外暴露的接口,在Index.ets导出文件中声明如下所示: 131```ts 132// library/Index.ets 133export { nativeAdd } from './src/main/ets/utils/nativeTest'; 134``` 135 136### 导出资源 137在编译构建HAP时,DevEco Studio会从HAP模块及依赖的模块中收集资源文件,如果不同模块下的资源文件出现重名冲突时,DevEco Studio会按照以下优先级进行覆盖(优先级由高到低): 138- AppScope(仅Stage模型支持)。 139- HAP包自身模块。 140- 依赖的HAR模块,如果依赖的多个HAR之间有资源冲突,会按照工程oh-package.json5中dependencies下的依赖顺序进行覆盖,依赖顺序在前的优先级较高。例如下方示例中dayjs和lottie中包含同名文件时,会优先使用dayjs中的资源。 141> **说明:** 142> 143> 如果在AppScope、HAP模块或HAR模块的国际化目录中配置了资源,在相同的国际化限定词下,合并的优先级也遵循上述规则。同时,国际化限定词中配置的优先级高于在base中的配置。例如,在AppScope的base中配置了资源字段,在HAR模块的en_US中配置了同样的资源字段,则在en_US的使用场景中,会更优先使用HAR模块中配置的资源字段。 144``` 145// oh-package.json5 146{ 147 "dependencies": { 148 "dayjs": "^1.10.4", 149 "lottie": "^2.0.0" 150 } 151} 152``` 153 154## 使用 155 156介绍如何配置HAR依赖,并引用HAR的ArkUI组件、接口、资源。 157 158引用HAR前,需要先配置对HAR的依赖,详见[引用HAR文件和资源](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-har-import)。 159 160### 引用HAR的ArkUI组件 161 162HAR的依赖配置成功后,可以引用HAR的ArkUI组件。通过`import`引入HAR导出的ArkUI组件,示例如下所示: 163```ts 164// entry/src/main/ets/pages/IndexSec.ets 165import { MainPage } from 'library'; 166 167@Entry 168@Component 169struct IndexSec { 170 build() { 171 Row() { 172 // 引用HAR的ArkUI组件 173 MainPage() 174 } 175 .height('100%') 176 } 177} 178``` 179### 引用HAR的类和方法 180通过`import`引用HAR导出的类和方法,示例如下所示: 181```ts 182// entry/src/main/ets/pages/Index.ets 183import { Log, func } from 'library'; 184 185@Entry 186@Component 187struct Index { 188 @State message: string = 'Hello World'; 189 190 build() { 191 Column() { 192 Text(this.message) 193 .fontFamily('HarmonyHeiTi') 194 .fontWeight(FontWeight.Bold) 195 .fontSize(32) 196 197 //引用HAR的ets类和方法 198 Button($r('app.string.button')) 199 .id('button') 200 .height(48) 201 .width('624px') 202 .margin({ top: '4%' }) 203 .type(ButtonType.Capsule) 204 .onClick(() => { 205 // 引用HAR的类和方法 206 Log.info('har msg'); 207 this.message = 'func return: ' + func(); 208 }) 209 } 210 .width('100%') 211 .backgroundColor($r('app.color.page_background')) 212 .height('100%') 213 } 214} 215``` 216 217### 引用HAR的native方法 218通过`import`引用HAR导出的native方法,示例如下所示: 219```ts 220// entry/src/main/ets/pages/Index.ets 221import { nativeAdd } from 'library'; 222 223@Entry 224@Component 225struct Index { 226 @State message: string = 'Hello World'; 227 228 build() { 229 Column() { 230 Text(this.message) 231 .fontFamily('HarmonyHeiTi') 232 .fontWeight(FontWeight.Bold) 233 .fontSize(32) 234 235 //引用HAR的native方法 236 Button($r('app.string.native_add')) 237 .id('nativeAdd') 238 .height(48) 239 .width('624px') 240 .margin({ top: '4%', bottom: '6%' }) 241 .type(ButtonType.Capsule) 242 .onClick(() => { 243 this.message = 'result: ' + nativeAdd(1, 2); 244 }) 245 } 246 .width('100%') 247 .backgroundColor($r('app.color.page_background')) 248 .height('100%') 249 } 250} 251``` 252 253### 引用HAR的资源 254通过`$r`引用HAR中的资源,例如在HAR模块的`src/main/resources`里添加字符串资源(在string.json中定义,name:hello_har)和图片资源(icon_har.png),然后在Entry模块中引用该字符串和图片资源的示例如下所示: 255```ts 256// entry/src/main/ets/pages/Index.ets 257@Entry 258@Component 259struct Index { 260 @State message: string = 'Hello World'; 261 262 build() { 263 Column() { 264 // 引用HAR的字符串资源 265 Text($r('app.string.hello_har')) 266 .id('stringHar') 267 .fontFamily('HarmonyHeiTi') 268 .fontColor($r('app.color.text_color')) 269 .fontSize(24) 270 .fontWeight(500) 271 .margin({ top: '40%' }) 272 273 List() { 274 ListItem() { 275 // 引用HAR的图片资源 276 Image($r('app.media.icon_har')) 277 .id('iconHar') 278 .borderRadius('48px') 279 } 280 .margin({ top: '5%' }) 281 .width('312px') 282 } 283 .alignListItem(ListItemAlign.Center) 284 } 285 .width('100%') 286 .backgroundColor($r('app.color.page_background')) 287 .height('100%') 288 } 289} 290``` 291## 编译 292 293HAR可以作为二方库和三方库提供给其他应用使用,如果需要对代码资产进行保护,建议[开启混淆](../arkts-utils/source-obfuscation-guide.md#开启源码混淆)。 294 295[混淆能力](../arkts-utils/source-obfuscation.md)开启后,DevEco Studio在构建HAR时,会对代码进行编译、混淆及压缩处理,保护代码资产。 296 297HAR模块原先默认开启混淆能力,会对API 10及以上的HAR模块,且编译模块为release时,自动进行简单的代码混淆;**从DevEco Studio 5.0.3.600开始,新建工程默认关闭代码混淆功能**,可以在HAR模块的build-profile.json5文件中的ruleOptions字段下的enable进行开启混淆,详情请见[代码混淆](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-build-obfuscation),配置如下所示: 298 299 ```json 300 { 301 "apiType": "stageMode", 302 "buildOption": { 303 }, 304 "buildOptionSet": [ 305 { 306 "name": "release", 307 "arkOptions": { 308 "obfuscation": { 309 "ruleOptions": { 310 "enable": true, 311 "files": [ 312 "./obfuscation-rules.txt" 313 ] 314 }, 315 "consumerFiles": [ 316 "./consumer-rules.txt" 317 ] 318 } 319 } 320 }, 321 ], 322 "targets": [ 323 { 324 "name": "default" 325 } 326 ] 327 } 328 ``` 329 330### 编译生成TS文件 331 332> **场景说明** 333> 334>在HAR中使用[Sendable](../arkts-utils/arkts-sendable.md)时,开启该配置。 335 336> **使用限制** 337> 338> 在依赖TS HAR时,禁止引用TS HAR中的ArkUI组件。 339 340 341HAR模块中arkts文件编译后,默认产物为js文件,想要将产物修改为ts文件,可以在HAR模块下的module.json5文件中将"metadata"字段下的"name"设置为“UseTsHar”,配置如下所示: 342> 343> **说明:** 344> 345> 从DevEco Studio NEXT Beta1(5.0.3.800)版本开始,默认构建字节码HAR,详情参考[构建HAR](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-hvigor-build-har)。 346> 347 348 ```json 349 { 350 "module": { 351 "name": "TsClosedHar", 352 "type": "har", 353 "deviceTypes": [ 354 "default", 355 "tablet", 356 "2in1" 357 ], 358 "metadata": [ 359 { 360 "name": "UseTsHar", 361 "value": "true" 362 } 363 ] 364 } 365 } 366 ``` 367 368## 发布 369 370详见[发布HAR](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-har-publish)。 371 372## 相关实例 373 374- [购物示例应用](https://gitcode.com/openharmony/applications_app_samples/tree/master/code/Solutions/Shopping/OrangeShopping)