HarmonyOS NEXT 统一 ToolManager 架构:插件化工具系统的设计与实现
HarmonyOS NEXT 统一 ToolManager 架构插件化工具系统的设计与实现前言在 HarmonyExplorer 项目中工具箱模块集成了文件压缩、格式转换、哈希计算等多种实用工具。随着工具数量增长如何避免代码臃肿、实现工具的动态扩展成为架构设计的核心挑战。本文将详细讲解基于插件化理念的统一 ToolManager 架构设计实现新增工具零侵入式扩展。参考 ArkTS 接口定义规范 了解接口设计要点。一、ToolManager 架构设计理念1.1 传统工具管理的痛点在未引入 ToolManager 之前工具箱页面通过 if-else 或 switch-case 硬编码管理工具调用。这种方式存在以下问题问题影响严重程度新增工具需修改核心代码违反开闭原则高工具间无法统一管理维护成本高中工具历史记录分散数据不一致中工具间无法共享数据代码重复低1.2 插件化设计目标ToolManager 的设计目标是构建一个高内聚、低耦合的工具管理系统零侵入扩展新增工具只需实现接口并注册无需修改已有代码统一管理所有工具的发现、加载、执行、历史记录统一处理分类组织工具按类别管理支持动态分组展示生命周期管理工具的初始化、执行、销毁全程可控插件化架构的核心价值在于将变化隔离让系统在不修改稳定核心的前提下灵活扩展新能力。二、插件化接口设计 ITool2.1 ITool 接口定义所有工具必须实现 ITool 接口该接口定义了工具的生命周期方法和元数据。接口设计是整个架构的基石。exportenumToolCategory{FILEfile,IMAGEimage,MEDIAmedia,SECURITYsecurity,UTILutil}exportinterfaceToolResult{success:boolean;data:string;message:string;}exportinterfaceToolMetadata{id:string;name:string;description:string;category:ToolCategory;icon:Resource;isAvailable:boolean;}exportinterfaceITool{getMetadata():ToolMetadata;execute(input:string):PromiseToolResult;onActivate():void;onDeactivate():void;}2.2 抽象基类实现为了减少重复代码提供 AbstractTool 抽象基类子类只需关注核心执行逻辑exportabstractclassAbstractToolimplementsITool{protectedmetadata:ToolMetadata;constructor(metadata:ToolMetadata){this.metadatametadata;}getMetadata():ToolMetadata{returnthis.metadata;}abstractexecute(input:string):PromiseToolResult;onActivate():void{LogUtil.info(工具激活: this.metadata.name);}onDeactivate():void{LogUtil.info(工具停用: this.metadata.name);}}三、工具注册机制3.1 注册器设计ToolManager 内部维护一个工具注册表支持按 ID 和类别检索。注册采用 Map 结构保证 O(1) 查找效率。exportclassToolManager{privatestatictools:Mapstring,IToolnewMap();privatestaticcategoryIndex:MapToolCategory,ArraystringnewMap();staticregister(tool:ITool):void{constmetadata:ToolMetadatatool.getMetadata();this.tools.set(metadata.id,tool);this.addToCategoryIndex(metadata.category,metadata.id);LogUtil.info(工具注册成功: metadata.name);}staticunregister(toolId:string):void{consttool:ITool|undefinedthis.tools.get(toolId);if(tool!undefined){constmetadata:ToolMetadatatool.getMetadata();this.removeFromCategoryIndex(metadata.category,toolId);tool.onDeactivate();this.tools.delete(toolId);}}privatestaticaddToCategoryIndex(category:ToolCategory,toolId:string):void{letids:Arraystring|undefinedthis.categoryIndex.get(category);if(idsundefined){ids[];this.categoryIndex.set(category,ids);}ids.push(toolId);}privatestaticremoveFromCategoryIndex(category:ToolCategory,toolId:string):void{constids:Arraystring|undefinedthis.categoryIndex.get(category);if(ids!undefined){constindex:numberids.indexOf(toolId);if(index0){ids.splice(index,1);}}}}3.2 工具发现与加载工具注册在应用初始化时自动完成。通过 ToolRegistry 集中管理所有工具的注册调用exportclassToolRegistry{staticinitAllTools():void{ToolManager.register(newFileCompressTool());ToolManager.register(newFileHashTool());ToolManager.register(newImageConvertTool());ToolManager.register(newAudioConvertTool());ToolManager.register(newBase64Tool());LogUtil.info(所有工具注册完成);}}四、具体工具实现示例4.1 文件压缩工具以下展示一个完整的工具实现继承 AbstractTool 并实现 execute 方法exportclassFileCompressToolextendsAbstractTool{constructor(){super({id:tool_file_compress,name:文件压缩,description:支持 ZIP 格式文件压缩,category:ToolCategory.FILE,icon:$r(app.media.ic_tool_compress),isAvailable:true});}asyncexecute(input:string):PromiseToolResult{try{consttargetPath:stringinput.zip;constsuccess:booleanawaitZipManager.compressFiles(input,targetPath);return{success:success,data:targetPath,message:success?压缩成功:压缩失败};}catch(error){return{success:false,data:,message:压缩异常: error.message};}}}4.2 文件哈希工具exportclassFileHashToolextendsAbstractTool{constructor(){super({id:tool_file_hash,name:文件哈希,description:计算文件 MD5/SHA256 值,category:ToolCategory.SECURITY,icon:$r(app.media.ic_tool_hash),isAvailable:true});}asyncexecute(input:string):PromiseToolResult{consthashValue:stringawaitHashUtil.calculateFileHash(input,SHA-256);return{success:hashValue.length0,data:hashValue,message:哈希计算完成};}}图1ToolManager 插件化架构图展示接口层、注册层和工具实现层的关系五、ToolHistory 历史记录5.1 历史记录模型每次工具执行后自动记录历史方便用户查看和复用。ToolHistory 数据模型如下exportinterfaceToolHistory{id:string;toolName:string;content:string;createTime:number;}5.2 历史记录管理importdataPreferencesfromohos.data.preferences;exportclassToolHistoryRepository{privatestaticpreference:dataPreferences.Preferences|nullnull;privatestaticreadonlyMAX_HISTORY:number100;staticasyncinit(context:Context):Promisevoid{this.preferenceawaitdataPreferences.getPreferences(context,tool_history);}staticasyncaddHistory(history:ToolHistory):Promisevoid{if(this.preferencenull){return;}constkey:stringhistory_history.id;awaitthis.preference.put(key,JSON.stringify(history));awaitthis.preference.flush();}staticasyncgetHistoryList():PromiseArrayToolHistory{if(this.preferencenull){return[];}constall:Recordstring,objectawaitthis.preference.getAll();constlist:ArrayToolHistory[];constkeys:ArraystringObject.keys(all);for(constkeyofkeys){if(key.startsWith(history_)){consthistory:ToolHistoryJSON.parse(String(all[key]));list.push(history);}}list.sort((a:ToolHistory,b:ToolHistory)b.createTime-a.createTime);returnlist;}}六、工具分类管理6.1 分类索引查询ToolManager 提供按类别查询工具的能力Toolbox 页面据此进行分组展示。HarmonyExplorer 中预定义的工具分类如下分类枚举分类名称典型工具示例FILE文件工具文件压缩、文件哈希IMAGE图片工具图片格式转换、图片压缩MEDIA媒体工具音频转换、视频提取SECURITY安全工具文件加密、哈希校验UTIL实用工具二维码生成、Base64 编码exportclassToolManager{staticgetToolsByCategory(category:ToolCategory):ArrayITool{constids:Arraystring|undefinedthis.categoryIndex.get(category);constresult:ArrayITool[];if(ids!undefined){for(constidofids){consttool:ITool|undefinedthis.tools.get(id);if(tool!undefinedtool.getMetadata().isAvailable){result.push(tool);}}}returnresult;}staticgetAllCategories():ArrayToolCategory{returnArray.from(this.categoryIndex.keys());}staticasyncexecuteTool(toolId:string,input:string):PromiseToolResult{consttool:ITool|undefinedthis.tools.get(toolId);if(toolundefined){return{success:false,data:,message:工具不存在};}tool.onActivate();constresult:ToolResultawaittool.execute(input);constmetadata:ToolMetadatatool.getMetadata();awaitToolHistoryRepository.addHistory({id:Date.now().toString(),toolName:metadata.name,content:result.data,createTime:Date.now()});tool.onDeactivate();returnresult;}}七、ToolCard 组件适配7.1 组件设计ToolCard 是工具箱页面的展示组件直接消费 ToolMetadata 渲染工具卡片。参考 ArkUI 组件开发。7.2 ToolCard 实现Componentexportstruct ToolCard{Propmetadata:ToolMetadata;onToolClick:(toolId:string)void(){};build():void{Column(){Image(this.metadata.icon).width(40).height(40).margin({bottom:8})Text(this.metadata.name).fontSize(13).fontColor($r(app.color.text_primary)).maxLines(1)Text(this.metadata.description).fontSize(11).fontColor($r(app.color.text_secondary)).maxLines(2).margin({top:2})}.width(100%).padding(12).borderRadius(12).backgroundColor($r(app.color.bg_card)).alignItems(HorizontalAlign.Center).opacity(this.metadata.isAvailable?1.0:0.4).onClick((){if(this.metadata.isAvailable){this.onToolClick(this.metadata.id);}})}}八、工具间数据传递8.1 数据传递机制某些工具的输出可以作为另一个工具的输入例如哈希计算结果可以传递给 Base64 编码工具。ToolManager 提供 ToolContext 管理工具间数据流exportclassToolContext{privatestaticdataMap:Mapstring,stringnewMap();staticsetData(key:string,value:string):void{this.dataMap.set(key,value);}staticgetData(key:string):string{returnthis.dataMap.get(key)??;}staticclearData(key:string):void{this.dataMap.delete(key);}staticclearAll():void{this.dataMap.clear();}}工具间数据传递采用键值对存储模式解耦了工具之间的直接依赖任何工具都可以生产或消费数据。九、ToolManager 与 KitManager 协作9.1 职责边界ToolManager 管理工具的注册与执行流程KitManager 管理 HarmonyOS Kit 的能力封装。两者协作关系如下工具执行时通过 ToolManager 调度工具内部调用 KitManager 获取系统能力KitManager 封装 File Kit、Image Kit 等底层 APIToolManager 记录执行历史KitManager 不感知业务逻辑维度ToolManagerKitManager职责工具生命周期管理系统能力封装依赖方向调用 KitManager不依赖 ToolManager扩展方式注册新 ITool封装新 Kit数据管理ToolHistory无状态9.2 协作示例exportclassImageConvertToolextendsAbstractTool{constructor(){super({id:tool_image_convert,name:图片格式转换,description:支持 PNG/JPEG/WebP 互转,category:ToolCategory.IMAGE,icon:$r(app.media.ic_tool_convert),isAvailable:true});}asyncexecute(input:string):PromiseToolResult{constparams:ConvertParams{sourcePath:input,targetFormat:ImageFormat.JPEG,quality:90};constresult:ConvertResultawaitKitManager.getImageKit().convertFormat(params);return{success:result.success,data:result.outputPath,message:result.message};}}十、新增工具流程10.1 零侵入扩展步骤新增一个工具的完整流程如下创建工具类继承 AbstractTool实现 execute 方法编写核心逻辑在 ToolRegistry.initAllTools 中添加注册调用无需修改 Toolbox 页面、ToolCard 组件等已有代码// 步骤1-2: 创建新工具exportclassQrCodeToolextendsAbstractTool{constructor(){super({id:tool_qrcode,name:二维码生成,description:将文本生成二维码图片,category:ToolCategory.UTIL,icon:$r(app.media.ic_tool_qrcode),isAvailable:true});}asyncexecute(input:string):PromiseToolResult{constqrPath:stringawaitQrCodeUtil.generate(input);return{success:qrPath.length0,data:qrPath,message:二维码生成成功};}}// 步骤3: 在 ToolRegistry.initAllTools 中添加一行注册ToolManager.register(newQrCodeTool());// 新增一行即可整个新增工具过程只需编写一个新类和一行注册代码完全不影响已有功能体现了开闭原则的工程实践。总结统一 ToolManager 架构是 HarmonyExplorer 项目中插件化设计的核心实践。通过 ITool 接口定义、AbstractTool 基类复用、注册表机制和分类索引实现了工具的零侵入式扩展。ToolHistory 历史记录和 ToolContext 数据传递机制进一步增强了工具系统的实用性。与 KitManager 的分层协作确保了业务逻辑与系统能力的清晰边界。这一架构使得工具箱模块可以持续扩展而不会导致代码腐化。更多架构设计参考请查阅 HarmonyOS 应用架构指南 和 ArkTS 编程规范。如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力相关资源HarmonyOS 官方文档ArkTS 接口与抽象类ArkUI 组件开发指南Preferences 数据存储CSDN HarmonyOS 架构设计HarmonyOS 开源社区

