卡片自定义刷新时间——setFormNextRefreshTime 让卡片在你想要的时间点醒来

卡片自定义刷新时间——setFormNextRefreshTime 让卡片在你想要的时间点醒来 文章目录setFormNextRefreshTime 是什么项目结构基于 StageServiceWidgetCards/nextrefreshtime卡片 UI点击触发自定义刷新时间FormAbility收到消息后设置下次刷新时间setFormNextRefreshTime 的参数说明三种刷新方式综合使用时序图常见坑写在最后form_config.json里配的updateDuration是固定间隔刷新最短 30 分钟一次。但实际需求经常不是这样的——用户点了按钮我想 5 分钟后刷新一次某个特定操作发生后我想在 1 小时后刷新。这就需要用到formProvider.setFormNextRefreshTime在运行时动态设置下次刷新的时间。setFormNextRefreshTime 是什么大白话版updateDuration是定闹钟每 30 分钟响一次setFormNextRefreshTime是临时闹钟你可以随时设置X 分钟后叫我。调用setFormNextRefreshTime(formId, minutes)后系统会在minutes分钟后调用你的onUpdateForm(formId)就这一次不会重复。项目结构基于 StageServiceWidgetCards/nextrefreshtimeStageServiceWidgetCards/ └── entry/src/main/ets/ ├── nextrefreshtime/ │ ├── pages/ │ │ └── NextRefreshTimeCard.ets ← 卡片 UI │ └── widgetabilify/ │ └── NextRefreshTimeFormAbility.ets ← 卡片 Ability └── ...卡片 UI点击触发自定义刷新时间// entry/src/main/ets/nextrefreshtime/pages/NextRefreshTimeCard.etsletstorageNextRefreshTimenewLocalStorage();Entry(storageNextRefreshTime)Componentstruct NextRefreshTimeCard{LocalStorageProp(title)title:ResourceStr$r(app.string.default_title);LocalStorageProp(detail)detail:ResourceStr$r(app.string.DescriptionDefault);build(){Column(){Column(){Text(this.title).fontColor(#FFFFFF).opacity(0.9).fontSize(14).textOverflow({overflow:TextOverflow.Ellipsis}).maxLines(1).margin({top:8%,left:10%})Text(this.detail).fontColor(#FFFFFF).opacity(0.6).fontSize(12).textOverflow({overflow:TextOverflow.Ellipsis}).maxLines(2).margin({top:5%,left:10%})}.width(100%).height(50%).alignItems(HorizontalAlign.Start)Row(){Button(){Text($r(app.string.update)).fontColor(#45A6F4).fontSize(12)}.width(120).height(32).margin({top:30%,bottom:10%}).backgroundColor(#FFFFFF).borderRadius(16).onClick((){// 点击按钮让 FormAbility 设置 5 分钟后刷新postCardAction(this,{action:message,params:{msgTest:messageEvent// FormAbility 收到后设置刷新时间}});})}.width(100%).height(40%).justifyContent(FlexAlign.Center)}.width(100%).height(100%).alignItems(HorizontalAlign.Start).backgroundImage($r(app.media.CardEvent)).backgroundImageSize(ImageSize.Cover)}}FormAbility收到消息后设置下次刷新时间// entry/src/main/ets/nextrefreshtime/widgetabilify/NextRefreshTimeFormAbility.etsimport{formBindingData,FormExtensionAbility,formProvider}fromkit.FormKit;import{Want}fromkit.AbilityKit;import{BusinessError}fromkit.BasicServicesKit;import{hilog}fromkit.PerformanceAnalysisKit;constTAGNextRefreshTimeFormAbility;constDOMAIN_NUMBER0xFF00;// 5分钟后刷新setFormNextRefreshTime 的单位是分钟最小值是 5constNEXT_REFRESH_MINUTES5;exportdefaultclassNextRefreshTimeFormAbilityextendsFormExtensionAbility{onAddForm(want:Want):formBindingData.FormBindingData{constformData:Recordstring,string{};returnformBindingData.createFormBindingData(formData);}onFormEvent(formId:string,message:string):void{hilog.info(DOMAIN_NUMBER,TAG,onFormEvent:${message});constmsg:Recordstring,stringJSON.parse(message);if(msg.msgTestmessageEvent){// 核心设置 5 分钟后触发 onUpdateFormformProvider.setFormNextRefreshTime(formId,NEXT_REFRESH_MINUTES).then((){hilog.info(DOMAIN_NUMBER,TAG,已设置${NEXT_REFRESH_MINUTES}分钟后刷新);// 可以先给卡片显示一个等待刷新的提示constwaitData:Recordstring,string{title:等待刷新中...,detail:将在${NEXT_REFRESH_MINUTES}分钟后更新};returnformProvider.updateForm(formId,formBindingData.createFormBindingData(waitData));}).catch((error:BusinessError){hilog.error(DOMAIN_NUMBER,TAG,设置刷新时间失败:${error.code}${error.message});});}}onUpdateForm(formId:string):void{// 到了设定的时间后系统会调用这里hilog.info(DOMAIN_NUMBER,TAG,onUpdateForm:${formId}- 自定义时间到了);classFormDataClass{title:stringTitle Update.;detail:stringDescription update success.;}constformDatanewFormDataClass();constformInfoformBindingData.createFormBindingData(formData);formProvider.updateForm(formId,formInfo).then((){hilog.info(DOMAIN_NUMBER,TAG,自定义刷新完成);}).catch((error:BusinessError){hilog.error(DOMAIN_NUMBER,TAG,刷新失败:${JSON.stringify(error)});});}}setFormNextRefreshTime 的参数说明formProvider.setFormNextRefreshTime(formId:string,// 要刷新的卡片 IDminute:number// 多少分钟后刷新最小值是 5不能小于5分钟):Promisevoid几个重要限制最小值是 5 分钟系统为了省电不允许小于 5 分钟的自定义刷新只触发一次不是循环刷新时间到了触发一次onUpdateForm就完了每 24 小时最多 50 次应用的卡片刷新总次数有上限超出不生效三种刷新方式综合使用实际项目里这三种方式经常组合使用。下面是一个场景需求天气卡片正常每小时刷新用户手动点刷新后 5 分钟内快速再刷一次。exportdefaultclassWeatherFormAbilityextendsFormExtensionAbility{onAddForm(want:Want):formBindingData.FormBindingData{// 卡片创建时立即获取一次天气数据constformIdJSON.stringify(want.parameters?.[ohos.extra.param.key.form_identity]??);this.fetchWeatherAndUpdate(formId);returnformBindingData.createFormBindingData({});}onUpdateForm(formId:string):void{// 定时刷新每小时或自定义刷新5分钟后都走这里this.fetchWeatherAndUpdate(formId);}onFormEvent(formId:string,message:string):void{constmsg:Recordstring,stringJSON.parse(message);if(msg.actionmanualRefresh){// 用户手动点了刷新立即更新一次并设置 5 分钟后再更新this.fetchWeatherAndUpdate(formId);// 设置 5 分钟后自动再刷一次为了确认数据稳定formProvider.setFormNextRefreshTime(formId,5).catch((error:BusinessError)console.error(error.message));}}privateasyncfetchWeatherAndUpdate(formId:string):Promisevoid{// 模拟获取天气数据constweatherData:Recordstring,string{title:深圳 今天 25°C,detail:晴转多云南风3-4级};awaitformProvider.updateForm(formId,formBindingData.createFormBindingData(weatherData));}}时序图常见坑坑1最小刷新间隔是 5 分钟设置小于 5 的值setFormNextRefreshTime会抛出错误code: 16500062别想着设 1 分钟。// 会报错时间太短formProvider.setFormNextRefreshTime(formId,1);// 最短设 5 分钟formProvider.setFormNextRefreshTime(formId,5);坑2每天 50 次上限单个应用的所有卡片加起来每 24 小时的setFormNextRefreshTime调用不能超过 50 次。超出后调用会悄悄失效不报错也不刷新。坑3setFormNextRefreshTime和updateDuration的关系两者互不影响可以同时使用。updateDuration是背景定时器setFormNextRefreshTime是一次性临时闹钟互相独立触发。坑4进程被杀后定时任务还在吗在的。系统维护了定时任务队列FormAbility 进程被杀也不影响。到了设定时间系统会重新拉起 FormAbility 进程并调用onUpdateForm。写在最后setFormNextRefreshTime解决了一个很实际的问题用户操作触发了某件事你希望在一段时间后反映到卡片上。不用一直保持进程活跃轮询系统帮你维护定时器到点叫你起来干活干完再去睡。对省电友好对用户也友好。