【鸿蒙开发基础学习】HAR-应用程序包开发与使用

HAR

HAR 简介

HAR(Harmony Archive)是静态共享包,可以包含代码、C++库、资源和配置文件。通过 HAR 可以实现多个模块或多个工程共享 ArkUI 组件、资源等相关代码。

使用场景

  • 作为二方库,发布到 OHPM 私仓,供公司内部其他应用使用。
  • 作为三方库,发布到 OHPM 中心仓,供其他应用使用。

约束限制

  • HAR 不支持在设备上单独安装/运行,只能作为应用模块的依赖项被引用。
  • HAR 不支持在配置文件中声明 UIAbility 组件与 ExtensionAbility 组件。
  • HAR 不支持在配置文件中声明 pages 页面,但是可以包含 pages 页面,并通过命名路由的方式进行跳转。
  • HAR 不支持引用 AppScope 目录中的资源。在编译构建时,AppScope 中的内容不会打包到 HAR 中,因此会导致 HAR 资源引用失败。
  • HAR 可以依赖其他 HAR,但不支持循环依赖,也不支持依赖传递。

创建

通过 DevEco Studio 创建一个 HAR 模块,详见创建库模块。

开发

介绍如何导出 HAR 的 ArkUI 组件、接口、资源,供其他应用或当前应用的其他模块引用。

  • Index.ets 文件:Index.ets 文件是 HAR 导出声明文件的入口,HAR 需要导出的接口,统一在 Index.ets 文件中导出。Index.ets 文件是 DevEco Studio 默认自动生成的,用户也可以自定义,在模块的 oh - package.json5 文件中的 main 字段配置入口声明文件,配置如下所示:
json 复制代码
{ 
  "main": "Index.ets" 
} 
  • 导出 ArkUI 组件
    ArkUI 组件的导出方式与 ts 的导出方式一致,通过 export 导出 ArkUI 组件,示例如下:
javascript 复制代码
// library/src/main/ets/components/mainpage/MainPage.ets
@Component 
export struct MainPage { 
  @State message: string = 'HAR MainPage';

  build() { 
    Column() { 
      Row() { 
        Text(this.message) 
         .fontSize(32) 
         .fontWeight(FontWeight.Bold)
      } 
     .margin({ top: '32px' }) 
     .height(56) 
     .width('624px') 

      Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center, alignContent: FlexAlign.Center }) {
        Column() { 
          Image($r('app.media.pic_empty')).width('33%')
          Text($r('app.string.empty'))
           .fontSize(14) 
           .fontColor($r('app.color.text_color'))
        } 
      }.width('100%') 
     .height('90%') 
    } 
   .width('100%') 
   .height('100%') 
   .backgroundColor($r('app.color.page_background'))
  } 
} 

HAR 对外暴露的接口,在 Index.ets 导出文件中声明如下所示:

javascript 复制代码
// library/Index.ets 
export { MainPage } from './src/main/ets/components/mainpage/MainPage';
  • 导出 ts 类和方法
    通过 export 导出 ts 类和方法,支持导出多个 ts 类和方法,示例如下所示:
javascript 复制代码
// library/src/main/ts/test.ets 
export class Log { 
    static info(msg: string) { 
        console.info(msg); 
    } 
} 

export function func() { 
  return 'har func'; 
} 

export function func2() { 
  return 'har func2'; 
} 

HAR 对外暴露的接口,在 Index.ets 导出文件中声明如下所示:

javascript 复制代码
// library/Index.ets 
export { Log } from './src/main/ts/test';
export { func } from './src/main/ts/test';
export { func2 } from './src/main/ts/test';
  • 导出 native 方法
    在 HAR 中也可以包含 C++编写的 so。对于 so 中的 native 方法,HAR 通过以下方式导出,以导出 libnative.so 的加法接口 add 为例:
javascript 复制代码
// library/src/main/ets/utils/nativeTest.ets
import native from 'liblibrary.so'; 

export function nativeAdd(a: number, b: number): number {
  let result: number = native.add(a, b);
  return result; 
} 

HAR 对外暴露的接口,在 Index.ets 导出文件中声明如下所示:

javascript 复制代码
// library/Index.ets 
export { nativeAdd } from './src/main/ets/utils/nativeTest';

资源

在编译构建 HAP 时,DevEco Studio 会从 HAP 模块及依赖的模块中收集资源文件,如果不同模块下的资源文件出现重名冲突时,DevEco Studio 会按照以下优先级进行覆盖(优先级由高到低):

  • AppScope(仅 API9 的 Stage 模型支持)。
  • HAP 包自身模块。
  • 依赖的 HAR 模块,如果依赖的多个 HAR 之间有资源冲突,会按照工程 oh - package.json5 中 dependencies 下的依赖顺序进行覆盖,依赖顺序在前的优先级较高。例如下方示例中 dayjs 和 lottie 中包含同名文件时,会优先使用 dayjs 中的资源。