相关新闻

Graph of Thoughts实战:KRAGEN如何将复杂问题拆解为可视化思维图谱

Graph of Thoughts实战:KRAGEN如何将复杂问题拆解为可视化思维图谱

Graph of Thoughts实战:KRAGEN如何将复杂问题拆解为可视化思维图谱 【免费下载链接】KRAGEN Software to implement GoT with a weviate vectorized database 项目地址: https://gitcode.com/gh_mirrors/kr/KRAGEN KRAGEN(Knowledge Retrieval Au…

2026/10/13 6:02:48 阅读更多 →
HarmonyOS NEXT 项目性能优化:从启动速度到内存管理的全链路实践

HarmonyOS NEXT 项目性能优化:从启动速度到内存管理的全链路实践

HarmonyOS NEXT 项目性能优化:从启动速度到内存管理的全链路实践 前言 在企业级 HarmonyOS 应用开发中,性能优化直接决定用户体验的成败。HarmonyExplorer 作为文件管理工具,需要处理大量文件列表、图片缩略图、视频预览等高负载场景。本文…

2026/10/12 21:07:57 阅读更多 →
长期自用|MX Player 安卓老牌全能播放器,本地影音播放的靠谱选择

长期自用|MX Player 安卓老牌全能播放器,本地影音播放的靠谱选择

