当前位置: 首页 > news >正文

鸿蒙 动态下载增强功能:产品特性按需分发

随着HarmonyOS应用的持续发展,应用的功能越来越丰富。但实际上,80%的用户使用时长都集中在20%的特性上,其余功能可能只面向部分用户。

为了避免用户首次下载应用耗时过长及过多占用用户空间,应用市场服务提供了按需分发的能力。

一、什么是按需分发?

一个应用程序被打包成多个安装包,安装包包含了所有的应用程序代码和静态资源。用户从应用市场下载的应用只包含基本功能的安装包,当用户需要使用增强功能时,相应安装包将会从服务器下载到设备上。

优势说明
减少首次下载耗时只下载基础包
节省用户空间按需下载,不预先安装
提升用户体验只下载用到的功能

二、限制

限制项说明
应用上架应用需要上架应用市场
设备支持Phone、Tablet、PC/2in1、TV(19+)
模拟器支持ARM版本、X86版本模拟器支持接入调试

三、核心接口

接口描述
getInstalledModule(moduleName)查询模块安装信息
createModuleInstallRequest(context)创建按需加载请求对象
addModule(moduleName)添加要按需加载的模块名
fetchModules(moduleInstallRequest)按需加载请求接口,异步返回结果
cancelTask(taskId)取消下载任务
showCellularDataConfirmation(context, taskId)流量提醒弹窗接口
on('moduleInstallStatus', callback, timeout)监听当前应用下载任务的进度
off('moduleInstallStatus', callback)取消监听

四、开发步骤

4.1 获取模块安装信息

import { moduleInstallManager } from '@kit.AppGalleryKit'; // 查询指定模块的安装信息 const moduleName: string = 'AModule'; const moduleInfo: moduleInstallManager.InstalledModule = moduleInstallManager.getInstalledModule(moduleName);

4.2 创建按需加载的请求实例

import { moduleInstallManager } from '@kit.AppGalleryKit'; import type { common } from '@kit.AbilityKit'; // 获取上下文(只支持UIAbilityContext和ExtensionContext) const context: common.UIAbilityContext | common.ExtensionContext = this.getUIContext().getHostContext() as common.UIAbilityContext; // 创建请求对象 const myModuleInstallProvider = new moduleInstallManager.ModuleInstallProvider(); const myModuleInstallRequest = myModuleInstallProvider.createModuleInstallRequest(context);

4.3 请求按需加载模块

// 添加要加载的模块名 const moduleNameA: string = 'AModule'; const moduleNameB: string = 'BModule'; const aResult = myModuleInstallRequest.addModule(moduleNameA); const bResult = myModuleInstallRequest.addModule(moduleNameB); // 发起按需加载请求 try { moduleInstallManager.fetchModules(myModuleInstallRequest) .then(() => { console.info('Succeeded in fetching Modules data.'); }) } catch (error) { console.error(`fetching Modules error: ${error.code}, ${error.message}`); }

4.4 使用动态模块

步骤1:配置动态模块(AModulelib)

在动态模块的module.json5中设置deliveryWithInstallfalse,标识该模块不会在应用安装时一起下载。

{ "module": { "name": "AModulelib", "deliveryWithInstall": false } }
步骤2:定义动态模块功能

Calc.ets

export function add(a: number, b: number) { return a + b; }

DateComponent.ets

@Component struct DateComponent { build() { Column() { Text('我是AModulelib中的组件') .margin(10); } .width(300) .backgroundColor(Color.Yellow); } } @Builder export function showDateComponent() { DateComponent() }

Index.ets(导出)

export { add } from './src/main/ets/utils/Calc'; export { showDateComponent } from './src/main/ets/components/DateComponent';
步骤3:配置动态依赖(entry模块)

在entry的oh-package.json5中添加:

