【鸿蒙开发基础学习】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" 
      } 
    ] 
  } 
} 
相关推荐
武子康7 分钟前
大数据-212 数据挖掘 机器学习理论 - 无监督学习算法 KMeans 基本原理 簇内误差平方和
大数据·人工智能·学习·算法·机器学习·数据挖掘
使者大牙16 分钟前
【大语言模型学习笔记】第一篇:LLM大规模语言模型介绍
笔记·学习·语言模型
As977_39 分钟前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
ajsbxi42 分钟前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
Rattenking42 分钟前
React 源码学习01 ---- React.Children.map 的实现与应用
javascript·学习·react.js
SameX1 小时前
鸿蒙 Next 电商应用安全支付与密码保护实践
前端·harmonyos
dsywws1 小时前
Linux学习笔记之时间日期和查找和解压缩指令
linux·笔记·学习
道法自然04021 小时前
Ethernet 系列(8)-- 基础学习::ARP
网络·学习·智能路由器
爱吃生蚝的于勒1 小时前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
SuperHeroWu72 小时前
【HarmonyOS】键盘遮挡输入框UI布局处理
华为·harmonyos·压缩·keyboard·键盘遮挡·抬起