说明:

如果在 AppScope/HAP 模块/HAR 模块的国际化目录中配置了资源,在相同的国际化限定词下,合并的优先级也遵循上述规则。同时,国际化限定词中配置的优先级高于在 base 中的配置。如:在 AppScope 的 base 中配置了资源字段,在 HAR 模块的 en_US 中配置了同样的资源字段,则在 en_US 的使用场景中,会更优先使用 HAR 模块中配置的资源字段。

json 复制代码
// oh - package.json5 
{ 
"dependencies": { 
  "dayjs": "^1.10.4", 
  "lottie": "^2.0.0" 
} 
} 

使用

介绍如何配置 HAR 依赖,并引用 HAR 的 ArkUI 组件、接口、资源。

  • 引用 HAR 前的配置:引用 HAR 前,需要先配置对 HAR 的依赖,详见引用 HAR 文件和资源。

  • 引用 HAR 的 ArkUI 组件

    HAR 的依赖配置成功后,可以引用 HAR 的 ArkUI 组件。ArkUI 组件的导入方式与 ts 的导入方式一致,通过 import 引入 HAR 导出的 ArkUI 组件,示例如下所示:

javascript 复制代码
// entry/src/main/ets/pages/IndexSec.ets
import { MainPage } from 'library'; 

@Entry 
@Component 
struct IndexSec { 
  build() { 
    Row() { 
      // 引用 HAR 的 ArkUI 组件 
      MainPage() 
    } 
   .height('100%') 
  } 
} 
  • 引用 HAR 的 ts 类和方法
    通过 import 引用 HAR 导出的 ts 类和方法,示例如下所示:
javascript 复制代码
// entry/src/main/ets/pages/Index.ets 
import { Log } from 'library'; 
import { func } from 'library'; 

@Entry 
@Component 
struct Index { 
  @State message: string = 'Hello World';

  build() { 
    Column() { 
      Text(this.message) 
       .fontFamily('HarmonyHeiTi') 
       .fontWeight(FontWeight.Bold) 
       .fontSize(32) 
       .fontWeight(700) 
       .fontColor($r('app.color.text_color'))
       .textAlign(TextAlign.Start) 
       .margin({ top: '32px' }) 
       .width('624px') 

      //引用 HAR 的 ts 类和方法 
      Button($r('app.string.button')) 
       .id('button') 
       .height(48) 
       .width('624px') 
       .margin({ top: '4%' }) 
       .type(ButtonType.Capsule) 
       .fontFamily('HarmonyHeiTi') 
       .borderRadius($r('sys.float.ohos_id_corner_radius_button'))
       .backgroundColor($r('app.color.button_background'))
       .fontColor($r('sys.color.ohos_id_color_foreground_contrary'))
       .fontSize($r('sys.float.ohos_id_text_size_button1'))
       .onClick(() => { 
          // 引用 HAR 的类和方法 
          Log.info('har msg'); 
          this.message = 'func return: ' func();
        }) 
    } 
   .width('100%') 
   .backgroundColor($r('app.color.page_background'))
   .height('100%') 
  } 
} 
  • 引用 HAR 的 native 方法
    通过 import 引用 HAR 导出的 native 方法,示例如下所示:
javascript 复制代码
// entry/src/main/ets/pages/Index.ets 
import { nativeAdd } from 'library'; 

@Entry 
@Component 
struct Index { 
  @State message: string = 'Hello World';

  build() { 
    Column() { 
      Text(this.message) 
       .fontFamily('HarmonyHeiTi') 
       .fontWeight(FontWeight.Bold) 
       .fontSize(32) 
       .fontWeight(700) 
       .fontColor($r('app.color.text_color'))
       .textAlign(TextAlign.Start) 
       .margin({ top: '32px' }) 
       .width('624px') 

      //引用 HAR 的 native 方法 
      Button($r('app.string.native_add'))
       .id('nativeAdd') 
       .height(48) 
       .width('624px') 
       .margin({ top: '4%', bottom: '6%' })
       .type(ButtonType.Capsule) 
       .fontFamily('HarmonyHeiTi') 
       .borderRadius($r('sys.float.ohos_id_corner_radius_button'))
       .backgroundColor($r('app.color.button_background'))
       .fontColor($r('sys.color.ohos_id_color_foreground_contrary'))
       .fontSize($r('sys.float.ohos_id_text_size_button1'))
       .onClick(() => { 
          this.message = 'esult: ' nativeAdd(1, 2);
        }) 
    } 
   .width('100%') 
   .backgroundColor($r('app.color.page_background'))
   .height('100%') 
  } 
} 
  • 引用 HAR 的资源
    通过 $r 引用 HAR 中的资源,例如在 HAR 模块的 src/main/resources 里添加字符串资源(在 string.json 中定义,name:hello_har)和图片资源(icon_har.png),然后在 Entry 模块中引用该字符串和图片资源的示例如下所示:
javascript 复制代码
// entry/src/main/ets/pages/Index.ets 
@Entry 
@Component 
struct Index { 
  @State message: string = 'Hello World';

  build() { 
    Column() { 
      // 引用 HAR 的字符串资源 
      Text($r('app.string.hello_har'))
       .id('stringHar') 
       .fontFamily('HarmonyHeiTi') 
       .fontColor($r('app.color.text_color'))
       .fontSize(24) 
       .fontWeight(500) 
       .margin({ top: '40%' }) 

      List() { 
        ListItem() { 
          // 引用 HAR 的图片资源 
          Image($r('app.media.icon_har'))
           .id('iconHar') 
           .borderRadius('48px') 
        } 
       .margin({ top: '5%' }) 
       .width('312px') 
      } 
     .alignListItem(ListItemAlign.Center)
    } 
   .width('100%') 
   .backgroundColor($r('app.color.page_background'))
   .height('100%') 
  } 
} 

编译

HAR 可以作为二方库和三方库提供给其他应用使用,如果需要对代码资产进行保护时,建议开启混淆能力。

  • 混淆能力:混淆能力开启后,DevEco Studio 在构建 HAR 时,会对代码进行编译、混淆及压缩处理,保护代码资产。

说明:

  • 编译 HAR 时,如果没有开启混淆能力,编译后的产物是源码文件。
  • 仅 Stage 模型的 ArkTS 工程支持混淆。
  • HAR 开启混淆后资源 ID 为 - 1,ResourceManager 等通过 ID 获取资源的 API 不再生效。

对于 API 10 及以上版本,HAR 模块默认开启混淆能力,可以在 HAR 模块的 build - profile.json5 文件中的 ruleOptions 字段下的 enable 进行设置,配置如下所示:

json 复制代码
{ 
  "apiType": "stageMode", 
  "buildOption": { 
  }, 
  "buildOptionSet": [ 
    { 
      "name": "release", 
      "arkOptions": { 
        "obfuscation": { 
          "ruleOptions": { 
            "enable": true, 
            "files": [ 
              "./obfuscation - rules.txt"
            ] 
          }, 
          "consumerFiles": [ 
            "./consumer - rules.txt" 
          ] 
        } 
      } 
    }, 
  ], 
  "targets": [ 
    { 
      "name": "default" 
    } 
  ] 
} 
  • 编译生成 TS 文件
    说明:
    在 HAR 中使用 Sendable class 时,开启该配置。

使用限制:

在依赖 TS HAR 时,禁止引用 TS HAR 中的 ArkUI 组件。

HAR 模块中 arkts 文件编译后,默认产物为 js 文件,想要将产物修改为 ts 文件,可以在 HAR 模块 src/main 目录下的 module.json5 文件中的"metadata"字段下的"UseTsHar"进行设置,配置如下所示:

json 复制代码
{ 
  "module": { 
    "name": "TsClosedHar", 
    "type": "har", 
    "deviceTypes": [ 
      "default", 
      "tablet", 
      "2in1" 
    ], 
    "metadata": [ 
      { 
        "name": "UseTsHar", 
        "value": "true" 
      } 
    ] 
  } 
} 
相关推荐
时光追逐者21 分钟前
MongoDB从入门到实战之MongoDB快速入门(附带学习路线图)
数据库·学习·mongodb
一弓虽26 分钟前
SpringBoot 学习
java·spring boot·后端·学习
genggeng不会代码2 小时前
用于协同显著目标检测的小组协作学习 2021 GCoNet(总结)
学习
搞机小能手2 小时前
六个能够白嫖学习资料的网站
笔记·学习·分类
高心星4 小时前
HarmonyOS 5.0应用开发——MVVM模式的应用
harmonyos·mvvm·鸿蒙5.0·备忘录应用
别说我什么都不会4 小时前
【仓颉三方库】工具类—— compress4cj
harmonyos
别说我什么都不会4 小时前
【仓颉三方库】工具类—— uuid4cj
harmonyos
The_cute_cat5 小时前
25.4.22学习总结
学习
冰茶_5 小时前
.NET MAUI 发展历程:从 Xamarin 到现代跨平台应用开发框架
学习·microsoft·微软·c#·.net·xamarin
帅云毅6 小时前
Web3.0的认知补充(去中心化)
笔记·学习·web3·去中心化·区块链