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