鸿蒙中APP、HAP、HAR、HSP常见问题

645 阅读6分钟

基本概念和关系

  • App是个上架概念,多个HAP打包一起上架。
  • HAP是可以独立运行、分发的,HAP不是复用的,复用的应该是HAR。
  • HAR是静态共享包,每个模块依赖的话都会打包到HAP里。
  • HSP是动态共享包,多模块共用的代码、资源可以使用HSP,提高代码的可重用性和可维护性。

问题一:如何安装打包出来的App包(通过什么命令安装)

App资源包是无法直接安装的,需要通过应用市场下载才能安装,最后通过解析App包安装的还是HAP包。

问题二:HSP打包后,为什么会生成HAR包,它是否会导致App包大小膨胀

HSP编译产生的HAR,只含有配置文件和接口定义,不含有代码逻辑,而且该HAR包仅用于开发态,并不会影响App包的大小。

问题三:HAP/HAR/HSP的关系是什么?是否都可以声明注册Ability和Page?三种类型分别推荐哪些的使用场景?选择原则是什么?

HAP:应用安装和运行的基本单元。支持在配置文件中声明abilities、extensionAbilities组件,支持在配置文件中声明pages页面。

主要使用场景:

  • Entry:应用的主模块,用于实现应用的入口界面、入口图标、主特性功能等。
  • Feature:应用的特性模块,用于实现应用的特性功能。

HAR:静态共享包。编译态复用,不支持在配置文件中声明abilities、extensionAbilities组件,不支持在配置文件中声明pages页面,支持Navigation组件导航。

主要使用场景:

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

HSP:动态共享包。运行时复用,不支持在配置文件中声明abilities、extensionAbilities组件,支持在配置文件中声明pages页面。

主要使用场景:

  • 多模块共用的代码、资源可以使用HSP,提高代码的可重用性和可维护性。
  • 元服务分包预加载。

问题四:Entry模块的HAP和Feature模块的HAP在使用和功能上的区别是什么

  • Entry类型的HAP:是应用的主模块,在module.json5配置文件中的type标签配置为“entry”类型。在同一个应用中,同一设备类型只支持一个Entry类型的HAP,通常用于实现应用的入口界面、入口图标、主特性功能等。
  • Feature类型的HAP:是应用的动态特性模块,在module.json5配置文件中的type标签配置为“feature”类型。一个应用程序包可以包含一个或多个Feature类型的HAP,也可以不包含;Feature类型的HAP通常用于实现应用的特性功能,可以配置成按需下载安装,也可以配置成随Entry类型的HAP一起下载安装。

问题五:在HAP中调用createModuleContext方法获取的Context是什么层级

  1. createModuleContext获取的是基类Context,主要是用来根据不同模块名获取Context,分别指向不同的HSP。
  2. HSP只是一个动态共享包,其包含了静态资源,但是本身是没有上下文的概念。所以需要通过创建Context的方式去获取该资源或者Module的信息。
  3. createModuleContext获取的是一个通用的、模块级的Context,不是ApplicationContext。

问题六:如何正确处理HAR/HSP包模块间的依赖关系

在HarmonyOS应用开发过程中,处理包(HAR/HSP)模块间的依赖是一个常见的需求。正确的依赖处理方式不仅能确保代码的模块化和可维护性,还能减少团队开发中的管理和沟通成本。以下是关于如何引用包模块的推荐和不推荐做法。

  • 推荐方式:

import { add } from "library";

  • 不推荐方式:

使用相对路径或绝对路径进行引用:虽然技术上可行,但这种做法不推荐。使用相对或绝对路径引用模块会破坏模块间的隔离性,增加团队开发的管理和沟通成本,且难以维护。例如:

import { add } from "../../library/src/main/ets/page/Index";

总结来说,为了保持代码的模块化、提高可维护性以及降低团队协作的复杂度,推荐使用包名进行模块间的依赖引用。避免使用相对或绝对路径,以维护项目的结构清晰和高效的团队合作。

问题七:HAR、HSP不能支持ability、Page声明,限制的理由是什么?后续是否会支持

Page:HAR和HSP支持page;只不过HAR中的page需要通过命名路由的方式跳转。

Ability:HAR和HSP不支持,后续也没有支持的计划,推荐在HAP中配置Ability。

问题八:HAR包是否支持依赖传递

例如有三个HAR分别为A、B、C,A依赖B,B依赖C。A是否可以引用C的资源?

解决措施

不支持A直接引用C的资源。A需要直接依赖C,即可引用。

问题九:如何引用HSP库

如需在应用内共享HSP,请将HSP共享包上传至私仓,动态共享包 HSP 包不能直接发布在私仓内,需要先转化为 .tgz 包,请先按以下操作编译生成*.tgz包。

1.将编译模式切换成release模式。

0000000000011111111.20250222123810.60621651091357641103179036469019.png

2.选中HSP模块的根目录,点击Build > Make Module ${libraryName}启动构建。 0000000000011111111.20250222123811.21779836531908875135401387066731.png

3.构建完成后,build目录下生成HSP包产物,其中.tgz用来上传至私仓。

0000000000011111111.20250222123811.37693507817841830775180028660383.png

4.上传到仓里然后通过ohpm install的方式安装到工程的依赖里(oh-package.json5的dependencies字段),然后就可以看到对应HSP里对外共享的方法等。

问题十:一个HSP模块如何快速切换成HAR模块?

解决方案

1.在HSP下的module.json5中,把"type": "shared"修改为"type": "har",删除"deliveryWithInstall"、"pages"字段;

2.删除HSP下的oh-package.json5中"packageType"字段;

3.删除HSP中的页面,如果要以页面的形式使用到的话,就需要改为命名路由的写法;

4.然后再找到HSP下的hvigorfile.ts文件,将里面的hspTasks改为harTasks;

5.最后编译该模块即可。

如编译过程中遇到其他错误,按照提示找到对应位置修改即可。