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

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

随着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中设置deliveryWithInstall为false标识该模块不会在应用安装时一起下载。{ module: { name: AModulelib, deliveryWithInstall: false } }步骤2定义动态模块功能Calc.etsexport function add(a: number, b: number) { return a b; }DateComponent.etsComponent 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功能:36) .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: Callbackvoid): 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: Callbackvoid): 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: Callbackvoid): 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.hsp2通过HDC命令或DevEco Studio安装基础包hdc install entry.hap3打开开发者调试模式设置 → 机型 → 关于手机 → 连续点击软件版本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()使用实现用户按需下载所需功能模块减少首次下载时间和存储空间占用。

相关文章:

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

随着HarmonyOS应用的持续发展,应用的功能越来越丰富。但实际上,80%的用户使用时长都集中在20%的特性上,其余功能可能只面向部分用户。 为了避免用户首次下载应用耗时过长及过多占用用户空间,应用市场服务提供了按需分发的能力。 …...

如何在 Taotoken 平台获取并管理你的 API Key 实现安全调用

如何在 Taotoken 平台获取并管理你的 API Key 实现安全调用 1. 注册与登录 Taotoken 平台 访问 Taotoken 平台并完成注册流程是获取 API Key 的第一步。注册成功后,使用你的账号密码登录控制台。控制台是管理所有 API 访问权限的核心界面,在这里你可以…...

零基础学AI编程之一 Claude Code安装保姆级教程

Claude 可以在终端运行(国内可用)、网页端(需登陆账号)、桌面端app(需登陆账号)和vscode插件的方式(国内可用)运行(4种)​ ​ 如果是有Claude账号的&#xff…...

从蓝帽杯Misc赛题复盘,聊聊CTF比赛中那些“藏在流量里”的密码与哈希

流量中的密码艺术:CTF比赛中网络取证的核心技术与实战解析 在网络安全竞赛的战场上,流量分析始终是取证环节的"必考题"。当一道Misc题目摆在你面前,那些看似杂乱无章的TCP/UDP数据流中,往往隐藏着解题的关键线索——可能…...

再战齿槽力!用Anti-Notch抑制齿槽力扰动效果竟然出乎意料的好!

1. 问题描述 **问题:**有铁芯直线电机因齿槽力引起的周期性速度/位置波动,利用控制器功能探索并实施的齿槽力补偿方案,以提升匀速运动精度。 **具体指标:**降低匀速运动时的速度波动幅值、缩小跟随误差的周期性波动幅值。 不同速度下,通过采集相应的位置误差数据,可以观…...

NVIDIA TAO实战:手写字符检测与识别模型优化

1. 基于NVIDIA TAO的手写字符检测与识别模型实战 在工业质检、物流分拣、金融票据处理等领域,手写字符的自动识别一直是个棘手的问题。传统OCR技术面对手写体时准确率往往不尽如人意,而定制化深度学习模型又面临数据准备复杂、训练周期长等挑战。最近我在…...

别再死记硬背了!用Python+Jupyter Notebook可视化理解流体力学核心概念(密度、雷诺数、管路阻力)

用PythonJupyter Notebook可视化理解流体力学核心概念 在工程实践中,流体力学概念往往因为数学公式的抽象性而令人望而生畏。传统教材中密密麻麻的微分方程和参数表格,让许多学习者陷入"理解-遗忘-再理解"的循环。现在,借助Python生…...

从Excel手工填报到Tidyverse全自动归因:某头部券商如何用200行R代码替代17人天/月人工核验(含审计留痕日志生成方案)

更多请点击: https://intelliparadigm.com 第一章:从Excel手工填报到Tidyverse全自动归因的范式跃迁 在数字营销分析领域,归因建模长期受限于Excel手工操作——数据清洗靠CtrlC/V、渠道权重靠经验估算、转化路径靠截图拼接。这种模式不仅耗时…...

空间计算领域领军企业是哪家?镜像视界

空间计算领域领军企业是哪家?镜像视界 镜像视界(浙江)科技有限公司是中国空间计算(视频孪生 / 空间智能)领域的领军企业,也是全球范围内纯视频空间计算范式的开创者与标杆。 一、行业定位 赛道定义者&am…...

