本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
鸿蒙(HarmonyOS)开发中,分包加载技术通过将应用拆分为多个模块(如Entry HAP和Feature HAP),实现按需加载和资源优化。以下是关键实现示例:
一、核心概念解析
1. 模块类型与角色
模块类型 | 标识(module.json5) | 作用 | 示例场景 |
---|---|---|---|
Entry HAP | "type": "entry" | 主模块,包含应用入口和核心功能,安装时必下载 | 应用的首页、登录模块 |
Feature HAP | "type": "feature" | 功能模块,按需动态加载(可独立更新) | 支付、设置、商品详情页 |
HSP | "type": "shared" | 动态共享包,多个HAP共享代码/资源(运行时加载) | 网络请求库、UI组件库 |
HAR | 无type字段 | 静态共享包,编译时嵌入(不能动态更新) | 工具类、通用配置 |
2. 关键配置字段
deliveryWithInstall
true
:随主包安装(如核心模块)false
:动态下载(如非紧急功能)
{
"module": {
"name": "feature_payment",
"type": "feature",
"deliveryWithInstall": false // 支付模块动态加载
}
}
preloads
声明需要预加载的模块列表(需在module.json5
的metadata
中配置):
"metadata": [{
"name": "preloads",
"value": "feature_payment,feature_settings" // 逗号分隔的模块名
}]
3. 动态加载流程
二、分包加载的核心场景与优势
-
适用场景
- 元服务轻量化:单个HAP/HSP需≤2MB,总包≤10MB。
- 功能模块独立:如电商应用的支付、商品详情等模块可拆分为独立Feature HAP 。
- 多设备适配:不同设备(手机/平板)加载不同模块组合 。
-
优势
- 减少安装包体积:非核心功能动态下载。
- 提升启动速度:主模块(Entry HAP)优先加载,子模块按需加载。
- 灵活部署:跨设备共享模块(如手机缓存供平板使用)。
三、分包加载的实现示例
1. 模块配置(module.json5)
{
"module": {
"name": "feature_payment", // 支付模块
"type": "feature", // 动态特性模块
"deliveryWithInstall": false, // 不随主包安装
"abilities": [
{
"name": "PaymentAbility",
"srcEntrance": "./ets/payment/PaymentAbility.ets",
"label": "支付功能",
"icon": "$media:payment_icon"
}
]
}
}
关键字段:
type: "feature"
:标记为动态模块。deliveryWithInstall: false
:需运行时下载 。
2. 主模块动态加载子模块
// 主模块(Entry HAP)中动态加载支付模块
import featureAbility from '@ohos.ability.featureAbility';
async function loadPaymentModule() {
try {
// 检查模块是否已安装
let bundleName = "com.example.app";
let moduleName = "feature_payment";
let installStatus = await featureAbility.checkAbilityInstall({
bundleName: bundleName,
moduleName: moduleName
});
if (!installStatus) {
// 下载并安装模块
await featureAbility.requestAbilityInstall({
bundleName: bundleName,
moduleName: moduleName,
abilityName: "PaymentAbility"
});
}
// 启动支付Ability
featureAbility.startAbility({
bundleName: bundleName,
moduleName: moduleName,
abilityName: "PaymentAbility"
});
} catch (err) {
console.error("加载支付模块失败:", err);
}
}
说明:
checkAbilityInstall
:验证模块是否已安装。requestAbilityInstall
:触发下载安装(需配置AGC云控) 。
四、分包加载的优化策略
-
预加载机制
- 配置预加载列表:在
module.json5
中声明preloads
字段,提前下载高频模块 。 - 分布式缓存:通过
@ohos.distributedCache
跨设备共享已下载模块。
- 配置预加载列表:在
-
资源隔离与共享
- HSP动态共享库:公共代码(如网络请求库)封装为HSP,多个HAP共享同一份代码
"dependencies": {
"shared": "file:../shared.hsp" // 引用本地HSP
}
- HAR静态共享库:基础工具类打包为HAR,编译时嵌入 。
- 体积控制
- 资源压缩:在
module.json5
中设置compressNativeLibs: true
压缩so库 。 - 按设备分发:通过
distroFilter
过滤设备类型,仅下发适配模块 。
- 资源压缩:在
五、注意事项
1. 模块拆分原则
- 按功能独立性拆分 例如:将“用户中心”和“消息通知”拆分为两个Feature HAP,避免互相依赖。
- 控制模块体积 单个HAP建议≤2MB(元服务强制要求),可通过
compressNativeLibs: true
压缩资源。 - 避免循环依赖 HSP共享库需设计为单向依赖(如A依赖B,但B不能反向依赖A)。
2. 动态加载优化
- 按需触发加载 在用户行为预测阶段加载(如点击“购物车”前静默预加载支付模块):
// 在用户浏览商品时预加载支付模块
onProductPageShow() {
setTimeout(() => {
loadModule("feature_payment"); // 延迟加载减少首屏压力
}, 3000);
}
- 降级策略 动态加载失败时提供替代方案:
try {
await loadModule("feature_payment");
} catch (err) {
showToast("功能加载中,请稍后重试");
navigateTo("lite_payment_page"); // 轻量级备用页面
}
3. 资源管理
- 共享资源处理
- HSP共享库:将图片、字体等资源放在HSP中,避免多模块重复打包。
- 资源冲突解决:通过
resourceManager
指定资源路径:
let resource = getContext().resourceManager;
let img = await resource.getMediaContent($r("app.media.icon"));
六、常见问题解决
1. 模块加载超时
- 现象:
requestAbilityInstall
长时间无响应 - 解决:
- 检查网络状态和设备存储空间
- 设置超时中断(默认30秒):
const controller = new AbortController();
setTimeout(() => controller.abort(), 15000); // 15秒超时
requestAbilityInstall({ signal: controller.signal });
2. 跨设备共享失败
- 现象:手机下载的模块无法在平板上使用
- 解决:
- 确认
distroFilter
配置匹配设备类型:
- 确认
"distroFilter": {
"apiVersion": ["4.0.0"], // 兼容API版本
"screenShape": ["round", "rect"] // 设备屏幕类型
}
- 使用
distributedBundle
同步模块:
import distributedBundle from '@ohos.distributedBundle';
distributedBundle.sync("feature_payment", (err) => { ... });
3. 资源ID冲突
- 现象:不同模块的
$r('app.string.title')
返回相同ID - 解决:
- 使用资源别名区分:
// feature_payment/resources/base/element/string.json
{
"name": "payment_title",
"value": "支付中心"
}
- 运行时通过模块名限定资源:
let res = await getResource("feature_payment", "payment_title");
七、总结
- 模块粒度:每个Feature HAP应代表一个完整用户场景(如“视频播放”)。
- 加载时机:结合用户行为分析预加载(如进入购物流程前加载支付模块)。
- 跨设备协同:利用分布式能力实现“一次下载,多端使用”。
- 安全边界:敏感功能模块(如支付)需加密校验HAP完整性。