• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# HAR
2A Harmony Archive (HAR) is a static shared package that can contain code, C++ libraries, resource files, and configuration files (also called profiles). It enables modules and projects to share code of ArkUI components, resources, and more.
3
4## When to Use
5- As a second-party library for internal applications, by being released to an OHPM private repository.
6- As a third-party library for external applications, by being released to the OHPM central repository.
7
8## Constraints
9
10- A HAR can only be referenced as a dependency of an application module. It cannot be installed or run independently on a device.
11- No [UIAbility](../application-models/uiability-overview.md) or [ExtensionAbility](../application-models/extensionability-overview.md) can be declared in the configuration file of a HAR.
12- The configuration file of a HAR does not support declaration of the [pages](./module-configuration-file.md#pages) tag. Still, it can include pages, which can be redirected through a [named route](../ui/arkts-routing.md#named-route).
13- The HAR does not support referencing resources in the **AppScope** folder. This is because the content in the **AppScope** folder is not packaged into the HAR during building.
14- A HAR can depend on other HARs, but does not support cyclic dependency or dependency transfer.
15
16## Creating a HAR
17You can create a HAR module in DevEco Studio.
18
19
20## Developing a HAR
21
22You can export the ArkUI components, APIs, and other resources of a HAR for other applications or intra-application modules to reference.
23
24The **Index.ets** file acts as the entry of the HAR export declaration file and is where the HAR exports APIs. This file is automatically generated by DevEco Studio by default. You can specify another file as the entry declaration file in the **main** field in the **oh-package.json5** file of the module. The code snippet is as follows:
25```json
26{
27  "main": "Index.ets"
28}
29```
30### Exporting ArkUI Components
31Use **export** to export the ArkUI components. The code snippet is as follows:
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```
65In the **Index.ets** file, declare the APIs that the HAR exposes to external systems. The code snippet is as follows:
66```ts
67// library/Index.ets
68export { MainPage } from './src/main/ets/components/mainpage/MainPage';
69```
70### Exporting TS Classes and Methods
71Use **export** to export TS classes and methods. Multiple TS classes and methods can be exported at the same time. The code snippet is as follows:
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```
88In the **Index.ets** file, declare the APIs that the HAR exposes to external systems. The code snippet is as follows:
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### Exporting Native Methods
97The HAR can contain .so files written in C++. Native methods in the .so file can be exported from the HAR in the following way. In the example, the **add** API in the **libnative.so** file is exported.
98```ts
99// library/src/main/ets/utils/nativeTest.ts
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```
107In the **Index.ets** file, declare the APIs that the HAR exposes to external systems. The code snippet is as follows:
108```ts
109// library/Index.ets
110export { nativeAdd } from './src/main/ets/utils/nativeTest';
111```
112
113### Resources
114Resources are packed into the HAR during building. Specifically, DevEco Studio collects resource files from the HAP module and its dependent modules, and overwrites the resource files with the same name (if any) based on the following priorities (in descending order):
115- AppScope (only for the stage model of API version 9)
116- Modules in the HAP
117- Dependent HAR modules<br>If resource conflicts occur between dependent HAR modules, they are overwritten based on the dependency sequence indicated under **dependencies** in the **oh-package.json5** file. The module that is higher in the dependency sequence list has a higher priority. For example, in the following example, if **dayjs** and **lottie** folders contain files with the same name, resources in **dayjs** are used preferentially.
118> **NOTE**
119>
120> With regard to resources in the internationalization folder of **AppScope**, HAP, and HAR directories, the preceding priority rules also apply to resources with the same internationalization qualifier. In addition, resources with internationalization qualifiers are prioritized over those in the **base** folder. For example, if resources with the same name are configured in both the **base** folder under **AppScope** and the **en_US** folder of a HAR, the one in the **en_US** folder is prioritized for internationalization purposes.
121```
122// oh-package.json5
123{
124  "dependencies": {
125    "dayjs": "^1.10.4",
126    "lottie": "^2.0.0"
127  }
128}
129```
130
131## Using a HAR
132
133Using a HAR means referencing its ArkUI components, APIs, and resources.
134
135To start with, configure dependency on the HAR.
136
137### Referencing ArkUI Components
138
139After configuring the dependency on the HAR, you can reference ArkUI components exported from the HAR by using **import**. The code snippet is as follows:
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      // Reference the ArkUI component in the HAR.
150      MainPage()
151    }
152    .height('100%')
153  }
154}
155```
156### Referencing TS Classes and Methods
157To reference the TS classes and methods exported from the HAR, use **import** as follows:
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      // Reference TS classes and methods.
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          // Reference TS classes and methods in the 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### Referencing Native Methods
206To reference the native methods exported from the HAR, use **import** as follows:
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      // Reference the native method in the HAR.
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### Referencing Resources
252Use **$r** to reference resources in the HAR. For example, add the **name: hello_har** string (defined in the **string.json** file) and **icon_har.png** image to the **src/main/resources** directory of the HAR module, and then reference the string and image in the entry module. The code snippet is as follows:
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      // Reference the string in the 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          // Reference the image in the 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## Building a HAR
290
291As aforementioned, a HAR can be used as a second-party or third-party library for other applications.
292
293To better protect your source code, enable obfuscation for the HAR so that DevEco Studio compiles, obfuscates, and compresses code during HAR building.
294
295> **NOTE**
296>
297> Obfuscation is only available for ArkTS projects in the stage model.
298> When obfuscation is enabled, the resource ID is **-1**, and APIs that obtain resources by ID, such as [ResourceManager](../reference/apis-localization-kit/js-apis-resource-manager.md), do not take effect.
299
300
301Since API version 10, obfuscation is enabled by default, and can be set through the **enable** field under **ruleOptions** in the **build-profile.json5** file of the HAR. The configuration is as follows:
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## Releasing a HAR
335
336Follow the [instructions](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/creating_har_api9-0000001518082393-V3#section1213451811512) to release a HAR.
337
338