世纪华通年营收379亿:净利56亿 同比增362% 拟投资60亿理财

雷递网 雷建平 4月29日浙江世纪华通集团股份有限公司(证券代码:002602 证券简称:世纪华通)今日发布2025年的年报。年报显示,世纪华通2025年营收为379亿元,较上年同期的226亿元增长67.55%。世纪华通2025年净…...

3D生成技术:从多视图到三维重建的实践指南

1. 3D生成技术概述:从多视图到三维重建的进化之路在计算机视觉和图形学领域,3D内容生成技术正经历着革命性的变革。这项技术的核心目标是将文本描述或单张2D图像转换为高质量的三维表示,为虚拟现实、游戏开发、影视制作等领域提供高效的资产生…...

ARM SIMD指令SHLL与SHRN详解及应用优化

1. ARM SIMD指令概述在ARM架构中,SIMD(Single Instruction Multiple Data)技术通过单条指令同时处理多个数据元素,显著提升了多媒体处理、信号处理等数据并行任务的执行效率。AdvSIMD作为ARM的SIMD指令集扩展,提供了丰…...

从CoPaw_Test项目看协同自动化测试框架的设计与工程实践

1. 项目概述:从“1NY2/CoPaw_Test”看自动化测试的协同进化最近在梳理团队内部的测试资产时,我反复琢磨一个项目:“1NY2/CoPaw_Test”。乍一看,这个命名有点“黑话”的味道,像是某个内部代号。但拆解开来,它…...

如何高效开启ZTE光猫工厂模式:专业网络运维的完整实战指南

如何高效开启ZTE光猫工厂模式:专业网络运维的完整实战指南 【免费下载链接】zteOnu A tool that can open ZTE onu device factory mode 项目地址: https://gitcode.com/gh_mirrors/zt/zteOnu 在ZTE光猫网络管理领域,zteOnu工具是一款颠覆性的命令…...

Amber AC Direct DC技术:革新电源转换的固态解决方案

1. 传统AC-DC电源转换技术面临的挑战在电子设备供电领域,将交流电(AC)转换为直流电(DC)是一个基础但至关重要的过程。传统方案主要依赖电磁变压器、整流桥和滤波电路组成的线性电源架构。这种技术路线存在几个明显的局…...

Rockchip RK3562嵌入式开发板评测与应用实践

1. Graperain G3562模块与开发板深度解析作为一名长期从事嵌入式系统开发的工程师,我最近测试了Graperain G3562这套基于Rockchip RK3562的系统模块(SOM)和配套开发板。这个平台在边缘AI和物联网应用中表现出色,今天我将从实际使用角度分享详细评测和技术…...

通过 Taotoken CLI 一键为团队所有 agent 开发环境配置统一模型密钥

通过 Taotoken CLI 一键为团队所有 agent 开发环境配置统一模型密钥 1. 准备工作 在开始配置前,请确保团队所有成员已安装 Node.js 16 或更高版本。Taotoken CLI 工具支持通过 npm 全局安装或直接使用 npx 运行,无需额外依赖。团队技术负责人需提前在 …...

NVIDIA显卡终极色彩校准指南:用novideo_srgb实现专业级色彩准确性

NVIDIA显卡终极色彩校准指南:用novideo_srgb实现专业级色彩准确性 【免费下载链接】novideo_srgb Calibrate monitors to sRGB or other color spaces on NVIDIA GPUs, based on EDID data or ICC profiles 项目地址: https://gitcode.com/gh_mirrors/no/novideo_…...

EchoDistill:扩散模型一步个性化新方法解析

1. 项目概述:扩散模型个性化新范式去年在训练Stable Diffusion的LoRA适配器时,我遇到一个头疼的问题:既要保留原模型的丰富生成能力,又要让模型学会特定风格或对象,往往需要数千步的微调。而今天要介绍的EchoDistill&a…...

关于搭建运维监控系统(Prometheus+Grafana)

