HarmonyOS 互动卡片通信架构:三方跨进程数据传递与状态回推全解析
2026/8/14 18:59:03 网站建设 项目流程

HarmonyOS 互动卡片通信架构:三方跨进程数据传递与状态回推全解析

前言

互动卡片里最容易出 bug 的不是动画,而是数据从哪来到哪去。动态卡片、宿主应用、互动卡片(激活态 UI)三者不在同一进程、生命周期也各管各的,通信方式选错轻则收不到数据、重则直接失效。

本文作为互动卡片系列的第三篇,将系统拆解三方通信架构——从动态卡片到应用页面跳转、从应用到卡片数据推送、从互动卡片到动态卡片状态回推,再到跨进程持久化存储,逐一讲解每种通信方式的核心 API 和适用场景。

一、三方通信架构全景

1.1 通信角色与关系

互动卡片涉及三个独立角色,它们之间需要多种通信方式协作:

图:互动卡片三方通信架构——动态卡片、应用、互动卡片之间的多种通信方式

角色进程生命周期管理方
动态卡片(非激活态)独立进程卡片在桌面时存活FormExtensionAbility
宿主应用主进程应用前台/后台EntryAbility
互动卡片(激活态)独立进程激活期间存活LiveFormExtensionAbility

1.2 七种通信方式总览

通信方向方式核心 API说明
动态卡片 → 应用页面跳转postCardAction(ROUTER)点击卡片跳转到应用页面
动态卡片 → 应用方法调用postCardAction(CALL)通过callee监听调用应用方法
动态卡片 → FormExtensionAbility发送消息postCardAction(MESSAGE)通过onFormEvent接收处理
应用 → 动态卡片数据推送formProvider.updateForm+formBindingData键值对自动映射到@LocalStorageProp
应用 → 互动卡片数据持久化用户首选项/RDB/文件存储跨进程通信,LiveFormExtensionAbility 读取
互动卡片内部共享存储LocalStorage同进程内传递初始数据
互动卡片 → 动态卡片数据回推formProvider.updateForm实况卡片状态变化回推到动态卡片

二、动态卡片 → 应用通信

2.1 页面跳转(ROUTER)

最常用的通信方式,用户点击卡片跳转到应用指定页面:

// 在卡片 UI 中调用postCardAction(this,{action:'router',abilityName:'EntryAbility',params:{targetPage:'DeliveryPage'// 目标页面名称}});

封装为工具方法:

exportclassActionUtils{/** * 卡片跳转到应用页面 */staticjumpAppPage(component:object,pageName:string):void{postCardAction(component,{action:'router',abilityName:'EntryAbility',params:{targetPage:pageName}});}}

2.2 方法调用(CALL)

卡片直接调用应用中的方法,通过callee监听实现:

// 1. 卡片端:发送 CALL 请求postCardAction(this,{action:'call',abilityName:'EntryAbility',params:{method:'playMusic',songId:'12345'}});// 2. 应用端:在 EntryAbility 中注册 callee 监听import{UIAbility,Want}from'@kit.AbilityKit';exportdefaultclassEntryAbilityextendsUIAbility{onCreate(want:Want):void{this.callee.on('call',(indata)=>{constmethod=indata.parameters.methodasstring;switch(method){case'playMusic':this.handlePlayMusic(indata.parameters.songId);break;case'pauseMusic':this.handlePauseMusic();break;}});}privatehandlePlayMusic(songId:string):void{console.info(`播放音乐:${songId}`);}privatehandlePauseMusic():void{console.info('暂停音乐');}}

三、动态卡片 → FormExtensionAbility 通信

3.1 消息发送(MESSAGE)

卡片通过postCardAction(MESSAGE)发送消息到FormExtensionAbility,这是互动卡片激活的关键路径:

// 卡片端:发送消息constparams={message:'requestOverflow',widthRatio:1.3,heightRatio:1.3,duration:5000};postCardAction(this,{action:'message',message:JSON.stringify(params)});// FormExtensionAbility 端:接收消息asynconFormEvent(formId:string,message:string):Promise<void>{constparams=JSON.parse(message);constmsgType=params.messageasstring;if(msgType==='requestOverflow'){awaitthis.requestOverflow(formId,params.widthRatio,params.heightRatio,params.duration);}}

四、应用 → 动态卡片数据推送

4.1 formProvider.updateForm

应用通过formProvider.updateForm向动态卡片推送数据,数据自动映射到卡片的@LocalStorageProp变量:

import{formProvider,formBindingData}from'@kit.FormKit';/** * 应用向动态卡片推送数据 */asyncfunctionupdateCardData(formId:string,data:Record<string,Object>):Promise<void>{try{constbindingData=formBindingData.createFormBindingData(data);awaitformProvider.updateForm(formId,bindingData);console.info('卡片数据更新成功');}catch(err){console.error(`卡片数据更新失败:${JSON.stringify(err)}`);}}// 使用示例:更新睡眠卡片状态awaitupdateCardData(formId,{isSleep:false,sleepTime:'07:30',wakeStatus:'按时起床'});
// 卡片端:接收数据@Entry@Componentstruct SleepCard{@LocalStorageProp('isSleep')isSleep:boolean=true;@LocalStorageProp('sleepTime')sleepTime:string='07:00';@LocalStorageProp('wakeStatus')wakeStatus:string='';build(){Column(){Image(this.isSleep?$rawfile('sleep/sleep_hanhan.png'):$rawfile('sleep/wake_hanhan.png')).width('60%').height('60%')Text(this.isSleep?'睡眠中':this.wakeStatus).fontSize(14).fontColor('#666')}}}

五、应用 → 互动卡片跨进程数据持久化

5.1 三种持久化方案

应用与互动卡片(激活态 UI)在不同进程,需要使用持久化存储传递数据:

方案API适用场景性能
用户首选项(Preferences)@kit.ArkData简单键值对(开关状态)
关系型数据库(RDB)@kit.ArkData结构化数据(歌曲列表)
文件存储@kit.CoreFileKit大量数据或上下文

5.2 用户首选项存储

import{preferences}from'@kit.ArkData';/** * 应用端:保存运动状态 */exportclassExerciseStateManager{privatestaticreadonlyPREF_NAME='exercise_state';staticasyncsaveExerciseState(state:ExerciseState):Promise<void>{constprefs=awaitpreferences.getPreferences(getContext(),ExerciseStateManager.PREF_NAME);awaitprefs.put('isExercising',state.isExercising);awaitprefs.put('calories',state.calories);awaitprefs.flush();}staticasyncgetExerciseState():Promise<ExerciseState>{constprefs=awaitpreferences.getPreferences(getContext(),ExerciseStateManager.PREF_NAME);return{isExercising:prefs.get('isExercising',false)asboolean,calories:prefs.get('calories',0)asnumber};}}interfaceExerciseState{isExercising:boolean;calories:number;}

5.3 关系型数据库存储

音乐卡片使用 RDB 存储歌曲列表和收藏状态,实现跨进程数据同步:

import{relationalStore}from'@kit.ArkData';/** * 音乐卡片数据管理器(RDB) */exportclassMusicDataManager{privatestaticstore:relationalStore.RdbStore|null=null;staticasyncinitDatabase(context:Context):Promise<void>{constconfig:relationalStore.StoreConfig={name:'MusicCard.db',securityLevel:relationalStore.SecurityLevel.S1};MusicDataManager.store=awaitrelationalStore.getRdbStore(context,config);// 创建歌曲表awaitMusicDataManager.store.executeSql(`CREATE TABLE IF NOT EXISTS songs ( id TEXT PRIMARY KEY, title TEXT NOT NULL, artist TEXT NOT NULL, isFavorite INTEGER DEFAULT 0 )`);}staticasyncgetSongs():Promise<SongInfo[]>{constresultSet=awaitMusicDataManager.store!.querySql('SELECT * FROM songs');constsongs:SongInfo[]=[];while(resultSet.goToNextRow()){songs.push({id:resultSet.getString(0),title:resultSet.getString(1),artist:resultSet.getString(2),isFavorite:resultSet.getLong(3)===1});}resultSet.close();returnsongs;}staticasyncupdateFavorite(songId:string,isFavorite:boolean):Promise<void>{awaitMusicDataManager.store!.executeSql('UPDATE songs SET isFavorite = ? WHERE id = ?',[isFavorite?1:0,songId]);}}interfaceSongInfo{id:string;title:string;artist:string;isFavorite:boolean;}

六、互动卡片 → 动态卡片状态回推

6.1 状态回推机制

互动卡片(激活态)中状态变化后,需要通过formProvider.updateForm将状态回推到动态卡片,确保非激活态显示正确的状态:

// 在互动卡片 UI 中回推状态import{formProvider,formBindingData}from'@kit.FormKit';/** * 互动卡片状态回推到动态卡片 */asyncfunctionpushStateBackToCard(formId:string,state:Record<string,Object>):Promise<void>{try{constbindingData=formBindingData.createFormBindingData(state);awaitformProvider.updateForm(formId,bindingData);console.info(`状态回推成功:${JSON.stringify(state)}`);}catch(err){console.error(`状态回推失败:${JSON.stringify(err)}`);}}// 睡眠卡片:动画结束后回推 isSleep 状态awaitpushStateBackToCard(this.formId,{isSleep:false,wakeStatus:'按时起床'});// 运动卡片:运动结束后回推卡路里数据awaitpushStateBackToCard(this.formId,{calories:300,isExercising:false});

6.2 四种卡片的状态回推

卡片回推内容触发时机
睡眠卡片isSleepwakeStatus起床动画结束后
快递卡片无需回推(状态无变化)-
运动卡片caloriesisExercising运动结束后
音乐卡片当前歌曲、播放状态切歌、播放状态变化时

七、互动卡片内部 LocalStorage 传递

7.1 LocalStorage 传递初始数据

LiveFormExtensionAbility通过LocalStorage向互动卡片 UI 传递初始数据:

// LiveFormExtensionAbility 中设置 LocalStorageonLiveFormCreate(liveFormInfo:LiveFormInfo,session:UIExtensionContentSession):void{conststorage:LocalStorage=newLocalStorage();// 传递上下文storage.setOrCreate('context',this.context);storage.setOrCreate('session',session);// 传递卡片信息storage.setOrCreate('formId',liveFormInfo.formId);storage.setOrCreate('borderRadius',liveFormInfo.borderRadius);storage.setOrCreate('formRect',liveFormInfo.rect);// 加载 UIsession.loadContent('livecardability/pages/DeliveryLiveCard',storage);}// 互动卡片 UI 中读取@Entry({useSharedStorage:true})@Componentstruct DeliveryLiveCard{@LocalStorageProp('formRect')rect?:formInfo.Rect=undefined;@LocalStorageProp('borderRadius')radius:number=0;@LocalStorageProp('formId')formId:string='';build(){Stack({alignContent:Alignment.TopStart}){Image($rawfile('delivery/background.png')).borderRadius(this.radius).width(this.rect?.width||0).height(this.rect?.height||0)}}}

八、通信方式选型指南

8.1 选型决策树

场景推荐方式原因
卡片跳转应用页面postCardAction(ROUTER)直接、简单
卡片调用应用方法postCardAction(CALL)支持方法调用和返回
卡片触发激活动画postCardAction(MESSAGE)必须经过 FormExtensionAbility
应用推送数据到卡片formProvider.updateForm唯一方式
应用传递数据到互动卡片用户首选项/RDB/文件跨进程,持久化
互动卡片回推状态formProvider.updateForm确保非激活态正确

8.2 各卡片使用的通信方式

卡片通信方式组合
睡眠卡片ROUTER(跳转页面)+ MESSAGE(触发动画)+updateForm(回推 isSleep)+ LocalStorage(内部传递)
音乐卡片CALL(播放控制)+ ROUTER(跳转页面)+ MESSAGE(触发动画)+ RDB(歌曲数据)+updateForm(同步状态)
运动卡片CALL(运动控制)+ ROUTER(跳转页面)+ MESSAGE(触发动画)+ 文件存储(运动状态)+updateForm(回推卡路里)
快递卡片ROUTER(跳转页面)+ MESSAGE(触发动画)+ LocalStorage(内部传递)

九、总结

本文系统拆解了互动卡片的三方通信架构:

  • 七种通信方式:ROUTER、CALL、MESSAGE、updateForm、持久化存储、LocalStorage、状态回推
  • 动态卡片 → 应用:页面跳转(ROUTER)和方法调用(CALL)两种方式
  • 应用 → 动态卡片:唯一方式formProvider.updateForm+formBindingData
  • 应用 → 互动卡片:三种持久化方案(Preferences / RDB / 文件存储)
  • 互动卡片 → 动态卡片formProvider.updateForm状态回推,确保非激活态正确显示

下一篇将以快递卡片和睡眠卡片为主线,深入讲解完整开发流程与帧动画、陀螺仪交互、破框效果的实战实现。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

  • 互动卡片开发实践文档:华为开发者文档
  • 互动卡片示例代码:GitCode
  • 用户首选项开发:华为开发者文档
  • 关系型数据库开发:华为开发者文档
  • 开源鸿蒙跨平台社区:CSDN 社区

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询