版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
项目8:卡片及元服务元服务是HarmonyOS面向未来的免安装服务形式,是原生智能的最佳载体,具备精准服务触达和原生自然体验。卡片作为应用入口之一,能为用户带来更好的元服务体验。本项目详细讲解卡片及元服务开发知识。导学:学习目标总览知识目标理解服务卡片概念与使用场景掌握卡片运行机制及开发步骤理解元服务概念与使用场景了解AppGalleryConnect平台了解卡片与元服务之间的关系掌握元服务开发流程能力目标能为传统应用及元服务应用创建卡片能运用卡片事件刷新卡片能应用ArkUI设计卡片页面能在AppGalleryConnect中创建元服务应用能在DevEcoStudio中创建元服务工程能应用元服务API开发元服务应用素质目标培养独立分析问题、解决问题的能力培养科学严谨的学习工作态度养成良好的职业素养任务1音乐播放卡片设计任务描述:实现一个音乐播放应用,为该应用创建音乐播放卡片。在卡片上点击播放按钮,应用能在后台播放音乐,按钮状态在"播放"与"暂停"之间切换;点击卡片按钮之外的区域能拉起应用播放页面;播放页面的播放按钮状态必须与卡片上的播放按钮状态保持同步;当为应用添加卡片时,卡片上的播放按钮状态必须与应用播放页面的播放按钮状态一致。8.1卡片开发基础桌面卡片不仅可作为传统应用的入口,也可作为元服务应用入口,使用户更为快捷、方便地拉起应用。卡片对传统应用及元服务应用而言不是必需,但能有效提升用户的使用体验。什么是卡片服务卡片类似桌面图标,提供界面展示形式,两者均能拉起应用。但图标内容不支持交互,而卡片则可以,如实现卡片界面刷新等。卡片还可将应用的重要信息或操作前置,达到服务直达、减少跳转层级的体验效果,并提供定时、定点等多种刷新机制,实现卡片永久在线。卡片分类(渲染层面)动态卡片:支持动效能力,可频繁刷新。静态卡片:使用最后一帧渲染数据,释放所有运行资源以节省内存,不支持动效,不能频繁刷新(会增加系统开销)。卡片分类(存在时间)临时卡片:短期存在,在特定事件触发后显示,完成展示目的后自动消失。可通过onCastToNormalForm()接口转为常态卡片,但目前桌面不使用临时卡片,暂无场景触发该接口。常态卡片:长期存在于桌面。服务直达以卡片形式呈现核心信息,简化交互流程,无须频繁跳转层级。永久在线提供定时、代理等多种卡片刷新机制,实现卡片永久在线发送消息。受限管控卡片支持的组件、事件、动画、数据管理、状态管理和API均进行了限制,保障性能、功耗及安全可靠。8.1.2卡片运行机制图8-1ArkTS卡片运行机制卡片运行机制:四大角色卡片使用方显示卡片内容的宿主应用,控制卡片在宿主中展示的位置。当前仅系统应用(如桌面)可作为卡片使用方。卡片提供方提供卡片显示内容的应用,控制卡片的显示内容、控件布局以及控件点击事件。卡片管理服务管理系统中所添加卡片的常驻代理服务,提供formProvider接口能力,同时提供卡片对象的管理与使用以及卡片周期性刷新等能力。卡片渲染服务管理卡片渲染实例,渲染实例与卡片使用方上的卡片组件一一绑定。运行卡片页面代码widgets.abc进行渲染,并将渲染后的数据发送至对应的卡片组件。卡片采用专门的卡片渲染服务执行页面代码,由卡片管理服务监管。属于同一应用提供方的渲染实例在同一ArkTS虚拟机环境中运行,不同应用提供方的渲染实例在各自独立的ArkTS虚拟机环境中运行,实现资源与状态的有效隔离。应用的主进程持有UIAbility,卡片进程持有FormExtensionAbility,两者相互独立。8.1.3卡片生命周期回调FormExtensionAbility作为卡片扩展模块,提供卡片创建、销毁、刷新等生命周期回调。需要注意的是,FormExtensionAbility实例创建后5秒内无操作将会被清理,可以用message事件机制重新拉起。onAddForm(want)使用方创建卡片时触发,返回卡片页面绑定的数据。参数Want包含卡片ID、卡片名称、卡片样式等,这些信息必须作为持久数据管理,以便后续更新和删除卡片。onCastToNormalForm(formId)卡片提供方接收临时卡片转常态卡片的通知。onUpdateForm(formId)卡片定时更新/定点更新/卡片使用方主动请求更新卡片时触发。获取最新数据后调用formProvider的updateForm()接口刷新卡片数据。onFormEvent(formId,message)卡片提供方接收处理卡片事件的通知。onRemoveForm(formId)卡片提供方接收销毁卡片的通知。onAcquireFormState(want)卡片提供方接收查询卡片状态通知,默认返回卡片初始状态(该方法可以选择性重写)。8.1.4卡片开发模块及配置核心开发模块FormExtensionAbility卡片扩展模块,提供卡片创建、销毁、刷新等生命周期回调接口,运行在单独进程中,与UIAbility分离。formProvider通过updateForm()、setFormNextRefreshTime()及getFormsInfo()接口实现更新卡片、设置下次更新时间、获取卡片信息。formBindingData提供卡片页面绑定数据功能。createFormBindingData()接口创建FormBindingData对象,数据保存在卡片持有的LocalStorage中,通常与@LocalStorageProp修饰的状态量绑定。postCardAction/FormLinkpostCardAction用于动态卡片内部与提供方应用间的交互;FormLink用于静态卡片交互,仅用于卡片页面。form_config.json关键配置项name:卡片名称,最大127字节displayName:展示名称,1~30字节src:卡片UI代码文件路径uiSyntax:卡片类型(arkts/html)colorMode:主题样式(auto/dark/light)isDefault:是否为默认卡片updateEnabled:是否支持周期性刷新scheduledUpdateTime:定点刷新时刻(24小时制)updateDuration:定时刷新周期(单位:30分钟)defaultDimension:默认外观规格(如2*2)isDynamic:是否为动态卡片dataProxyEnabled:是否支持代理刷新8.1.5为应用添加卡片按压应用图标,弹出菜单,选择"卡片"选项,点击"添加至桌面"按钮,即可完成卡片添加。图8-2添加卡片:长按应用图标→选择"卡片"→点击"添加至桌面"8.2卡片事件概述为降低鸿蒙系统能耗,卡片进程的存活时间被设定了限制。卡片并非应用的组成部分,而是由系统桌面应用管理的独立服务,仅能通过特定接口进行数据交换和页面管理。每张卡片持有独立的LocalStorage,与应用的LocalStorage隔离,UIAbility与FormExtensionAbility无法直接访问卡片的LocalStorage。因此,鸿蒙系统设计了一套事件机制以触发相关应用,重新与卡片进行数据通信。router事件拉起实体应用到前台,也可通过数据交互刷新卡片内容。在UIAbility的onCreate()或onNewWant()中获取数据。call事件将销毁的应用拉起后到后台,需具备后台运行权限(ohos.permission.KEEP_BACKGROUND_RUNNING)。通过RPC方式传输数据,目前在元服务中不支持。message事件只能与FormExtensionAbility进行通信,如果FormExtensionAbility被清理,可再次拉起以刷新卡片内容。在onFormEvent()回调中获取数据。卡片事件图示(图8-3)图8-3ArkTS卡片事件:router/call事件触发UIAbility;message事件触发FormExtensionAbility的onFormEvent()回调。8.2.2postCardAction()接口与FormLink组件postCardAction()接口与FormLink组件仅用于卡片中,以发送卡片事件与实体应用进行数据交互。前者用于动态卡片,后者用于静态卡片。postCardAction()接口声明postCardAction(component:Object,action:Object):voidaction参数说明action(必填):router/message/callbundleName:router/call时跳转的包名moduleName:router/call时跳转的模块名abilityName:router/call时跳转的UIAbility名uri:router时跳转的统一资源标识符params:携带的额外参数(JSON键值对);call类型时需填入method参数示例:router事件(例8-1)Button('拉起应用至前台').onClick(()=>{postCardAction(this,{action:'router',abilityName:'EntryAbility',params:{message:'Hi'}});});示例:message事件(例8-3)Button('拉起FormExtensionAbility').onClick(()=>{postCardAction(this,{action:'message',params:{message:'Hi'}});});FormLink组件(例8-4)FormLink({action:'router',abilityName:'EntryAbility',params:{message:'Hi'}}){Button('拉起应用至前台')}8.3卡片刷新卡片刷新指卡片页界面内容(如文本、图片等)改变。ArkTS卡片框架提供了formProvider模块的updateForm()和requestForm()接口主动触发卡片的页面刷新,通过卡片持有的LocalStorage确认需要刷新的卡片数据。updateForm()仅提供方调用,只允许刷新自己的卡片;requestForm()仅使用方调用,只允许刷新添加到当前使用方的卡片。1updateForm()接口将数据发送给卡片页面以刷新卡片。参数formId为接收数据的卡片标识;formBindingData为发送的数据,保存于卡片持有的LocalStorage中,常用@LocalStorageProp读取。2createFormBindingData()接口创建FormBindingData对象,封装发送给卡片页面的数据。参数obj通常用Record<key,value>泛型封装,key名称必须与卡片页面中@LocalStorageProp的参数名一致。3getFormsInfo()接口获取设备上当前应用程序的卡片信息。可传入过滤器FormInfoFilter(仅有moduleName属性),返回符合条件的卡片配置信息数组。4setFormNextRefreshTime()接口设置卡片的下一次更新时间。参数formId为卡片标识;minute指定多久之后更新,单位为分钟,值大于或等于5。8.3.2通过卡片事件刷新卡片Router事件Message事件Call事件router事件刷新流程通过postCardAction()触发router事件拉起应用至前台,在onCreate()或onNewWant()中准备数据,获取formId,调用updateForm()发送数据卡片LocalStorage接收数据,用@LocalStorageProp读取并刷新卡片message事件刷新流程通过postCardAction()触发message事件拉起FormExtensionAbility,在onFormEvent()中准备数据,调用updateForm()发送数据卡片LocalStorage接收数据,用@LocalStorageProp读取并刷新卡片call事件刷新流程卡片组件获取卡片formId(通过onAddForm()获取后用updateForm()发送给卡片)通过postCardAction()携带method、formId触发call事件拉起应用至后台,UIAbility的onCreate()中用Callee对象的on()接口订阅回调,在onDestroy()中取消订阅回调中获取formId及数据,调用updateForm()刷新卡片call事件需要应用具备后台运行权限:ohos.permission.KEEP_BACKGROUND_RUNNING,需在module.json5中添加权限声明。卡片刷新效果(图8-4)图8-4卡片刷新(例8-5):点击卡片上的"播放/暂停"按钮,使之来回切换。实例源码参看CardRefresh工程。左图为播放状态,右图为暂停状态。任务实施音乐播放卡片:实施思路01后台播控卡片用call事件拉起实体应用于后台,实现音乐的后台播控。02前台播控卡片用router事件拉起实体应用的播控页面,实现音乐的前台播控,并通过setWindowSystemBarEnable()实现沉浸式窗口。03新卡片状态同步添加卡片时,通过onAddForm()获取formId,传给卡片状态量(用@Watch装饰),在响应函数中触发call事件携带formId,UIAbility订阅回调获取formId及当前播放状态,调用formProvider.updateForm()刷新卡片。04播控按钮同步实体应用播控音乐时,UIAbility获取当前播放状态,通过formProvider.updateForm()刷新卡片,使卡片与应用页面的播控按钮状态保持一致。05MusicService封装将音乐播控逻辑封装为MusicService类。MusicService声明回调函数但不实现,其实现交给EntryAbility;EntryAbility实现回调函数后注入MusicService,MusicService在需要时调用。通过这种方式实现两个类对象之间的数据交互。任务代码:EntryAbility.ets(文件8-1)UIAbility组件,程序入口类。核心逻辑:注册call事件回调、初始化音乐服务、刷新卡片数据。exportdefaultclassEntryAbilityextendsUIAbility{//播放/暂停回调(call事件触发)playOrPauseCallBack=(data:rpc.MessageSequence)=>{letparams=JSON.parse(data.readString());if(params.status==='PAUSE')MusicService.getInstance().play();elseif(params.status==='PLAY')MusicService.getInstance().pause();returnnull;};//添加卡片时初始化卡片播放按钮状态initCardCallBack=(data:rpc.MessageSequence)=>{letparams=JSON.parse(data.readString());if(params.formId){MusicService.getInstance().setPlayStateCall((data:PlayProcessData)=>{this.setPlayProgress(data);this.updateCardData(false,data.isPlay,params.formId);});this.updateCardData(true,AppStorage.get('isPlay'),params.formId);}returnnull;};onCreate(want:Want,launchParam):void{//注册回调函数this.callee.on('METHOD_PLAY_PAUSE',this.playOrPauseCallBack);this.callee.on('METHOD_INIT_CARD',this.initCardCallBack);MusicService.getInstance().initAudioPlayer(this.createSongData());}onDestroy():void{this.callee.off('METHOD_INIT_CARD');this.callee.off('METHOD_PLAY_PAUSE');MusicService.getInstance().release();}}任务代码:WidgetCard.ets(文件8-2)卡片页面。通过@LocalStorageProp绑定卡片数据,点击播放按钮触发call事件,点击其他区域触发router事件拉起应用。@Entry@ComponentstructWidgetCard{readonlyABILITY_NAME:string='EntryAbility';@LocalStorageProp('isPlay')isPlay:boolean=false;@LocalStorageProp('photo')photo:ResourceStr='';@LocalStorageProp('title')title:string='';@LocalStorageProp('singer')singer:string='';@LocalStorageProp('formId')formId:string='';build(){Row(){Column({space:5}){Image(this.photo).size({height:'50%'})Row(){Text(this.title).fontSize(10).fontColor(Color.White)Text('-'+this.singer).fontSize(10).fontColor(Color.White)}//播放/暂停按钮:触发call事件Image(this.isPlay?$r('app.media.ic_public_pause'):$r('app.media.ic_public_play')).width(32).onClick(()=>{postCardAction(this,{action:'call',abilityName:this.ABILITY_NAME,params:{method:'METHOD_PLAY_PAUSE',status:this.isPlay?'PLAY':'PAUSE',formId:this.formId}});})}}.backgroundColor('#6C5748').height('100%').onClick(()=>{//点击非按钮区域:触发router事件拉起应用postCardAction(this,{action:'router',abilityName:this.ABILITY_NAME});})}}任务代码:EntryFormAbility.ets(文件8-3)卡片生命周期接口组件。在onAddForm()中获取formId并发送给卡片,使新添加的卡片能够初始化播控按钮状态。exportdefaultclassEntryFormAbilityextendsFormExtensionAbility{onAddForm(want:Want){if(want.parameters&&want.parameters[formInfo.FormParam.IDENTITY_KEY]!==undefined){letformId=want.parameters[formInfo.FormParam.IDENTITY_KEY].toString();//将formId发送给卡片,卡片收到后触发call事件通知UIAbilityletupdateData:Record={'formId':formId};constcardMsg=formBindingData.createFormBindingData(updateData);formProvider.updateForm(formId,cardMsg).then(()=>{L(TAG,`updateFormsuccessformId:${JSON.stringify(cardMsg)}`);}).catch((error:BusinessError)=>{Logger.error(TAG,`updateFormfailed:${JSON.stringify(error)}`);});}returnformBindingData.createFormBindingData();}onAcquireFormState(want:Want){returnformInfo.FormState.READY;}}任务1运行结果图8-5操控卡片:左图为播放状态,右图为暂停状态,卡片播控按钮实时切换。图8-6应用主页面:播控页面的播控按钮状态与卡片保持同步。拓展提升:本任务仅实现了单首歌曲播放,且歌曲以资源形式存在于应用中,增大了部署包尺寸。可在此基础上结合数据存储技术及AVPlayer组件设计在线歌单,实现在线播放并保存播放状态。在鸿蒙卡片服务的设计与开发中,我们不仅在构建一个信息展示的窗口,更是在搭建科技与人文之间的桥梁。每一张卡片,都是开发者工匠精神的凝结——既要追求极致的流畅体验,又要在方寸屏幕间传递温度与效率。这背后蕴含的是科技报国的家国情怀和追求卓越的创新精神。作为未来的开发者,我们要将个人成长融入国家科技自立自强的浪潮中,用一行行代码践行"中华有为"的使命担当,让世界看到中国开发的智慧与力量。任务2"音乐播放器"元服务应用设计任务描述:桌面卡片不仅可作为传统应用的入口,也可作为元服务应用入口。本任务实现一个音乐播放的元服务应用,并为应用设计播放卡片。主应用不在内存中时,点击卡片播放按钮能拉起主应用播控页面播放歌曲;主应用存活时,点击卡片的播放按钮能在后台播放歌曲;点击卡片其他位置时,能拉起应用播控页面播放歌曲。以上场景中,播控页面的播控按钮状态必须与卡片上的播控按钮状态同步。8.4元服务开发概述元服务是HarmonyOS专为万物互联时代设计的一种轻量级应用形式,依托HarmonyOS平台的开放能力进行开发,被封装成AppPack格式,由HarmonyOS的应用框架统一管理。其核心特点包括无处不在的接入性、服务的直接可达性以及跨设备的兼容性。HarmonyOS应用与元服务基于同一个鸿蒙系统技术栈开发,同属一个鸿蒙生态。开发者通过业务解耦将应用分解为若干元服务独立开发,按需根据场景组合成复杂应用。传统应用手动下载安装包大小无限制按需使用应用内或应用市场更新功能齐全,开发成本高,周期长载体:跟随设备API:全量API自主运营,人找应用成本高元服务应用免安装包大小有限制(单HAP≤2MB)即用即走自动更新轻量化完整功能,开发成本较低载体:跟随华为账号API:只能使用元服务API集支付、地图、广告等经营履约能力辅助经营;负一屏等系统分入口帮助人找服务元服务六大特征秒开直达,纯净清爽即点即用,实现秒开启动,丝滑流畅;默认隐匿登录直达使用,无弹窗干扰;基于HarmonyOS,有多个分发入口,能够更高效地触达用户。服务相伴,恰合适宜服务面板在负一屏、锁屏界面等常伴跟随,服务履约过程中提供的信息由官方保障;服务通知和状态恰和适宜的提醒,提供更便捷、高效的服务闭环。用完即走,帐号相随用户使用完元服务后,退出无二次弹窗;用户资产跟随帐号,多设备安全同步,用户可随时找回自己的元服务。一体两面,嵌入运行元服务和应用是鸿蒙生态下的两种程序形态,元服务免安装,更为轻量;两者可独立部署,也可以嵌入运行,助力商户私域运营。原生智能,全域搜索元服务基于HarmonyOS,是原生智能应用开发的最佳实践,能实现服务的精准分发与体验的无缝直达。高效开发,生而可信提供元服务标准UX组件集、场景化模板及API集,同时构建元服务生态规则,开发者在规则之上高效开发,实现生而可信。元服务典型使用场景场景一:常用服务卡片添加到桌面将常用的天气、备忘录及热点新闻列表等服务卡片添加到桌面上,解锁手机即可在桌面上查看即时信息,体验快捷服务。同时,通过负一屏发现服务卡片,无须安装即可使用热点服务卡片。场景二:释放手机,跨设备享受服务例如,打车是人们日常生活中经常使用的服务,通常人们在手机上打车,需要一直停留在手机界面才能准确获取司机的状态信息。有了元服务的分布式能力,在手机打车后,将司机状态实时同步到手表,无须查看手机,抬腕即可获取司机状态。8.4.2元服务基础信息每个元服务有独立的图标、名称、描述、快照。基础信息应能够准确反映服务提供方的特征及服务的核心体验,并与其他关联的应用和服务保持同步更新。图标规范元服务图标继承HarmonyOS设计语言体系,内部圆形表示完整独立,外圈装饰线表示可分可合可流转的特点。分辨率必须为216×216px或512×512px的PNG格式,确保图标清晰度及背景透明。图标主体内容应保持在圆形区域内,外围装饰线可根据主体内容或品牌色填充(单色、双色、渐变色)。名称规范元服务名称应精确表示服务内容,简短、易懂、易记忆。名称中应体现品牌或服务提供方以使用户区分。服务名称不超过8个中文字符。正确示例:"华为商城购物车""微博热搜榜""京东直播"。描述规范元服务描述应简要而准确地说明服务的功能,做到用户一眼可知。不允许复用元服务名称;不允许出现广告运营或为应用引流的暗示信息;不允许为空或使用非中文语言。服务描述不超过15个中文字符。正确示例:"快速查看购物清单""即时获取时事新闻"。快照规范快照是与元服务关联的小尺寸服务卡片的预览图(截图),用来让用户直观地理解服务功能和样式,通常展示在负一屏的发现页中。快照分辨率必须为600×600px,对应小尺寸(2×2)服务卡片设计。快照必须提供直角图片且适配深浅模式,提交时不要提前进行圆角剪裁。元服务图标示例图8-7元服务图标:内部圆形表示完整独立,外圈装饰线表示可分可合可流转。图8-8元服务图标主体内容:应用图标→主体内容(圆形区域内)→外围装饰线。图8-9元服务图标样例:渐变、双色、单色(同主体内容)、单色(同主体背景)四种设计风格。8.4.3元服务开发流程图8-10元服务开发流程元服务开发流程详解开发前注册华为开发者帐号,在AGC(AppGalleryConnect)中创建元服务应用,获取AppID。元服务包名命名格式:com.atomicservice.[appid]。获取AppID后通过DevEcoStudio创建元服务工程,搭建开发环境。开发中元服务包含页面、卡片、图标三个部分。DevEcoStudio提供元服务图标生成工具,可通过导入指定尺寸和格式的图片快速生成元服务图标。真机调试:目前不支持模拟器调试元服务卡片。打包通过DevEcoStudio快速打包生成发布版本,此版本可用于开放式测试或提交上架审核。测试在正式发布前,发布开放式测试版本,邀请部分用户提前体验,收集用户反馈,提前发现问题进行改进,保证全网版本质量,提升用户体验。上架当元服务经过全面测试,确保版本没有问题,即可发布正式版本。任务实施元服务应用:实施思路本任务与任务1功能相同,但技术路线差别较大。由于元服务应用不支持全量API,UIAbility没有接收端点(callee),也不支持rpcnamespace,导致为元服务添加的卡片无法使用call事件机制。此外,单个HAP大小限制为2MB,歌曲资源必须以在线形式提供。解决方案:使用公共事件机制在卡片扩展模块进程与主应用进程之间实现进程间通信,以此代替卡片call事件机制。1UIAbility获取新卡片formId添加桌面卡片时,在FormExtensionAbility的onAddForm()中以参数形式携带卡片formId发布自定义公共事件,在UIAbility的订阅回调中获取卡片formId。2主应用在后台时播放音乐在卡片中,用message事件拉起FormExtensionAbility,在onFormEvent()中携带formId发布自定义公共事件,通知UIAbility控制音乐播放。3主应用已销毁时拉起并播放在UIAbility的onCreate()、onDestroy()中用Preferences保存主应用存活状态。FormExtensionAbility的onFormEvent()中读取存活状态,若主应用已销毁,则通过卡片刷新机制通知卡片触发router事件拉起主应用,并在onCreate()中播放音乐。4在线播放歌曲用media.AVPlayer提供的在线播放音乐功能。由于Preferences跨进程同步有时不及时,重写了Preferences功能(源代码参看DbStore.ets)。创建元服务应用:AGC操作步骤新建AppID创建AppID并选择元服务类型选择项目选择或新建所属项目注册登录注册华为帐号并登录AGC确认接入开放能力接入并获取包名填写信息输入应用名称与分类Step1-2:注册与新建打开AGC网址(/consumer/cn/service/josp/agc),注册华为帐号并完成身份认证。登录后,在左侧导航栏选择"证书、AppID和Profile→AppID",点击右上角"新建"按钮。Step3:设置基础信息应用类型选择"元服务";应用名称填写"音乐播放器";应用分类选择"应用",完成后点击"下一步"。Step4:选择或创建项目在"应用所属项目"栏填写项目名称(如"我的鸿蒙应用"),点击"确认"按钮。Step5:完成创建进入"开放能力接入"页面,本任务无须开放能力接入,点击"确认"完成创建。返回AppID页面可看到已创建的应用,包名为com.atomicservice.6917561790143570297,其中6917561790143570297即为AppID。AGC操作截图图8-11AppID页面图8-14选择开放能力接入图8-15AppID页面:包名com.atomicservice.6917561790143570297创建元服务工程MusicAtomicService创建步骤启动DevEcoStudio,选择"File→New→CreateProject",选择"AtomicService"元服务开发,选择"EmptyAbility"模板,点击"Next"。点击"SignIn"按钮登录华为开发者帐号(也可选择访客模式体验,访客模式无须登录华为帐号)。在弹出的网页界面中点击允许,完成访问帐号授权。进入工程配置界面,填写"Projectname"(如MusicAtomicService),其他参数保持默认设置。点击"Finish",等待工程创建完成,DevEcoStudio会自动生成示例代码和相关资源。注意:元服务的"BundleName"采用固定前缀和AppID组合方式(com.atomicservice.[appid])命名,为自动生成,开发者无法手动修改。访客模式如需在真机上运行,需在AppScope/app.json5中补充真实存在的包名。图8-16登录华为开发者账号图8-17元服务应用信息元服务工程配置与目录结构图8-18元服务工程配置图8-19元服务工程目录结构:与传统应用目录结构相同。至此,元服务工程创建完毕。创建元服务图标如果元服务需要发布,就必须准备独立的元服务图标。先准备1个1024×1024px的.png/.jpeg/.jpg格式图片(背景不透明)作为材料。操作步骤在工程中选中entry模块右击,选择"New→ImageAsset",进入图标配置页面。在"Path"中选择本地图片路径。在预览界面配置图标颜色(Color)、名称(Name)、保存路径(ResDirectory/Saveto)。点击"Finish",在src/main/resources/base/media路径下生成元服务图标,可在module.json5的icon字段中配置。生成尺寸说明:ResDirectory:生成512×512px尺寸图标,保存在工程中Saveto:生成216×216px尺寸图标,保存在本地,用于AGC上架图8-20元服务图标配置图8-21元服务图标元服务代码:WidgetCard.ets(文件8-4)卡片页面。与任务1的主要区别:使用message事件代替call事件,并通过@Watch装饰的pullAbility状态量监听卡片刷新触发router事件拉起应用。@Entry@ComponentstructWidgetCard{readonlyABILITY_NAME:string='EntryAbility';@LocalStorageProp('isPlay')isPlay:boolean=false;@LocalStorageProp('photo')photo:ResourceStr=$rawfile('bamboo.png');@LocalStorageProp('title')title:string='';@LocalStorageProp('singer')singer:string='';@LocalStorageProp('formId')formId:string='12400633174999288';//触发更新,用于拉起EntryAbility(当主应用已销毁时)@LocalStorageProp('pullAbility')@Watch('pullAbility')trigger:number=0;pullAbility(){postCardAction(this,{action:'router',abilityName:this.ABILITY_NAME,params:{formId:this.formId,status:'PLAY'}});}build(){Column(){//歌曲封面、标题、歌手信息...//播放/暂停按钮:触发message事件Image(this.isPlay?$r('app.media.ic_public_pause'):$r('app.media.ic_public_play')).width(32).onClick(()=>{postCardAction(this,{action:'message',abilityName:this.ABILITY_NAME,params:{status:this.isPlay?'PLAY':'PAUSE',formId:this.formId}});})}.backgroundColor('#6C5748').height('100%').onClick(()=>{//点击非按钮区域:触发router事件postCardAction(this,{action:'router',abilityName:this.ABILITY_NAME,params:{formId:this.formId}});})}}元服务代码:EntryAbility.ets(文件8-5)UIAbility组件,程序入口类。核心变化:用公共事件机制(EventHub)代替call事件机制,订阅来自FormExtensionAbility的自定义公共事件。exportdefaultclassEntryAbilityextendsUIAbility{//公共事件订阅回调:接收EntryFormAbility发布的事件onEventCallBack(err,data:commonEventManager.CommonEventData){letparams=JSON.parse(data.dataasstring);setPlayStateCallBack(params.formId);if(params.status==='PAUSE')MusicService.getInstance().play();elseif(params.status==='PLAY')MusicService.getInstance().pause();}onCreate(want:Want,launchParam):void{//订阅公共事件EventHub.on("PLAY_MUSIC",this.onEventCallBack);//保存UIAbility存活状态DbStore.getInstance(this.context.getApplicationContext())?.put(Constants.ENTRYABILITY,Constants.ENTRYABILITY_EXIST);MusicService.getInstance().initAudioPlayer(this.createSongData());setPlayStateCallBack('');this.onNewWant(want,launchParam);}//UIAbility已在后台运行时,收到router事件触发onNewWant()onNewWant(want:Want,launchParam):void{if(want?.parameters?.params){constparams=JSON.parse(want.parameters.paramsasstring);if(params.formId!==''&¶ms.status==='PLAY'){setPlayStateCallBack(params.formId);setTimeout(()=>{MusicService.getInstance().play();},1000);}}}onDestroy():void{//保存UIAbility存活状态DbStore.getInstance(this.context.getApplicationContext())?.put(Constants.ENTRYABILITY,Constants.ENTRYABILITY_NOT_EXIST);EventHub.off("PLAY_MUSIC");MusicService.getInstance().stop();MusicService.getInstance().release();}}元服务代码:EntryFormAbility.ets(文件8-6)卡片生命周期回调接口组件。该实体仅存活5秒。核心逻辑:onAddForm()中初始化卡片数据并发布公共事件传递formId;onFormEvent()中判断主应用存活状态,决定是拉起应用还是发布公共事件通知播放。exportdefaultclassEntryFormAbilityextendsFormExtensionAbility{onAddForm(want:Want){//从DbStore读取当前播放状态、歌曲信息conststate=DbStore.getInstance(...)?.get(Constants.IS_PLAY,false);//获取formId并初始化卡片数据letformId=want.parameters[formInfo.FormParam.IDENTITY_KEY].toString();letupdateData={'photo':$rawfile(photo),'title':title,'singer':singer,'isPlay':state,'formId':formId};formProvider.updateForm(formId,formBindingData.createFormBindingData(updateData)).then(()=>{//将新添加的卡片formId发送给EntryAbilityEventHub.emit('PLAY_MUSIC',JSON.stringify({'formId':formId}));});returnformBindingData.createFormBindingData('');}//通过刷新卡片,在卡片中用router事件拉起应用privatepullEntryAbility(formId:string){constupdateData={'pullAbility':(newDate()).getTime()};formProvider.updateForm(formId,formBindingData.createFormBindingData(updateData));}onFormEvent(formId:string,message:string):void{constentryabilityExist=DbStore.getInstance(...).get(Constants.ENTRYABILITY,'');//
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年甘肃省甘南州玛曲县招聘第四次全国农业普查工作人员笔试备考题库及答案详解
- 2026中国热带农业科学院椰子研究所第二批招聘工作人员6人笔试备考题库及答案详解
- 2026年永修县面向社会公开招聘社区专职网格员【9人】笔试参考题库及答案详解
- 2026浙江金华市中心医院神经外科国家临床重点专科招聘科研助理人员1人笔试备考题库及答案详解
- 2026年兰州大学基础医学院助理教授招聘笔试模拟试题及答案详解
- 2026泉州南安市诗山中学秋季编外合同教师招聘若干人笔试备考试题及答案详解
- 2026中国热带农业科学院香料饮料研究所第二批招聘10人笔试模拟试题及答案详解
- 2026湖北武汉大学人民医院医师招聘2人笔试参考题库及答案详解
- 2026河南安阳正一中学体育教师招聘1人笔试参考题库及答案详解
- 2026云南昆明铁道职业技术学院招聘3人笔试备考题库及答案详解
- 四川卫健委课题申报书
- MES系统开发合同
- 2025年宝山区社区工作者招聘考试真题(附含答案)
- 高速公路改扩建交通导改方案
- 2025年全国初级导游人员资格考试(政策与法律法规、导游业务)历年参考题库含答案详解(5卷)
- 【MOOC答案】《人力资源管理》(南京邮电大学)章节作业慕课答案
- 如何书包班会课件
- 服装公司资产管理制度
- 冬病夏治及中医夏季养生课件
- 园区污水接纳协议书
- 《现代农业技术与装备》课件
评论
0/150
提交评论