这篇文章沉淀一下对系统监控级别的信息量积累: 为什么要了解这个一块 了解这一块的哪些内容 如果我们想一个界面掌握,服务器的运行情况 jar包的运行情况 用户点击量 流量的时间段分布情况。 就需要使用到这快。 我们掌握着一块,需要掌握什…...

HAPS太贵?国产芯华章 vs 三巨头:手把手教你评估与搭建高性价比SoC FPGA原型验证平台

SoC FPGA原型验证平台选型指南:从成本控制到国产替代实战 在芯片设计领域,原型验证环节往往占据项目总成本的30%以上,而验证效率又直接影响产品上市时间。对于资源有限的中小型设计团队而言,如何在预算约束下搭建高效的验证平台&a…...

DyaDiT:融合扩散模型与变换器的手势生成系统

1. 项目概述DyaDiT(Dynamic Diffusion Transformer)是一种融合扩散模型与变换器架构的创新性手势生成系统,专为社交场景中的自然交互需求设计。这个项目解决了传统手势生成模型在时序连贯性和社交语境适应性方面的痛点——当两个人在对话时&a…...

seata的相关信息量认识沉淀

seata作为一个分布式任务 我们作为开发者,应该从哪些认识seata掌握那些信息量 我提供一个认识框架 1.如何搭建配置到微服务生态里 2.在代码里,应该如何使用 3.提供了哪些机制,供使用 4.seata的实现原理是什么 5.在项目中,使用&…...

Claude会话保活:心跳机制原理与Python自动化实现

1. 项目概述:一个让Claude保持“心跳”的守护者如果你和我一样,深度依赖Claude这类大型语言模型进行编程、写作或复杂问题分析,那你一定遇到过这个令人头疼的场景:正和一个长对话线程(Thread)进行到关键时刻…...

开发AI Agent应用时如何通过Taotoken灵活调度不同模型

开发AI Agent应用时如何通过Taotoken灵活调度不同模型 1. 多模型调度在AI Agent中的典型场景 现代AI Agent应用往往需要组合多种大模型能力。例如文档分析任务可能先调用Claude模型进行语义理解,再通过CodeLlama生成数据处理代码,最后用GPT-4执行结果校…...

保姆级教程:MGV3200盒子免拆机刷安卓9,用ADB和U盘搞定(附刷机脚本)

MGV3200电视盒子免拆机刷安卓9全流程指南:从ADB调试到卡刷实战 每次打开电视盒子都要忍受长达一分钟的广告,预装软件占满存储空间,想安装个第三方应用还得破解限制——这些困扰终于在我发现MGV3200刷机方案后彻底解决。今天分享的这套免拆机方…...

多模态数学推理:融合视觉与符号的AI解题新范式

1. 项目背景与核心价值数学推理一直是人工智能领域最具挑战性的研究方向之一。传统数学解题系统主要依赖符号逻辑和规则引擎,但面对几何图形、函数图像等视觉元素时往往束手无策。我们团队在CVPR 2022上首次提出的多模态数学推理框架,通过融合视觉特征提…...

CentOS 7.9服务器性能摸底:手把手教你用Linpack测出真实算力(附HPL.dat调优指南)

CentOS 7.9服务器性能摸底:手把手教你用Linpack测出真实算力(附HPL.dat调优指南) 在数据中心和云计算环境中,服务器的实际计算能力往往比规格参数更能反映真实性能。尤其对于科学计算、金融建模或AI训练等高负载场景,浮…...

FPGA做信号处理,为什么我推荐你用FIR IP核而不是自己写RTL?聊聊资源与性能的权衡

FPGA信号处理实战:为什么FIR IP核是更优选择? 在FPGA信号处理领域,FIR滤波器的实现方式一直是工程师们热议的话题。每当项目进入开发阶段,团队内部总会掀起一场关于"使用IP核还是自研RTL"的激烈讨论。作为一个经历过多次…...

数据结构面试官最爱问的10个问题,我帮你整理好了(附详细答案)

数据结构面试高频10题解析:从原理到实战技巧 在技术面试中,数据结构问题往往是考察候选人基本功的核心环节。无论是校招还是社招,面试官都倾向于通过这些问题评估应聘者的逻辑思维、编码能力和计算机科学素养。本文将深入剖析面试中最常出现的…...