5 分钟速读
- 鸿蒙系统支持多类型设备,架构顶层的产品层往往根据目标设备/元服务等维度进行拆分(多个 HAP),客户端开发者可以理解为项目对 pad 和 phone 提供不同的包。
- 鸿蒙平台有若干编译产物类型,其中共享代码库主要分为 HSP(动态库)和 HAR(静态库)。
- 鸿蒙官方文档推荐使用 HSP(动态库),推荐理由是可以减少包大小。
- 官方文档没有提到的是鸿蒙目前的包管理工具 ohpm(对标 npm)仅支持 HAR 类型的包,也就是静态包。
- 以上,意味着做鸿蒙开发大概率(只要用第三方库)会面临 HSP 和 HAR 共存的问题,处理不好会导致三方库 HAR 重复多次入包,造成包体积膨胀。
- 通过技术手段将 HAR 以 HSP 的方式入包,解决动静态库共存问题是目前实践的最优解。
Emmm...如果你还没接触过 HAR/HSP/HAP 这些概念也不要紧,后面会有对应介绍。只要你们公司的 App 计划要做鸿蒙平台的开发适配,看下去就应该有所收获。
为什么会包膨胀?
鸿蒙平台编译产物
进入正题之前,先允许我为没有弄清楚鸿蒙编译产物的同学科普一下这篇文章用到的三种鸿蒙编译产物:
- HAP,Harmony Ability Package 的简写,说人话就是鸿蒙应用包内承载业务代码的编译产物类型,一个鸿蒙商城的 APP 包内至少需要一个 HAP。
- HAR,Harmony Archive 的简写,静态库。
- HSP,Harmony Shared Package 的简写,动态库。
上图简单画了一下鸿蒙 Next 的编译产物:图中假定项目为 Phone 和 Pad 两种设备类型提供了独立的包(有些公司的要求和设计比较苛刻,鸿蒙一多特性可能无法还原设计要求);用颜色标识了不同的包依赖不同的 Feature 模块(HSP);鸿蒙官方推荐模块化的代码以 HSP 方式入包,所以图里暂时没有加入 HAR。
官方推荐 HSP
鸿蒙官方其实推荐做架构中的模块化时选择 HSP,主要原因是 HSP 有利于控制包大小。
包管理仅支持 HAR
目前鸿蒙平台的包管理工具 ohpm 仅支持 HAR 的静态包,也就是说只要我们的项目使用 ohpm 托管的库就会不可避免的引入 HAR,导致类似上节图左侧的包结构。
如图,如果不能恰当的处理引入的 HAR,包大小问题并不会得到解决,甚至会进一步劣化
静态 vs 动态
作为一名架构师,区分静态库和动态库是基础中的基础,也是这篇文章的重点内容:
- 静态库,对应静态链接,出包前执行链接。
- 动态库,对应动态链接,App 启动时执行链接。
链接工作主要做什么呢?拿 C 语言举例,假设一个源文件调用了另一个源文件中定义的函数,那么需要让程序在执行时知道去哪找到这个函数的定义,这样程序才可以顺利执行。
举个例子,我们看书的时候可能遇到一些晦涩难懂的词汇,这些词汇往往出自某典故,书里一般会提供角标指向对应的典故。我们读到这些词汇时按照角标找到典故就可以理解词汇的意思,然后翻回来接着往下读。
- 静态链接呢,就好比典故和书的内容放在一起,以一本书的形式出版,书的页数自然就变多了 。读者查询起来会比较快捷,简单理解就是空间换时间。
- 动态链接呢,则好比是书里的角标直接写明出自某某作者某某书籍的某章节,不和这本书放在一起出版,书的页数不变 。读者查询需要购买两本书跳着看,简单理解就是时间换空间。
解决方案
包体积膨胀
弄清楚 HSP 和 HAR 对应的动态和静态,也就理解了一开始的几幅图中为什么 HAR 总会多次分裂,处理不当确实会让 HAR 重复入包造成我们说的「包体积膨胀」问题。
上图的 .abc 就是鸿蒙代码的编译产物,如果处理不当编译产物的大小有明显差异
最差的情况,包体积膨胀的公式:(HAP数 + HSP数) * 三方库 HAR 包体积总和;可以想象随业务需求的发展这个膨胀系数还是挺恐怖的。
思路
如果可以将通过 ohpm 引入的 HAR 包转成 HSP 的形式,这个问题就可以解决。
我们可以通过新建一个 HSP 来做一个伞结构包,将用到的 HAR 包依赖收敛到这个伞 HSP 包,通过伞 HSP 包间接 export 导出底部的 HAR 内容提供给上层使用。
实操
上面的思路落地方式是通过新建一个 HSP,将我们用到的第三方库 HAR 依赖统一放到这个 HSP 的 oh-package.json5 文件做收敛形成伞结构 HSP:
接着,在伞结构 HSP 对外导出的 Index.ets 文件中做一个中转导出:
中转 export 时可以利用通配符 * 号来全量导出
总结与展望
其实伞状 HSP 的方式不一定是把所有的 HAR 包都收敛到一个 HSP:如果业务有拆分多个 HAP 的需求,每个 HAP 可能用到的 HAR 包也不一样。可以根据自己负责的业务项目实际情况结合本文来做更加精细化的 HAR 转 HSP 包装。
其实 ohpm 作为一个包管理平台本身不应该限制包的引入方式一定要是静态的 HAR,这一点在参加 2024 鸿蒙生态学堂·北京站时和鸿蒙那边的老师交流过,答复还是说 ohpm 支持 HSP 的诉求不常见且有替代思路(本文),鸿蒙目前要做的高优事情也很多,短期应该不大会做这方面的支持,所以我才把之前工作实践过程中的这套方案分享出来,希望可以对做鸿蒙平台开发工作的朋友有帮助。
最后,简单自我介绍一下,我之前是一名 iOS Developer,目前在腾讯负责组内项目的鸿蒙平台开发适配工作。有一个微信公众号,在上面可以直接联系到我本人,偶尔也会在上面分享一些从业十年的心得,希望大家可以联系我一起学习交流~