{ "dynamicDependencies": { "AModulelib": "file:../AModulelib" } }
步骤4:检查并加载动态模块
import { moduleInstallManager } from '@kit.AppGalleryKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { BusinessError, Callback } from '@kit.BasicServicesKit'; import { common } from '@kit.AbilityKit'; @Entry @Component struct Index { @BuilderParam AModulelibComponent: Function; @State countTotal: number = 0; @State isShow: boolean = false; build() { Column() { Button('调用增量模块中的add功能:3+6') .onClick(() => { this.initAModulelib(() => { import('AModulelib').then((ns: ESObject) => { this.countTotal = ns.add(3, 6); }).catch((error: BusinessError) => { hilog.error(0, 'TAG', `add error: ${error.code}, ${error.message}`); }); }) }); Text('计算结果:' + this.countTotal).margin(10); Button('调用增量模块中的showDateComponent功能') .onClick(() => { this.initAModulelib(() => { import('AModulelib').then((ns: ESObject) => { this.AModulelibComponent = ns.showDateComponent; this.isShow = true; }).catch((error: BusinessError) => { hilog.error(0, 'TAG', `showDateComponent error: ${error.code}, ${error.message}`); }); }) }); if (this.isShow) { this.AModulelibComponent() } } .width('100%') .height('100%') } // 检查是否已加载AModulelib包 private initAModulelib(successCallBack: Callback<void>): void { try { const result = moduleInstallManager.getInstalledModule('AModulelib'); if (result?.installStatus === moduleInstallManager.InstallStatus.INSTALLED) { hilog.info(0, 'TAG', 'AModulelib installed'); successCallBack(); } else { hilog.info(0, 'TAG', 'AModulelib not installed'); this.fetchModule('AModulelib', successCallBack); } } catch (error) { hilog.error(0, 'TAG', `getInstalledModule error: ${error.code}, ${error.message}`); } } // 监听下载进度 private onListenEvents(successCallBack: Callback<void>): void { const timeout = 3 * 60; // 3分钟,最大30分钟 moduleInstallManager.on('moduleInstallStatus', (data) => { if (data.taskStatus === moduleInstallManager.TaskStatus.INSTALL_SUCCESSFUL) { successCallBack(); this.showToastInfo('install success'); } }, timeout); } // 加载指定包 private fetchModule(moduleName: string, successCallBack: Callback<void>): void { try { const context = this.getUIContext().getHostContext() as common.UIAbilityContext; const moduleInstallProvider = new moduleInstallManager.ModuleInstallProvider(); const moduleInstallRequest = moduleInstallProvider.createModuleInstallRequest(context); moduleInstallRequest.addModule(moduleName); moduleInstallManager.fetchModules(moduleInstallRequest) .then((data) => { if (data.code === moduleInstallManager.RequestErrorCode.SUCCESS) { this.onListenEvents(successCallBack); } else { hilog.info(0, 'TAG', 'fetchModules failure'); } }) .catch((error: BusinessError) => { hilog.error(0, 'TAG', `fetchModules error: ${error.code}, ${error.message}`); }); } catch (error) { hilog.error(0, 'TAG', `handleFetchModules error: ${error.code}, ${error.message}`); } } private showToastInfo(msg: string) { this.getUIContext().getPromptAction().showToast({ message: msg, duration: 2000 }); } }

五、接入调试功能

5.1 调试前提

产品特性按需分发提供了接入调试功能,支持开发者在接入过程中进行调试,应用无需上架应用市场

5.2 调试步骤

步骤操作
1使用调试证书签名应用,本地编译构建entry.hap和AModulelib.hsp
2通过HDC命令或DevEco Studio安装基础包:hdc install entry.hap
3打开开发者调试模式:设置 → 机型 → 关于手机 → 连续点击软件版本7次
4访问设备沙箱路径,创建cache/moduleinstall/AModulelib目录
5将AModulelib.hsp上传至对应模块目录下(确保有读写权限)

5.3 工作原理

安装包上传后,按照正常业务流程调用API,无需改动参数即可安装好模块调试包。监听到安装成功后,对应模块目录下的文件会被自动删除。

六、业务流程