在安卓生态里,影音播放器工具层出不穷,有的主打高颜值界面,有的侧重在线资源推送,但真正能做到兼容性拉满、稳定不折腾、轻量化无冗余的本地播放器,其实寥寥无几。 MX Player 算是陪伴安卓用户多年的老牌工具&#xff…

2026/10/11 14:28:03 阅读更多 →

最新新闻

静态时序分析实战:从时序弧到时钟约束的完整解读

静态时序分析实战:从时序弧到时钟约束的完整解读

说实话,静态时序分析这个系列写到第二篇,我想换个切入点。上一篇我们把STA是什么、为什么需要它、建立时间和保持时间的基本定义聊了一遍。但很多刚接触时序分析的同学,看完概念之后对着工具报出来的一屏时序报告,还是会有一种&qu…

2026/10/13 18:54:57 阅读更多 →
Java工程师24周转型Agent Engineer:完整学习路线与避坑指南

Java工程师24周转型Agent Engineer:完整学习路线与避坑指南

做Java后端做了六七年,本来觉得自己就在“写接口、调存储、薅中间件”这条路上走到黑了,结果这两年AI应用的需求一冒出来,身边好几个Java同事陆续转去做了Agent方向,薪资涨幅都不小。很多人问我:Java工程师转Agent Eng…

