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