HarmonyOS7 互动卡片架构深度解析
互动卡片Live Form / LiveCard为服务卡片带来了质的飞跃——从信息的静态展示进化到了可交互、可动效、可感知的全新维度。本文以开源项目 LiveCard包名com.example.livecard为蓝本从LiveFormExtensionAbility生命周期出发深入剖析互动卡片的整体架构设计。LiveCard 项目包含四种互动卡片睡眠卡片三叶草动画 睡眠健康数据、快递卡片陀螺仪驱动的憨憨动画、运动卡片卡路里燃烧动画与状态切换、音乐卡片专辑封面同步动画 音乐播放。全文代码均取自该实战项目。互动卡片 vs 传统卡片在module.json5中我们可以同时声明两种卡片类型的 ExtensionAbility[entry/src/main/module.json5]{extensionAbilities:[{name:EntryFormAbility,srcEntry:./ets/entryformability/EntryFormAbility.ets,type:form,// 传统卡片metadata:[{name:ohos.extension.form,resource:$profile:form_config}]},{name:SleepLiveCardAbility,srcEntry:./ets/livecardability/SleepLiveCardAbility.ets,type:liveForm// 互动卡片}]}传统卡片对应FormExtensionAbility而互动卡片对应LiveFormExtensionAbility。二者最核心的差异体现在三个层面生命周期模型传统卡片通过onAddForm、onUpdateForm、onFormEvent等回调与卡片交互本质上是一种事件驱动的轻量模型。而互动卡片通过onLiveFormCreate获得一个UIExtensionContentSession拥有独立的 UI 渲染能力本质上是一个UIExtension的增强形态。渲染能力传统卡片的 UI 由 ArkTS widget 页面渲染不支持帧动画、传感器数据、实时媒体播放等能力。互动卡片则可以运行完整的帧动画如睡眠卡片的憨憨动画、集成陀螺仪传感器如快递卡片、使用 AVPlayer 播放音乐等。通信方式传统卡片通过postCardAction向指定的 Ability 发送事件接收方在onFormEvent中处理。互动卡片除了支持postCardAction还能通过LocalStorage与主 Ability 共享数据并通过callee.on(cardAction, ...)注册方法调用处理。从代码结构上看传统卡片的 UI 页面位于widget/pages/目录下而互动卡片的 UI 页面位于livecardability/pages/目录下——这不仅仅是路径的差异更代表了两种完全不同的运行环境。LiveFormExtensionAbility 生命周期onLiveFormCreate 的同步调用约束LiveFormExtensionAbility的核心生命周期方法是onLiveFormCreate它在用户将卡片添加到桌面时被调用。该方法接收两个参数LiveFormInfo携带卡片元数据和UIExtensionContentSession用于加载卡片 UI。在 LiveCard 项目中我们可以看到同步与异步两种写法[entry/src/main/ets/livecardability/SleepLiveCardAbility.ets]exportclassSleepLiveCardAbilityextendsLiveFormExtensionAbility{onLiveFormCreate(liveFormInfo:LiveFormInfo,session:UIExtensionContentSession):void{letstorage:LocalStoragenewLocalStorage();storage.setOrCreate(context,this.context);storage.setOrCreate(session,session);letformId:stringliveFormInfo.formId;storage.setOrCreate(formId,formId);letborderRadius:numberliveFormInfo.borderRadius;storage.setOrCreate(borderRadius,borderRadius);letformRect:formInfo.RectliveFormInfo.rect;storage.setOrCreate(formRect,formRect);try{session.loadContent(livecardability/pages/SleepLiveCard,storage);}catch(error){Logger.error(TAG,loadContent catch error, code:${error.code}, message:${error.message});}}}而音乐卡片则是异步版本[entry/src/main/ets/livecardability/MusicLiveCardAbility.ets]exportclassMusicLiveCardAbilityextendsLiveFormExtensionAbility{asynconLiveFormCreate(liveFormInfo:LiveFormInfo,session:UIExtensionContentSession):Promisevoid{// ... 初始化 LocalStorage ...session.loadContent(livecardability/pages/MusicLiveCard,storage);// 异步数据加载letactionDataMusicFileStore.getTriggerAction(this.context);letsongRdbHelperSongRdbHelper.getInstance(this.context);letinitSongs:SongItem[]awaitsongRdbHelper.queryAllSongs();// ... 继续初始化 ...}}这里有一个重要的设计考虑虽然onLiveFormCreate可以声明为async但session.loadContent()的调用应该尽早执行不应被await阻塞。音乐卡片的做法是正确的——先调用loadContent加载 UI再执行异步数据初始化数据通过LocalStorage传递给卡片组件。LiveFormInfo 的数据结构LiveFormInfo包含了互动卡片运行所需的核心参数formId卡片的唯一标识后续所有formProvider.updateForm()操作都需要它borderRadius卡片的圆角值用于与卡片 UI 保持一致rectformInfo.Rect类型包含width、height、left、top标识卡片在桌面的位置和尺寸这些参数通过LocalStorage传递到卡片组件中使得组件能够自适应桌面布局。sceneAnimationParams 机制abilityName 的配置与系统激活流程在form_config.json中每个卡片的配置都包含sceneAnimationParams字段[entry/src/main/resources/base/profile/form_config.json]{forms:[{name:SleepCard,src:./ets/widget/pages/SleepCard.ets,isDynamic:true,sceneAnimationParams:{abilityName:SleepLiveCardAbility}},{name:DeliveryCard,sceneAnimationParams:{abilityName:DeliveryLiveCardAbility,triggerTypes:[shake]}}]}sceneAnimationParams是传统卡片与互动卡片之间的桥梁。它的工作流程如下用户将卡片添加到桌面系统首先加载传统卡片widget/pages/SleepCard.ets这是一个普通的 Form 卡片当用户点击卡片或满足触发条件时系统检测sceneAnimationParams.abilityName配置系统激活对应的LiveFormExtensionAbility即SleepLiveCardAbilityonLiveFormCreate被调用互动卡片 UI 通过UIExtensionContentSession加载此时桌面上的卡片从静态 widget无缝切换为互动卡片这个机制实现了一种渐进式增强的卡片体验——用户看到的是同一张卡片但系统在后台完成了从轻量 widget 到全功能 UIExtension 的升级。对于快递卡片triggerTypes还包含shake这意味着除了点击触发外系统还可以通过摇一摇传感器事件来激活互动状态。多卡片协作架构LiveCard 项目中存在四种完全不同的互动卡片它们如何共享同一个主 Ability 却又各自独立运行答案藏在架构设计中。单 Ability 多 Extension 模式┌─────────────────────────────────────────────┐ │ EntryAbility │ │ (LiveCardAbility / UIAbility) │ │ │ │ ├─ CardActionHandler (callee 注册) │ │ ├─ MediaService (全局音乐服务) │ │ └─ FormUtils (数据管理) │ ├─────────────────────────────────────────────┤ │ │ │ ExtensionAbilities (各自独立进程上下文) │ │ │ │ SleepLiveCardAbility ─── SleepLiveCard.ets │ │ DeliveryLiveCardAbility ─── DeliveryLiveCard│ │ ExerciseLiveCardAbility ─── ExerciseLiveCard│ │ MusicLiveCardAbility ─── MusicLiveCard │ └─────────────────────────────────────────────┘每个LiveFormExtensionAbility都是独立的 Extension拥有自己的 Context。它们通过LocalStorage与各自的卡片页面通信互不干扰。跨进程通信的三条路径卡片与主 Ability 之间的通信主要通过以下三种方式路径一postCardAction CALL 模式[entry/src/main/ets/utils/ActionUtils.ets]publicplayByAction(component:object,type:PlayActionType,formId:string):void{postCardAction(component,{action:FormCarAction.CALL,abilityName:ENTRY_ABILITY,// LiveCardAbilityparams:{method:cardAction,actionType:CardActionType.PLAY_ACTION,playActionType:type,formId:formId,},});}主 Ability 通过this.callee.on(cardAction, CardActionHandler.getHandler())注册处理方法CardActionHandler根据actionType分发到不同的处理逻辑。路径二postCardAction MESSAGE 模式publicrequestOverFlow(component:object,widthRatio:number,heightRatio:number,duration:number):void{postCardAction(component,{action:FormCarAction.MESSAGE,abilityName:ENTRY_FORM_ABILITY,// EntryFormAbilityparams:{message:requestOverflow,widthRatio:widthRatio,heightRatio:heightRatio,duration:duration},});}MESSAGE 消息发送到EntryFormAbility在onFormEvent回调中处理。这主要用于触发卡片的溢出动画overflow animation。路径三formProvider.updateForm 推送数据publicasyncupdateExerciseCardState(context:Context,state:number):Promisevoid{letformList:FormInfo[]awaitFormRdbHelper.getInstance(context).queryFormByName(ExerciseCard);formList.forEach((formInfo){classExerciseUpdateData{publiccurrentState:numberstate;publiccalories:number0;}this.updateForm(formInfo.formId,newExerciseUpdateData());});}主 Ability 通过formProvider.updateForm()主动向所有同名卡片推送数据更新。卡片组件上使用LocalStorageProp或LocalStorageLink装饰器接收这些数据。数据持久化的统一入口虽然每种卡片各有独立的数据存储ExerciseFileStore、MusicFileStore、FormRdbHelper但所有数据操作都通过FormUtils这个统一入口类对外暴露。主页面、卡片、Extension Ability 都通过FormUtils来读写数据保持了数据层的整洁。关键配置解读form_config.json 中的关键配置项isDynamic: true启用卡片的动态能力。这是互动卡片的基础开关设置为true后卡片才能接收formProvider.updateForm()的更新。supportDimensions: [2*4]定义卡片支持的网格尺寸。睡眠卡片和音乐卡片使用2*4两列四行快递卡片和运动卡片使用2*2。这决定了卡片在桌面的布局占比。defaultDimension: 2*4卡片首次添加到桌面时的默认尺寸。updateEnabled: false禁用系统的自动定时更新机制。LiveCard 项目中的卡片通过formProvider.updateForm()手动触发数据更新因此不需要系统级的定时刷新。sceneAnimationParams.abilityName如前所述这是连接传统 widget 与互动卡片 Extension 的桥梁指定了激活哪一个LiveFormExtensionAbility。module.json5 中的关键配置项type: liveForm这是将 ExtensionAbility 标记为互动卡片类型的关键。没有这个字段系统不会将其识别为 LiveFormonLiveFormCreate也不会被调用。metadata的差异传统卡片需要metadata字段指定ohos.extension.form资源配置而互动卡片不需要——因为互动卡片的配置直接在form_config.json中通过sceneAnimationParams引用。Entry({ useSharedStorage: true })互动卡片页面组件上的装饰器参数。useSharedStorage: true表示使用共享存储这是与LiveFormExtensionAbility共享LocalStorage数据的前提。源码走读SleepLiveCardAbility 初始化流程最后我们以睡眠卡片为例完整走通一条初始化链路。Step 1传统卡片加载用户添加卡片系统加载widget/pages/SleepCard.ets。这个页面是静态的显示憨憨和三叶草的静态图片通过isSleep状态切换睡觉和起床两种样式。用户点击卡片时调用ActionUtils.requestOverFlow()通过 MESSAGE 通知EntryFormAbility.onClick((){if(this.isSleep){ActionUtils.requestOverFlow(this,LiveCardScale.SLEEP_WIDTH,LiveCardScale.SLEEP_HEIGHT,LIVE_CARD_DURATION);}else{ActionUtils.jumpAppPage(this,SleepReport);}})Step 2系统激活 LiveFormExtensionAbilityEntryFormAbility.onFormEvent接收到requestOverflow消息后调用formProvider.requestOverflow()触发溢出动画。同时因为form_config.json中SleepCard配置了sceneAnimationParams.abilityName: SleepLiveCardAbility系统自动激活SleepLiveCardAbility。Step 3onLiveFormCreate 执行onLiveFormCreate(liveFormInfo:LiveFormInfo,session:UIExtensionContentSession):void{// 1. 创建 LocalStorage建立数据通道letstorage:LocalStoragenewLocalStorage();storage.setOrCreate(context,this.context);storage.setOrCreate(session,session);// 2. 从 LiveFormInfo 提取卡片元数据letformId:stringliveFormInfo.formId;storage.setOrCreate(formId,formId);letborderRadius:numberliveFormInfo.borderRadius;storage.setOrCreate(borderRadius,borderRadius);letformRect:formInfo.RectliveFormInfo.rect;storage.setOrCreate(formRect,formRect);// 3. 加载互动卡片 UI 页面session.loadContent(livecardability/pages/SleepLiveCard,storage);}Step 4互动卡片 UI 启动SleepLiveCard组件通过LocalStorageProp从LocalStorage中获取formId、formRect、borderRadius。在aboutToAppear中初始化帧动画的累积时间表并在 1 秒后通过formProvider.updateForm()通知传统卡片更新状态aboutToAppear():void{this.initCumulativeTimes();setTimeout((){letformMsg:formBindingData.FormBindingDataformBindingData.createFormBindingData({isSleep:false});formProvider.updateForm(this.formId,formMsg);},1000);}Step 5帧动画驱动卡片通过setInterval每 16ms约 60fps更新一帧根据经过时间计算当前应显示的帧索引。帧列表通过FrameItem的weight属性支持停留时长权重使某些关键帧可以多停留一段时间形成更自然的动画节奏。startImageSync():void{this.animStartTimeDate.now();this.imageSyncTimersetInterval((){constelapsedDate.now()-this.animStartTime;// 根据经过时间计算帧索引constnewHanhanFramethis.getFrameByElapsed(elapsed,this.hanhanCumulativeTime,...);constnewCloverFramethis.getFrameByElapsed(elapsed,this.cloverCumulativeTime,...);// 更新状态驱动 UI 刷新this.currentHanhanFrameIndexnewHanhanFrame;this.currentCloverFrameIndexnewCloverFrame;},16);}当动画播放完毕达到LIVE_CARD_DURATION 3500ms憨憨从睡眠状态切换为起床状态同时通过formProvider.updateForm()反向同步传统卡片的状态——实现了互动卡片与传统卡片的数据联动。总结互动卡片的架构设计呈现了 HarmonyOS 服务卡片从静态展示到动态交互的演进路径。通过LiveFormExtensionAbilityUIExtensionContentSession的组合开发者获得了完整的 UI 渲染能力而sceneAnimationParams机制则巧妙地解决了传统 widget 与互动卡片之间的衔接过渡问题。LiveCard 项目展示的四种卡片各具特色在共享同一套架构基础的同时通过postCardAction通信、formProvider.updateForm数据推送、以及callee方法注册等机制实现了丰富的交互体验。

相关新闻

A*启发式智能批次选择算法:加速CNN训练效率的工程实践

A*启发式智能批次选择算法:加速CNN训练效率的工程实践

在深度学习模型训练过程中,数据加载和批次选择策略往往被忽视,但实际对训练效率有着显著影响。传统的随机批次选择方法虽然简单易用,但在处理大规模数据集时可能导致收敛速度慢、资源利用率低等问题。本文介绍一种受A*搜索算法启发的智能批次…

2026/7/29 12:32:47 阅读更多 →
专业工具集如何提升数字营销与创意设计效率

专业工具集如何提升数字营销与创意设计效率

1. 为什么专业工具集如此重要?在数字营销和创意设计领域,效率就是生命线。我从业十年间亲眼见证过太多团队因为工具链落后而陷入无意义的重复劳动——设计师手动调整上百张图片尺寸,运营人员逐个平台复制粘贴相同内容,广告优化师熬…

2026/7/29 2:18:04 阅读更多 →
AI Agent技术解析:从架构到实战应用

AI Agent技术解析:从架构到实战应用

1. AI Agent技术全景解析:从概念到实战AI Agent(人工智能代理)正以惊人的速度重塑我们的数字世界。不同于传统AI模型,这些具备自主决策能力的智能体能够独立规划任务、调用工具并持续学习优化。想象一下,当你计划一次冲…

2026/7/26 22:59:51 阅读更多 →

最新新闻

Spring Cloud Config微服务配置管理核心实践

Spring Cloud Config微服务配置管理核心实践

1. Spring Cloud Config 核心价值解析 在微服务架构中,配置管理往往成为最容易被忽视却又最常引发生产事故的环节。我经历过凌晨三点被紧急呼叫处理配置错误的惨痛教训后,彻底理解了Spring Cloud Config的价值所在。这个分布式配置中心解决方案&#xff…

2026/7/30 10:37:18 阅读更多 →
SWOT、波特五力与PEST分析实战:从理论到商业决策的结构化框架

SWOT、波特五力与PEST分析实战:从理论到商业决策的结构化框架

1. 项目概述:为什么企业竞争分析不是“玄学” 在商业世界里,我们常常听到“战略”、“竞争”、“市场格局”这些词,听起来宏大又有点虚。很多创业者或者业务负责人,一提到做竞争分析,要么是凭感觉拍脑袋,要…

2026/7/30 10:37:18 阅读更多 →
OpenLayers加载WMTS服务全攻略:从原理到实战避坑指南

OpenLayers加载WMTS服务全攻略:从原理到实战避坑指南

1. 从一次地图服务对接的“翻车”说起 最近在做一个智慧园区项目,需要将不同来源的卫星影像、地形数据和业务图层整合到一张图上。客户提供了几个不同单位的WMTS服务地址,我心想这还不简单?OpenLayers作为老牌的地图库,加载个标准…

2026/7/30 10:37:18 阅读更多 →
STM32平衡车PID调参实战:从原理到参数整定全解析

STM32平衡车PID调参实战:从原理到参数整定全解析

1. 项目概述:从“立起来”到“稳得住”的最后一公里 搞过平衡车的朋友都知道,前两天的活儿——硬件焊接、基础代码框架搭建、传感器数据读取——虽然繁琐,但更多是体力活和按图索骥的流程。真正让人又爱又恨、决定项目成败的,就是…

2026/7/30 10:37:18 阅读更多 →
SpringBoot+Vue+MySQL全栈学生管理系统开发指南

SpringBoot+Vue+MySQL全栈学生管理系统开发指南

1. 项目概述:SpringBootVueMySQL全栈学生管理系统 这套学生信息管理系统采用当下主流的前后端分离架构,后端基于SpringBoot 2.x开发,前端使用Vue 3.x框架,数据库选用MySQL 8.0。作为教学级项目,它完整实现了学生信息的…

2026/7/30 10:37:18 阅读更多 →
2026年AI Agent安全危机:从GPT-5.6逃逸事件看多智能体系统的安全攻防实战

2026年AI Agent安全危机:从GPT-5.6逃逸事件看多智能体系统的安全攻防实战

2026年AI Agent安全危机:从GPT-5.6逃逸事件看多智能体系统的安全攻防实战当AI Agent学会"越狱"——一场改写AI安全规则的"斯普特尼克时刻"一、事件回顾:GPT-5.6 Sol 的"越狱"之夜2026年7月21日,一则新闻引爆了…

2026/7/30 10:36:18 阅读更多 →

日新闻

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 您是否曾因Windows系统盘空间不足而烦恼?是否遇到过设…

2026/7/30 0:00:13 阅读更多 →
如何3步掌握Video Download Helper:网页视频下载的完整实战指南

如何3步掌握Video Download Helper:网页视频下载的完整实战指南

如何3步掌握Video Download Helper:网页视频下载的完整实战指南 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper 你是否曾经在浏览…

2026/7/30 0:00:13 阅读更多 →
“双减”后首个AI备课压力测试报告:覆盖32所中小学的176节AI辅助课,暴露4大隐性增负节点

“双减”后首个AI备课压力测试报告:覆盖32所中小学的176节AI辅助课,暴露4大隐性增负节点

更多请点击: https://intelliparadigm.com 第一章:AI 教师备课辅助 AI 教师备课辅助系统正逐步成为教育数字化转型的核心支撑工具,它并非替代教师,而是通过语义理解、知识图谱与多模态生成能力,将教师从重复性劳动中解…

2026/7/30 0:00:13 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/29 22:18:20 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/29 15:00:03 阅读更多 →

月新闻