MITK中两种微服务的三层架构实现对比
两种微服务的三层架构实现对比按 OSGi 规范的三层架构模块层 / 生命周期层 / 服务层对比CppMicroServicesus::与 CTK PluginFramework 的实现细节。源码位置CppMicroServices:D:/MITK/Modules/CppMicroServices/core/src/CTK:D:/MITK-superbuild-2023.12/ep/src/CTK/Libs/PluginFramework/OSGi 规范定义三层模块层Module Layer打包与依赖、生命周期层Lifecycle Layer安装/启动/停止、服务层Service Layer注册/发现。两套实现对三层的完成度截然不同。一、模块层Module Layer——“模块是什么、依赖怎么声明”CppMicroServicesus::CTK模块单位普通动态库.dll/.so无特殊打包CTK 插件带 META-INF/MANIFEST.MF 的 Qt 插件元数据可选manifest.json版本、autoLoadDirMANIFEST.MF 强制Plugin-SymbolicName、Plugin-Version、Require-Plugin、Plugin-ActivationPolicyctkPluginConstants.h: L132-240依赖声明没有——模块间依赖靠链接器编译期解决Require-Plugin: com.acme.test; plugin-version[1.0,2.0)——带版本区间的运行期依赖L204-209依赖解析无解析过程checkRequirePlugin递归解析 Require 链 版本区间匹配资源系统编译进二进制的资源容器usModuleResourceContainer资源存SQLitePLUGIN_RESOURCES_TABLE身份注册ModuleRegistry: name → Module*自增 idctkPlugins: location(URL) → QSharedPointerctkPluginSQLite 持久化安装状态CTK 依赖解析实现ctkPluginFrameworkContext.cpp: L269-300voidctkPluginFrameworkContext::checkRequirePlugin(ctkPluginPrivate*plugin){QListIteratorctkRequirePlugin*i(plugin-require);// MANIFEST 里的 Require-Plugin 列表while(i.hasNext()){ctkRequirePlugin*pri.next();// 按名字 版本区间找候选插件QListctkPlugin*plplugins-getPlugins(pr-name,pr-pluginRange);for(...每个候选 p2...){if(tempResolved.contains(p2))okp2;// 正在本轮解析中处理循环依赖elseif(RESOLVED_FLAGSp2-state)okp2;// 已解析elseif(p2-statectkPlugin::INSTALLED)// 递归解析依赖的依赖tempResolved 集合防环...}}}核心差异us:: 的模块层是退化的——没有版本、没有依赖解析、没有安装概念模块 已被 OS 加载的库。CTK 实现了完整 OSGi 模块层——版本区间依赖、解析失败可诊断、安装状态跨进程持久SQLite。二、生命周期层Lifecycle Layer——“状态机与钩子”CTK完整六态状态机ctkPlugin.h: L87-103UNINSTALLED ← INSTALLED → RESOLVED → STARTING → ACTIVE ↑ │ └──── STOPPING ←─────┘INSTALLED→RESOLVEDgetUpdatedStatectkPlugin_p.cpp: L174-198触发依赖解析成功才置 RESOLVED 并广播事件——装了和能用是两个状态启动start0()ctkPlugin_p.cpp: L720-790ctkPluginException*ctkPluginPrivate::start0(){fwCtx-listeners.emitPluginChanged(ctkPluginEvent(STARTING,...));pluginLoader.load();// QPluginLoader 加载库pluginActivatorqobject_castctkPluginActivator*(pluginLoader.instance());// Qt 插件根对象即 ActivatorpluginActivator-start(pluginContext.data());// 回调 start()statectkPlugin::ACTIVE;...// 异常回滚路径L780-789// STOPPING → removePluginResources() → context invalidate → 退回 RESOLVED}每一步状态迁移都发 ctkPluginEventSTARTING/STARTED/STOPPING/STOPPED支持懒激活Plugin-ActivationPolicy: eager/lazystart 中途被 uninstall 有专门检测STATECHANGE_ERRORActivator 接口ctkPluginActivator.h: L71-111classctkPluginActivator{virtualvoidstart(ctkPluginContext*context)0;virtualvoidstop(ctkPluginContext*context)0;};CppMicroServices二态usModule.h: L64,166未加载 ⇄ 已加载IsLoaded() 一个 bool加载即注册即启动静态初始化US_INITIALIZE_MODULE→ModuleRegistry::Register→Module::Start一气呵成没有中间可停留的状态Activator 获取用原生符号查找usModule.cpp: L133-135std::string activator_func_us_module_activator_instance_d-info.name;void*symModuleUtils::GetSymbol(d-info,activator_func.c_str());// dlsym 等价d-moduleActivatoractivatorHook();d-moduleActivator-Load(d-moduleContext);事件只有 LOADING/LOADED/UNLOADING/UNLOADED 四种无 RESOLVED 概念无异常回滚状态机Activator::Load抛异常直接向上传播L152-156 注释明说语义上视为 noexcept核心差异CTK 的生命周期与 .so 加载解耦——库可以加载着但插件停在 RESOLVED 未激活BlueBerry ExtensionRegistry 正是利用这一点插件 RESOLVED 就解析它的 plugin.xml不必 start懒激活的基础。us:: 的生命周期与 .so 加载同一简单但无法表达就绪未启动。三、服务层Service Layer——“几乎是同一份代码”这一层两者都是 Knopflerfish 的完整移植结构逐字段对应机制CppMicroServicesCTK差异双表存储servicesclassServicesusServiceRegistry_p.h: L63-80同名双表ctkServices_p.h: L64-71仅容器STL vs QHashranking 排序lower_bound有序插入Get取back()同无服务本体InterfaceMap std::mapstring, void*QObject*QStringList接口名CTK 服务必须是 QObject用qobject_cast校验接口使用记账dependents: MapModule*,intdependents: QHashQSharedPointerctkPlugin,int同构作用域singleton / module / prototype 三种SERVICE_SCOPEsingleton ctkServiceFactoryus:: 多 prototype事件分发回调接口 监听器分桶objectclass/service.id 两级 cacheQt 信号槽ctkServiceSlotEntryreceiverslot 名事件投递机制不同LDAP 过滤usLDAPExprctkLDAPExpr同一算法自动清理RemoveModuleResources卸载时注销全部服务归还引用removePluginResources()stop 时同样操作同构跟踪器us::ServiceTracker.tpp 模板ctkServiceTracker同构核心差异只有两点CTK 服务绑定 Qt 元对象系统服务必须是 QObject、事件走信号槽、接口用Q_DECLARE_INTERFACEqobject_castus:: 零 Qt 依赖靠模板。锁粒度CTK 部分用 QReadWriteLockus:: 单 Mutex。总结一张表看三层完成度OSGi 层CppMicroServicesCTK模块层◐ 退化无版本/无依赖解析模块已加载的库● 完整MANIFEST Require-Plugin 版本区间 递归解析 SQLite 持久化生命周期层◐ 二态加载/未加载静态初始化自动走完● 完整六态状态机 事件 懒激活 异常回滚服务层● 完整Knopflerfish 移植● 完整同一份 Knopflerfish 移植Qt 化这解释了 MITK 的分工为什么合理Modules 层用 us::——算法库不需要安装/解析/延迟启动这些重量级语义加载即用、零依赖最合适Plugins 层用 CTK——UI 插件需要版本依赖、按需激活、RESOLVED 阶段读 plugin.xml非完整生命周期不可两者服务层同源同构所以开发者跨层切换时 API 心智模型几乎不变。关键源码文件索引CppMicroServicesModules/CppMicroServices/core/下层内容文件关键行模块层模块表src/module/usModuleRegistry.cppL39-73模块层manifest.json 解析src/module/usModulePrivate.cppL53-68生命周期层二态判定include/usModule.hL64, L166IsLoaded生命周期层Start/符号查找src/module/usModule.cppL119-171生命周期层自动注册宏include/usModuleInitialization.hL57-120服务层服务双表src/service/usServiceRegistry_p.hL63-80服务层注册私有体/dependentssrc/service/usServiceRegistrationBasePrivate.hL40-115服务层监听器分桶src/service/usServiceListeners_p.hL43-65CTKep/src/CTK/Libs/PluginFramework/下层内容文件关键行模块层MANIFEST 头常量ctkPluginConstants.hL132-240模块层Require-Plugin 解析ctkPluginFrameworkContext.cppL269-300checkRequirePlugin模块层插件表ctkPlugins_p.hL45-63模块层SQLite 存储ctkPluginStorageSQL.cppL38-39生命周期层六态状态机ctkPlugin.hL59-103生命周期层RESOLVED 判定ctkPlugin_p.cppL174-198getUpdatedState生命周期层start0/QPluginLoader/回滚ctkPlugin_p.cppL720-790生命周期层Activator 接口ctkPluginActivator.hL71-111服务层服务双表ctkServices_p.hL40-71服务层信号槽事件ctkServiceSlotEntry_p.hL45-75两种微服务的应用实例追踪本文是《两种微服务的三层架构实现对比》的补充各取一个真实 MITK 例子端到端描述具体实现过程。例一CppMicroServicesInteractionEventObserver交互事件观察者例二CTKIDataStorageService数据仓库服务例一 CppMicroServicesInteractionEventObserverus:: 微服务在 MITK 里最典型的应用鼠标交互事件如何广播给不认识的观察者十字光标同步链路中的DisplayActionEventBroadcast正是靠它接入的。① 定义接口Modules/CoreModules/Core/include/mitkInteractionEventObserver.hstructInteractionEventObserver{virtualvoidNotify(InteractionEvent*event,boolisHandled)0;...};只有头文件没有任何实现依赖——消费方和提供方都只 include 它。② 提供方注册服务构造时Modules/Core/src/Interactions/mitkDisplayActionEventBroadcast.cpp: L46-48——对象构造时把自己注册进服务表mitk::DisplayActionEventBroadcast::DisplayActionEventBroadcast(){us::ServiceProperties props;props[name]std::string(DisplayActionEventBroadcast);// 以 InteractionEventObserver 接口注册自身m_ServiceRegistrationus::GetModuleContext()-RegisterServiceInteractionEventObserver(this,props);}内部发生的事RegisterService→ServiceRegistry::RegisterServiceusServiceRegistry.cpp: L87接口名us_service_interface_iidInteractionEventObserver()作为 key写入classServices表立即广播ServiceEvent::REGISTERED析构时m_ServiceRegistration.Unregister()自动注销③ 消费方用 ServiceTracker LDAP 过滤器查找Modules/Core/src/Interactions/mitkDispatcher.cpp: L40-49——每个渲染窗口的事件分发器构造时建跟踪器// 构造 LDAP 过滤器只要 InteractionEventObserver 这个接口的服务std::string classInteractionEventObserver(us::ServiceConstants::OBJECTCLASS()us_service_interface_iidInteractionEventObserver());// 再按属性过滤全局的 或 专属本 renderer 的us::LDAPFilterfilter(((|specificRendereranyRenderer)classInteractionEventObserver));m_EventObserverTrackernewus::ServiceTrackerInteractionEventObserver(us::GetModuleContext(),filter);LDAP 过滤器的实战用法不只按接口还按props里的属性筛选——同一接口的多个服务实例可以按属性精确圈定。④ 每次事件分发时动态取服务mitkDispatcher.cpp: L198-213——每处理一个鼠标/键盘事件/* Notify InteractionEventObserver */conststd::vectorus::ServiceReferenceInteractionEventObserverlistEventObserverm_EventObserverTracker-GetServiceReferences();// 拿当前时刻的全部匹配服务for(autoit:listEventObserver){InteractionEventObserver*observerm_EventObserverTracker-GetService(it);if(observerobserver-IsEnabled())observer-Notify(event,eventIsHandled);// 广播}每次都现查——运行中途新加载一个带观察者的模块比如测量工具模块注册了自己的观察者下一个鼠标事件就会自动广播给它Dispatcher 一行代码不用改。完整链路DisplayActionEventBroadcast 构造 → RegisterServiceInteractionEventObserver(this) [提供方Modules/Core] → classServices[...InteractionEventObserver] 本实例 ↓ 运行期解耦 QmitkRenderWindow 收到鼠标事件 → Dispatcher::ProcessEvent → ServiceTracker(LDAP过滤).GetServiceReferences() [消费方互不 include 实现] → observer-Notify(event) → SetCrosshair/Scroll/... → 十字光标同步链路例二 CTKIDataStorageServiceCTK 服务在 MITK 里最核心的应用所有 View 如何拿到全局唯一的 DataStorage。① 定义接口带 Qt 元对象声明Plugins/org.mitk.core.services/src/mitkIDataStorageService.h: L29-49structMITK_CORE_SERVICES_PLUGINIDataStorageService{virtualIDataStorageReference::PointerGetDataStorage()const0;virtualIDataStorageReference::PointerGetDefaultDataStorage()const0;...};// CTK 服务必须做 Qt 接口声明——这是与 us:: 的关键差异Q_DECLARE_INTERFACE(mitk::IDataStorageService,org.mitk.service.IDataStorageService)② 提供方在插件 Activator::start 里注册Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.cpp: L90-91——org.mitk.core.services插件被 CTK启动进入 ACTIVE 状态时voidorg_mitk_core_services_Activator::start(ctkPluginContext*context){dataStorageService.reset(newDataStorageService());// 创建实现context-registerServicemitk::IDataStorageService(dataStorageService.data());}对比例一us:: 的注册发生在对象构造/模块加载时CTK 的注册发生在插件 start时——三层对比文档里生命周期绑定点不同在真实代码中的体现。CTK 内部用qobject_cast校验实现确实携带Q_DECLARE_INTERFACE声明的接口然后写入ctkServices的双表。③ 消费方用 ctkServiceTrackerPlugins/org.mitk.gui.qt.common/src/QmitkAbstractView.cpp// L146: 私有类成员——跟踪器ctkServiceTrackermitk::IDataStorageService*m_DataStorageServiceTracker;// L51-57: 构造时打开跟踪QmitkAbstractViewPrivate(QmitkAbstractView*qq):m_DataStorageServiceTracker(QmitkCommonActivator::GetContext())// 插件上下文{m_DataStorageServiceTracker.open();// 开始跟踪服务出现/消失自动感知}// L390-400: 任何 View 调 GetDataStorage() 时mitk::DataStorage::PointerQmitkAbstractView::GetDataStorage()const{mitk::IDataStorageService*dsServiced-m_DataStorageServiceTracker.getService();if(dsService!nullptr)returndsService-GetDataStorage()-GetDataStorage();returnnullptr;}④ 自动清理View 析构 →m_DataStorageServiceTracker.close()→ 停止跟踪插件 stop →removePluginResources()→ 注销服务 清理依赖计数服务注销时所有持有引用的 View 自动收到serviceRemoved信号getService()返回 nullptr完整链路org.mitk.core.services 插件启动ACTIVE → Activator::start() → registerServiceIDataStorageService(dataStorageService) [提供方] → ctkServices[org.mitk.service.IDataStorageService] 本实例 ↓ 运行期解耦 QmitkAbstractView 构造 → ctkServiceTracker.open() → 监听服务注册/注销信号 → 任何 View 调 GetDataStorage() → tracker.getService() → DataStorageService::GetDataStorage() → 全局唯一 DataStorage 实例对比小结维度CppMicroServicesInteractionEventObserverCTKIDataStorageService注册时机对象构造时模块加载即注册插件 start 时ACTIVE 状态才注册接口声明纯 C 结构体模板元编程Q_DECLARE_INTERFACE Qt 元对象服务发现ServiceTrackerLDAPFilter属性过滤ctkServiceTrackerQt 信号槽监听生命周期绑定与模块加载/卸载同步与插件状态机INSTALLED→RESOLVED→ACTIVE同步典型场景跨模块事件广播鼠标交互插件间共享单例全局 DataStorage这两个实例完整展示了三层架构对比在 MITK 中的实际应用us:: 用于模块层的轻量事件广播CTK 用于插件层的完整生命周期管理 服务共享。

相关新闻

深度解析CodableWrappers架构:从零构建自己的属性包装器编码器

深度解析CodableWrappers架构:从零构建自己的属性包装器编码器

深度解析CodableWrappers架构:从零构建自己的属性包装器编码器 【免费下载链接】CodableWrappers A Collection of PropertyWrappers to make custom Serialization of Swift Codable Types easy 项目地址: https://gitcode.com/gh_mirrors/co/CodableWrappers …

2026/8/16 14:53:21 阅读更多 →
从世界状态到可执行控制:Cosmos 3 Edge 与机器人控制器之间应建立什么合同

从世界状态到可执行控制:Cosmos 3 Edge 与机器人控制器之间应建立什么合同

从世界状态到可执行控制:Cosmos 3 Edge 与机器人控制器之间应建立什么合同 TL;DR 场景:Cosmos 3 Edge 把视觉理解、未来预测、视频生成和动作生成放入同一套 4B 世界表示,端侧机器人需要把"模型提案"和"硬件执行"清晰分…

2026/8/5 3:38:29 阅读更多 →
地质灾害监测预警数据集解析与应用实践

地质灾害监测预警数据集解析与应用实践

1. 地质灾害监测预警数据集的行业价值作为一名长期从事地质灾害监测算法开发的工程师,我深知高质量数据对于模型训练的重要性。在边坡形变分析和地质灾害预警领域,最大的痛点莫过于缺乏带精确空间坐标和时序轨迹的真实监控数据。传统的数据采集方式往往存…

2026/8/8 0:15:06 阅读更多 →

最新新闻

别再混淆了:3D高斯泼溅中的“仿射近似”、透视投影与正交投影

别再混淆了:3D高斯泼溅中的“仿射近似”、透视投影与正交投影

如果你刚开始接触 3D Gaussian Splatting(3DGS),大概率会看到这样一句话:“将非线性透视投影近似为仿射变换。”同时,如果你做过直接法视觉SLAM(如DSO),可能会在光度误差的雅可比推导…

2026/8/18 13:48:31 阅读更多 →
鸿蒙手机如何将网站转为带百度搜索的APP

鸿蒙手机如何将网站转为带百度搜索的APP

根据您的问题,核心诉求是:在鸿蒙系统的手机上,将网站(Web)生成为安卓应用(APK),并且该应用需要集成百度搜索功能。 需要明确的是,鸿蒙系统(HarmonyOS&#x…

2026/8/18 13:48:31 阅读更多 →
【SCI2区】混沌博弈优化算法CGO-CNN-GRU-Attention用电需求预测Matlab实现

【SCI2区】混沌博弈优化算法CGO-CNN-GRU-Attention用电需求预测Matlab实现

✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,代码获取、论文复现及科研仿真合作可私信。🍎个人主页:Matlab科研工作室🍊个人信条:格物致知。更多Matlab完整代码及仿真定制内容点…

2026/8/18 13:48:31 阅读更多 →
5分钟快速上手r3f-game-demo:本地运行这个开源2D游戏demo的完整教程

5分钟快速上手r3f-game-demo:本地运行这个开源2D游戏demo的完整教程

5分钟快速上手r3f-game-demo:本地运行这个开源2D游戏demo的完整教程 【免费下载链接】r3f-game-demo A demo on how to do a simple tile-based game with React and react-three-fiber 项目地址: https://gitcode.com/gh_mirrors/r3/r3f-game-demo r3f-game…

2026/8/18 13:48:31 阅读更多 →
锤子助手第064个开关:字体注入网页的位置、验证方法与网页显示安全边界

锤子助手第064个开关:字体注入网页的位置、验证方法与网页显示安全边界

🔥 个人主页: 杨利杰YJlio ❄️ 个人专栏: 《Windows 疑难杂症与工单复盘案例库》 《Sysinternals实战教程》 《WINDOWS教程》 《Windows PowerShell 实战》 《IOS插件分析测试》 《超简单:用Python让Excel飞起来》…

2026/8/18 13:47:31 阅读更多 →
解锁编程潜力,从掌握GitHub开始

解锁编程潜力,从掌握GitHub开始

目录: 一、搜索开源项目 1、什么是Git 2、Github常用词含义 3、一个完整的项目界面 4、使用Github搜索项目 二、访问速度慢的解决 1、使用网易UU 2、使用Steam 3、最简单方法 三、创建与下载工程 1、创建与删除仓库 2、上传工程文件 3、下载工程 一、搜…

2026/8/18 13:47:31 阅读更多 →

日新闻

告别逐帧截图:用 extract-video-ppt 快速提取视频中的 PPT 并一键导出 PDF

告别逐帧截图:用 extract-video-ppt 快速提取视频中的 PPT 并一键导出 PDF

告别逐帧截图:用 extract-video-ppt 快速提取视频中的 PPT 并一键导出 PDF 【免费下载链接】extract-video-ppt extract the ppt in the video 项目地址: https://gitcode.com/gh_mirrors/ex/extract-video-ppt 如果你还停留在"看网课 不停暂停 截图 …

2026/8/18 0:00:57 阅读更多 →
思源宋体TTF一站式上手:7个字重免费商用,从下载到上线的完整走查

思源宋体TTF一站式上手:7个字重免费商用,从下载到上线的完整走查

思源宋体TTF一站式上手:7个字重免费商用,从下载到上线的完整走查 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 你是不是也经历过这种时刻:设计稿里…

2026/8/18 0:00:58 阅读更多 →
华硕笔记本控制权回收指南:GHelper 如何用一个 10MB 文件替代 Armoury Crate

华硕笔记本控制权回收指南:GHelper 如何用一个 10MB 文件替代 Armoury Crate

华硕笔记本控制权回收指南:GHelper 如何用一个 10MB 文件替代 Armoury Crate 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, …

2026/8/18 0:00:59 阅读更多 →

周新闻

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

如果你是一名开发者,最近可能已经感受到了AI大模型正在从“玩具”变成“生产力工具”的强烈信号。从代码补全到智能Agent,从本地部署到云端API,我们正处在一个技术栈快速重构的节点。然而,面对层出不穷的模型、框架和工具&#xf…

2026/8/18 9:15:35 阅读更多 →
工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/18 9:06:28 阅读更多 →
【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

2026/8/18 9:04:56 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/17 18:54:37 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/17 18:55:16 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/17 18:55:55 阅读更多 →