用户下载基础包(entry.hap) ↓ 用户使用增强功能 ↓ 应用检查模块是否已安装 ↓ 未安装 → 调用fetchModules下载动态安装包 ↓ 动态安装包下载完成 ↓ 通过on接口告知用户下载结果 ↓ 使用动态import调用模块功能
要点说明
配置关键deliveryWithInstall: false模块不随应用安装
依赖配置dynamicDependenciesentry模块动态依赖
检查安装getInstalledModule判断模块是否已安装
下载模块fetchModules按需下载
使用方式动态import()加载模块功能
监听进度on('moduleInstallStatus')监听下载结果

开发流程

配置动态模块(deliveryWithInstall: false) ↓ 配置动态依赖(oh-package.json5) ↓ 检查模块是否已安装(getInstalledModule) ↓ 未安装则下载(fetchModules + on监听) ↓ 安装成功后动态import使用模块功能

一句话

鸿蒙中产品特性按需分发通过将增强功能配置为deliveryWithInstall: false,在entry模块中配置dynamicDependencies,运行时通过getInstalledModule检查、fetchModules下载、动态import()使用,实现用户按需下载所需功能模块,减少首次下载时间和存储空间占用。

http://www.jsqmd.com/news/729283/

相关文章:

  • 2026成都冷藏冷冻冰袋厂家排行:成都吸塑包装设计定制、成都吸塑厂、成都吸塑托盘、成都吸塑盒、成都定制泡沫箱、成都泡沫包装盒选择指南 - 优质品牌商家
  • RTeAAL Sim:张量代数优化RTL仿真的核心技术解析
  • UE5与Unity:商业引擎的困境与孪大师的破局之道
  • HAPS太贵?国产芯华章 vs 三巨头:手把手教你评估与搭建高性价比SoC FPGA原型验证平台
  • 别再死记硬背了!用Python+Jupyter Notebook可视化理解流体力学核心概念(密度、雷诺数、管路阻力)
  • 世纪华通年营收379亿:净利56亿 同比增362% 拟投资60亿理财
  • 如何高效开启ZTE光猫工厂模式:专业网络运维的完整实战指南
  • 文章十五:ElasticSearch 运用ingest加工索引数据
  • 手把手教你学Simulink——基于Simulink的扰动观测器(DOB)负载扰动补偿
  • 系统架构设计师论文预测题目2:论云原生架构下的可观测性系统设计
  • 芯片展哪家好?聚焦芯片前沿技术,甄选业内高人气专业芯片展 - 品牌2026
  • 电商导购 Agent:个性化推荐与下单 Harness
  • 关于搭建运维监控系统(Prometheus+Grafana)
  • NVIDIA TAO实战:手写字符检测与识别模型优化
  • 使用Python快速编写第一个调用Taotoken多模型API的脚本
  • 空间计算领域领军企业是哪家?镜像视界
  • VLFM复现!
  • 基于文本控制的PET医学影像降噪技术解析
  • EchoDistill:扩散模型一步个性化新方法解析
  • 大模型微调实战:LoRA 微调 LLaMA 2 踩坑全解+数据集预处理+训练调优+落地部署(8G显存可跑)
  • 如何高效使用跨平台自动化工具:KeymouseGo 鼠标键盘录制实战指南
  • 再战齿槽力!用Anti-Notch抑制齿槽力扰动效果竟然出乎意料的好!
  • 最简单把deepseek接入vscode
  • 【仿真测试】基于FPGA的QPSK软解调+扩频通信链路实现,包含帧同步,定时点,扩频伪码同步,信道,误码统计
  • 国内半导体展哪家好?2026年行业优质国内半导体展资源 - 品牌2026
  • 零基础学AI编程之一 Claude Code安装保姆级教程
  • 如何快速实现音乐地址解析:一站式跨平台音乐解析解决方案
  • 用STM32CubeMX和HAL库快速上手RFID读卡器(附完整工程源码)
  • Windows 11 + CUDA 11.8 环境下,手把手教你用 PaddleOCR 2.6 训练一个识别手写笔记的模型
  • 强化学习在图像质量评估中的应用:EditScore工具解析