2026/10/13 18:54:57 阅读更多 →
Lucide Icons:现代轻量可定制的前端图标方案

Lucide Icons:现代轻量可定制的前端图标方案

图标这摊事,看着小,真管起来其实挺烦。带过几个前端项目之后,我最深的体会就是:图标的数量会失控、风格会失守、替换成本会失控。早些年我干过不少蠢事,比如把所有图标拼成一张雪碧图,坐标一个个对着设计稿…

2026/10/13 18:54:57 阅读更多 →
SQL Server数据库系统加固规范:从安装基线到权限审计与备份加密

SQL Server数据库系统加固规范:从安装基线到权限审计与备份加密

简介:一份面向数据库管理员与安全运维人员的Sql Server数据库系统加固规范文档,围绕账号管理、认证授权、日志配置、通信协议、设备安全等维度,明确定义了数据库加固的具体策略与执行条目,可帮助企业排查数据库弱口令、共享账号、…

2026/10/13 18:54:57 阅读更多 →
LiteLLM实战:构建多模型统一接入层与Proxy网关

LiteLLM实战:构建多模型统一接入层与Proxy网关

最近在做一个内部的多模型接入项目,几套模型服务的 API 格式各不相同,光是适配层就写了小两千行。后来换成了 LiteLLM,整个接入工作一下子清爽了很多。这篇文章就聊聊我在实际项目里用 LiteLLM 做统一模型接入层的经验,包括核心设…

2026/10/13 18:54:57 阅读更多 →
SpringBoot+Shiro+Redis+Elasticsearch商城实战:从技术栈到避坑指南

SpringBoot+Shiro+Redis+Elasticsearch商城实战:从技术栈到避坑指南

简介:这份SpringBoot天猫商城整站项目适合有一定Java基础、想系统学习前后端分离电商系统的开发者。项目采用SpringBoot作为后端,前端整合Bootstrap、Vue.js与jQuery,页面由Thymeleaf渲染,数据层使用JPA搭配Redis缓存,…

2026/10/13 18:53:55 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →