共计 17751 个字符,预计需要花费 45 分钟才能阅读完成。
「鸿蒙学习笔记」Stage 模型 – 服务卡片
服务卡片(以下简称“卡片”)是一种界面展现模式,能够将利用的重要信息或操作前置到卡片,以达到服务中转、缩小体验层级的目标。卡片罕用于嵌入到其余利用(以后卡片应用方只支持系统利用,如桌面)中作为其界面显示的一部分,并反对拉起页面、发送音讯等根底的交互性能。
服务卡片架构:
卡片的基本概念:
- 卡片应用方:如上图中的桌面,显示卡片内容的宿主利用,管制卡片在宿主中展现的地位。
-
- 利用图标:利用入口图标,点击后可拉起利用过程,图标内容不反对交互。
-
- 卡片:具备不同规格大小的界面展现,卡片的内容能够进行交互,如实现按钮进行界面的刷新、利用的跳转等。
- 卡片提供方:蕴含卡片的利用,提供卡片的显示内容、控件布局以及控件点击解决逻辑。
-
- FormExtensionAbility:卡片业务逻辑模块,提供卡片创立、销毁、刷新等生命周期回调。
-
- 卡片页面:卡片 UI 模块,蕴含页面控件、布局、事件等显示和交互信息。
卡片的常见应用步骤如下:
卡片运行机制
ArkTS 卡片实现原理:
- 卡片应用方:显示卡片内容的宿主利用,管制卡片在宿主中展现的地位,以后仅零碎利用能够作为卡片应用方。
- 卡片提供方:提供卡片显示内容的利用,管制卡片的显示内容、控件布局以及控件点击事件。
- 卡片治理服务:用于管理系统中所增加卡片的常驻代理服务,提供 formProvider 接口能力,同时提供卡片对象的治理与应用以及卡片周期性刷新等能力。
- 卡片渲染服务:用于治理卡片渲染实例,渲染实例与卡片应用方上的卡片组件一一绑定。卡片渲染服务运行卡片页面代码 widgets.abc 进行渲染,并将渲染后的数据发送至卡片应用方对应的卡片组件。
ArkTS 卡片渲染服务运行原理:
ArkTS 卡片反对在卡片中运行逻辑代码,为确保 ArkTS 卡片产生问题后不影响卡片应用方利用的应用,ArkTS 卡片新增了卡片渲染服务用于运行卡片页面代码 widgets.abc,卡片渲染服务由卡片治理服务治理。
卡片应用方的每个卡片组件都对应了卡片渲染服务里的一个渲染实例,同一利用提供方的渲染实例运行在同一个虚拟机运行环境中,不同利用提供方的渲染实例运行在不同的虚拟机运行环境中,通过虚拟机运行环境隔离不同利用提供方卡片之间的资源与状态。
开发过程中须要留神的是 globalThis 对象的应用,雷同利用提供方的卡片 globalThis 对象是同一个,不同利用提供方的卡片 globalThis 对象是不同的。
ArkTS 卡片的劣势:
- 新增了动效的能力:ArkTS 卡片凋谢了属性动画和显式动画的能力,使卡片的交互更加敌对。
- 新增了自定义绘制的能力:ArkTS 卡片凋谢了 Canvas 画布组件,卡片能够应用自定义绘制的能力构建更多样的显示和交互成果。
- 容许卡片中运行逻辑代码:凋谢逻辑代码运行后很多业务逻辑能够在卡片外部自闭环,拓宽了卡片的业务实用场景。
ArkTS 卡片的束缚:
- 不反对加载 so。
- 不反对应用 native 语言开发。
- 仅反对申明式范式的局部组件、事件、动效、数据管理、状态治理和 API 能力。
- 卡片的事件处理和应用方的事件处理是独立的,倡议在应用方反对左右滑动的场景下卡片内容不要应用左右滑动性能的组件,以防手势抵触影响交互体验。
- 暂不反对导入模块。
- 暂不反对极速预览。
- 暂不反对断点调试能力。
- 暂不反对 Hot Reload 热重载。
卡片相干模块
- FormExtensionAbility:卡片扩大模块,提供卡片创立、销毁、刷新等生命周期回调。
- FormExtensionContext:FormExtensionAbility 的上下文环境,提供 FormExtensionAbility 具备的接口和能力。
- formProvider:提供卡片提供方相干的接口能力,可通过该模块提供接口实现更新卡片、设置卡片更新工夫、获取卡片信息、申请公布卡片等。
- formInfo:提供了卡片信息和状态等相干类型和枚举。
- formBindingData:提供卡片数据绑定的能力,包含 FormBindingData 对象的创立、相干信息的形容。
- 页面布局(Card.ets):提供申明式范式的 UI 接口能力。
-
- ArkTS 卡片特有能力:postCardAction 用于卡片外部和提供方利用间的交互,仅在卡片中能够调用。
-
- ArkTS 卡片能力列表:列举了能在 ArkTS 卡片中应用的 API、组件、事件、属性和生命周期调度。
- 卡片配置:蕴含 FormExtensionAbility 的配置和卡片的配置
-
- 在 module.json5 配置文件中的 extensionAbilities 标签下,配置 FormExtensionAbility 相干信息。
-
- 在 resources/base/profile/ 目录下的 form_config.json 配置文件中,配置卡片(WidgetCard.ets)相干信息。
创立卡片
创立卡片:
ArkTS 卡片创立实现后,工程中会新增如下卡片相干文件:卡片生命周期管理文件(EntryFormAbility.ts)、卡片页面文件(WidgetCard.ets)和卡片配置文件(form_config.json)。
配置卡片
卡片相干的配置文件次要蕴含 FormExtensionAbility 的配置和卡片的配置两局部:
-
卡片须要在 module.json5 配置文件中的 extensionAbilities 标签下,配置 FormExtensionAbility 相干信息。FormExtensionAbility 须要填写 metadata 元信息标签,其中键名称为固定字符串“ohos.extension.form”,资源为卡片的具体配置信息的索引。
{ "module": { ... "extensionAbilities": [ { "name": "EntryFormAbility", "srcEntrance": "./ets/entryformability/EntryFormAbility.ts", "label": "$string:EntryFormAbility_label", "description": "$string:EntryFormAbility_desc", "type": "form", "metadata": [ { "name": "ohos.extension.form", "resource": "$profile:form_config" } ] } ] } }
-
卡片的具体配置信息。在上述 FormExtensionAbility 的元信息(“metadata”配置项)中,能够指定卡片具体配置信息的资源索引。例如当 resource 指定为 $profile:form_config 时,会应用开发视图的 resources/base/profile/ 目录下的 form_config.json 作为卡片 profile 配置文件。
{ "forms": [ { "name": "widget", "description": "This is a service widget.", "src": "./ets/widget/pages/WidgetCard.ets", "uiSyntax": "arkts", "window": { "designWidth": 720, "autoDesignWidth": true }, "colorMode": "auto", "isDefault": true, "updateEnabled": true, "scheduledUpdateTime": "10:30", "updateDuration": 1, "defaultDimension": "2*2", "supportDimensions": ["2*2"] } ] }
卡片生命周期治理
创立 ArkTS 卡片,需实现 FormExtensionAbility 生命周期接口。
-
在 EntryFormAbility.ts 中,导入相干模块。
import formInfo from '@ohos.app.form.formInfo'; import formBindingData from '@ohos.app.form.formBindingData'; import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility'; import formProvider from '@ohos.app.form.formProvider';
-
在 EntryFormAbility.ts 中,实现 FormExtensionAbility 生命周期接口,其中在 onAddForm 的入参 want 中能够通过 FormParam 取出卡片的相干信息。
import formInfo from '@ohos.app.form.formInfo'; import formBindingData from '@ohos.app.form.formBindingData'; import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility'; import formProvider from '@ohos.app.form.formProvider'; export default class EntryFormAbility extends FormExtensionAbility {onAddForm(want) {console.info('[EntryFormAbility] onAddForm'); // 在入参 want 中能够取出卡片的惟一标识:formId let formId: string = want.parameters[formInfo.FormParam.IDENTITY_KEY]; // 应用方创立卡片时触发,提供方须要返回卡片数据绑定类 let obj = { 'title': 'titleOnAddForm', 'detail': 'detailOnAddForm' }; let formData = formBindingData.createFormBindingData(obj); return formData; } onCastToNormalForm(formId) { // Called when the form provider is notified that a temporary form is successfully // converted to a normal form. // 应用方将长期卡片转换为常态卡片触发,提供方须要做相应的解决 console.info(`[EntryFormAbility] onCastToNormalForm, formId: ${formId}`); } onUpdateForm(formId) { // 若卡片反对定时更新 / 定点更新 / 卡片应用方被动申请更新性能,则提供方须要重写该办法以反对数据更新 console.info('[EntryFormAbility] onUpdateForm'); let obj = { 'title': 'titleOnUpdateForm', 'detail': 'detailOnUpdateForm' }; let formData = formBindingData.createFormBindingData(obj); formProvider.updateForm(formId, formData).catch((err) => {if (err) { // 异样分支打印 console.error(`[EntryFormAbility] Failed to updateForm. Code: ${err.code}, message: ${err.message}`); return; } }); } onChangeFormVisibility(newStatus) { // Called when the form provider receives form events from the system. // 须要配置 formVisibleNotify 为 true,且为零碎利用才会回调 console.info('[EntryFormAbility] onChangeFormVisibility'); } onFormEvent(formId, message) { // Called when a specified message event defined by the form provider is triggered. // 若卡片反对触发事件,则须要重写该办法并实现对事件的触发 console.info('[EntryFormAbility] onFormEvent'); } onRemoveForm(formId) { // Called to notify the form provider that a specified form has been destroyed. // 当对应的卡片删除时触发的回调,入参是被删除的卡片 ID console.info('[EntryFormAbility] onRemoveForm'); } onConfigurationUpdate(config) { // 当系统配置信息置更新时触发的回调 console.info('[EntryFormAbility] configurationUpdate:' + JSON.stringify(config)); } onAcquireFormState(want) {// Called to return a {@link FormState} object. // 卡片提供方接管查问卡片状态告诉接口,默认返回卡片初始状态。return formInfo.FormState.READY; } }
开发卡片事件
ArkTS 卡片中提供了 postCardAction()接口用于卡片外部和提供方利用间的交互,以后反对 router、message 和 call 三种类型的事件,仅在卡片中能够调用。
应用 router 事件跳转到指定 UIAbility
在卡片中应用 postCardAction 接口的 router 能力,可能疾速拉起卡片提供方利用的指定 UIAbility,因而 UIAbility 较多的利用往往会通过卡片提供不同的跳转按钮,实现一键中转的成果。例如相机卡片,卡片上提供拍照、录像等按钮,点击不同按钮将拉起相机利用的不同 UIAbility,从而晋升用户的体验。
通常应用按钮控件来实现页面拉起,示例代码如下:
-
在卡片页面中布局两个按钮,点击其中一个按钮时调用 postCardAction 向指定 UIAbility 发送 router 事件,并在事件内定义须要传递的内容。
@Entry @Component struct WidgetCard {build() {Column() {Button('性能 A') .margin('20%') .onClick(() => {console.info('Jump to EntryAbility funA'); postCardAction(this, { 'action': 'router', 'abilityName': 'EntryAbility', // 只能跳转到以后利用下的 UIAbility 'params': {'targetPage': 'funA' // 在 EntryAbility 中解决这个信息} }); }) Button('性能 B') .margin('20%') .onClick(() => {console.info('Jump to EntryAbility funB'); postCardAction(this, { 'action': 'router', 'abilityName': 'EntryAbility', // 只能跳转到以后利用下的 UIAbility 'params': {'targetPage': 'funB' // 在 EntryAbility 中解决这个信息} }); }) } .width('100%') .height('100%') } }
-
在 UIAbility 中接管 router 事件并获取参数,依据传递的 message 不同,抉择拉起不同的页面。
import UIAbility from '@ohos.app.ability.UIAbility'; import window from '@ohos.window'; let selectPage = ""; let currentWindowStage = null; export default class CameraAbility extends UIAbility { // 如果 UIAbility 第一次启动,在收到 Router 事件后会触发 onCreate 生命周期回调 onCreate(want, launchParam) { // 获取 router 事件中传递的 targetPage 参数 console.info("onCreate want:" + JSON.stringify(want)); if (want.parameters.params !== undefined) {let params = JSON.parse(want.parameters.params); console.info("onCreate router targetPage:" + params.targetPage); selectPage = params.targetPage; } } // 如果 UIAbility 已在后盾运行,在收到 Router 事件后会触发 onNewWant 生命周期回调 onNewWant(want, launchParam) {console.info("onNewWant want:" + JSON.stringify(want)); if (want.parameters.params !== undefined) {let params = JSON.parse(want.parameters.params); console.info("onNewWant router targetPage:" + params.targetPage); selectPage = params.targetPage; } if (currentWindowStage != null) {this.onWindowStageCreate(currentWindowStage); } } onWindowStageCreate(windowStage: window.WindowStage) { let targetPage; // 依据传递的 targetPage 不同,抉择拉起不同的页面 switch (selectPage) { case 'funA': targetPage = 'pages/FunA'; break; case 'funB': targetPage = 'pages/FunB'; break; default: targetPage = 'pages/Index'; } if (currentWindowStage === null) {currentWindowStage = windowStage;} windowStage.loadContent(targetPage, (err, data) => {if (err && err.code) {console.info('Failed to load the content. Cause: %{public}s', JSON.stringify(err)); return; } }); } };
应用 call 事件拉起指定 UIAbility 到后盾
许多利用心愿借助卡片的能力,实现和利用在前台时雷同的性能。例如音乐卡片,卡片上提供播放、暂停等按钮,点击不同按钮将触发音乐利用的不同性能,进而进步用户的体验。在卡片中应用 postCardAction 接口的 call 能力,可能将卡片提供方利用的指定 UIAbility 拉到后盾。同时,call 能力提供了调用利用指定办法、传递数据的性能,使利用在后盾运行时能够通过卡片上的按钮执行不同的性能。
通常应用按钮控件来触发 call 事件,示例代码如下:
-
在卡片页面中布局两个按钮,点击其中一个按钮时调用 postCardAction 向指定 UIAbility 发送 call 事件,并在事件内定义须要调用的办法和传递的数据。须要留神的是,method 参数为必选参数,且类型须要为 string 类型,用于触发 UIAbility 中对应的办法。
@Entry @Component struct WidgetCard {build() {Column() {Button('性能 A') .margin('20%') .onClick(() => {console.info('call EntryAbility funA'); postCardAction(this, { 'action': 'call', 'abilityName': 'EntryAbility', // 只能跳转到以后利用下的 UIAbility 'params': {'method': 'funA' // 在 EntryAbility 中调用的办法名} }); }) Button('性能 B') .margin('20%') .onClick(() => {console.info('call EntryAbility funB'); postCardAction(this, { 'action': 'call', 'abilityName': 'EntryAbility', // 只能跳转到以后利用下的 UIAbility 'params': { 'method': 'funB', // 在 EntryAbility 中调用的办法名 'num': 1 // 须要传递的其余参数 } }); }) } .width('100%') .height('100%') } }
-
在 UIAbility 中接管 call 事件并获取参数,依据传递的 method 不同,执行不同的办法。其余数据能够通过 readString 的形式获取。须要留神的是,UIAbility 须要 onCreate 生命周期中监听所需的办法。
import UIAbility from '@ohos.app.ability.UIAbility'; function FunACall(data) { // 获取 call 事件中传递的所有参数 console.log('FunACall param:' + JSON.stringify(data.readString())); return null; } function FunBCall(data) {console.log('FunACall param:' + JSON.stringify(data.readString())); return null; } export default class CameraAbility extends UIAbility { // 如果 UIAbility 第一次启动,在收到 call 事件后会触发 onCreate 生命周期回调 onCreate(want, launchParam) { try { // 监听 call 事件所需的办法 this.callee.on('funA', FunACall); this.callee.on('funB', FunBCall); } catch (error) {console.log('register failed with error. Cause:' + JSON.stringify(error)); } } // 过程退出时,解除监听 onDestroy() { try {this.callee.off('funA'); this.callee.off('funB'); } catch (error) {console.log('register failed with error. Cause:' + JSON.stringify(error)); } } };
通过 message 事件刷新卡片内容
在卡片页面中能够通过 postCardAction 接口触发 message 事件拉起 FormExtensionAbility,而后由 FormExtensionAbility 刷新卡片内容,上面是这种刷新形式的简略示例。
-
在卡片页面通过注册 Button 的 onClick 点击事件回调,并在回调中调用 postCardAction 接口触发事件至 FormExtensionAbility
let storage = new LocalStorage(); @Entry(storage) @Component struct WidgetCard {@LocalStorageProp('title') title: string = 'init'; @LocalStorageProp('detail') detail: string = 'init'; build() {Column() {Button('刷新') .onClick(() => { postCardAction(this, { 'action': 'message', 'params': {'msgTest': 'messageEvent'} }); }) Text(`${this.title}`) Text(`${this.detail}`) } .width('100%') .height('100%') } }
-
在 FormExtensionAbility 的 onFormEvent 生命周期中调用 updateForm 接口刷新卡片
import formBindingData from '@ohos.app.form.formBindingData'; import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility'; import formProvider from '@ohos.app.form.formProvider'; export default class EntryFormAbility extends FormExtensionAbility {onFormEvent(formId, message) { // Called when a specified message event defined by the form provider is triggered. console.info(`FormAbility onEvent, formId = ${formId}, message: ${JSON.stringify(message)}`); let formData = { 'title': 'Title Update Success.', // 和卡片布局中对应 'detail': 'Detail Update Success.', // 和卡片布局中对应 }; let formInfo = formBindingData.createFormBindingData(formData) formProvider.updateForm(formId, formInfo).then((data) => {console.info('FormAbility updateForm success.' + JSON.stringify(data)); }).catch((error) => {console.error('FormAbility updateForm failed:' + JSON.stringify(error)); }) } ... }
成果如图:
通过 router 或 call 事件刷新卡片内容
在卡片页面中能够通过 postCardAction 接口触发 router 或 call 事件拉起 UIAbility,而后由 UIAbility 刷新卡片内容,上面是这种刷新形式的简略示例。
通过 router 事件刷新卡片内容
-
在卡片页面通过注册 Button 的 onClick 点击事件回调,并在回调中调用 postCardAction 接口触发 router 事件至 FormExtensionAbility。
let storage = new LocalStorage(); @Entry(storage) @Component struct WidgetCard {@LocalStorageProp('detail') detail: string = 'init'; build() {Column() {Button('跳转') .margin('20%') .onClick(() => {console.info('postCardAction to EntryAbility'); postCardAction(this, { 'action': 'router', 'abilityName': 'EntryAbility', // 只能跳转到以后利用下的 UIAbility 'params': {'detail': 'RouterFromCard'} }); }) Text(`${this.detail}`).margin('20%') } .width('100%') .height('100%') } }
-
在 UIAbility 的 onCreate()或者 onNewWant()生命周期中能够通过入参 want 获取卡片的 formID 和传递过去的参数信息,而后调用 updateForm 接口刷新卡片。
import UIAbility from '@ohos.app.ability.UIAbility'; import formBindingData from '@ohos.app.form.formBindingData'; import formProvider from '@ohos.app.form.formProvider'; import formInfo from '@ohos.app.form.formInfo'; export default class EntryAbility extends UIAbility { // 如果 UIAbility 第一次启动,在收到 Router 事件后会触发 onCreate 生命周期回调 onCreate(want, launchParam) {console.info('Want:' + JSON.stringify(want)); if (want.parameters[formInfo.FormParam.IDENTITY_KEY] !== undefined) {let curFormId = want.parameters[formInfo.FormParam.IDENTITY_KEY]; let message = JSON.parse(want.parameters.params).detail; console.info(`UpdateForm formId: ${curFormId}, message: ${message}`); let formData = {"detail": message + ': onCreate UIAbility.', // 和卡片布局中对应}; let formMsg = formBindingData.createFormBindingData(formData) formProvider.updateForm(curFormId, formMsg).then((data) => {console.info('updateForm success.' + JSON.stringify(data)); }).catch((error) => {console.error('updateForm failed:' + JSON.stringify(error)); }) } } // 如果 UIAbility 已在后盾运行,在收到 Router 事件后会触发 onNewWant 生命周期回调 onNewWant(want, launchParam) {console.info('onNewWant Want:' + JSON.stringify(want)); if (want.parameters[formInfo.FormParam.IDENTITY_KEY] !== undefined) {let curFormId = want.parameters[formInfo.FormParam.IDENTITY_KEY]; let message = JSON.parse(want.parameters.params).detail; console.info(`UpdateForm formId: ${curFormId}, message: ${message}`); let formData = {"detail": message + ': onNewWant UIAbility.', // 和卡片布局中对应}; let formMsg = formBindingData.createFormBindingData(formData) formProvider.updateForm(curFormId, formMsg).then((data) => {console.info('updateForm success.' + JSON.stringify(data)); }).catch((error) => {console.error('updateForm failed:' + JSON.stringify(error)); }) } } ... }
通过 call 事件刷新卡片内容
-
在应用 postCardAction 接口的 call 事件时,须要在 FormExtensionAbility 中的 onAddForm 生命周期回调中更新 formId。
import formBindingData from '@ohos.app.form.formBindingData'; import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility'; export default class EntryFormAbility extends FormExtensionAbility {onAddForm(want) {let formId = want.parameters["ohos.extra.param.key.form_identity"]; let dataObj1 = {"formId": formId}; let obj1 = formBindingData.createFormBindingData(dataObj1); return obj1; } ... };
-
在卡片页面通过注册 Button 的 onClick 点击事件回调,并在回调中调用 postCardAction 接口触发 call 事件至 UIAbility。
let storage = new LocalStorage(); @Entry(storage) @Component struct WidgetCard {@LocalStorageProp('detail') detail: string = 'init'; @LocalStorageProp('formId') formId: string = '0'; build() {Column() {Button('拉至后盾') .margin('20%') .onClick(() => {console.info('postCardAction to EntryAbility'); postCardAction(this, { 'action': 'call', 'abilityName': 'EntryAbility', // 只能跳转到以后利用下的 UIAbility 'params': { 'method': 'funA', 'formId': this.formId, 'detail': 'CallFromCard' } }); }) Text(`${this.detail}`).margin('20%') } .width('100%') .height('100%') } }
-
在 UIAbility 的 onCreate 生命周期中监听 call 事件所需的办法,而后调用 updateForm 接口刷新卡片。
import UIAbility from '@ohos.app.ability.UIAbility'; import formBindingData from '@ohos.app.form.formBindingData'; import formProvider from '@ohos.app.form.formProvider'; import formInfo from '@ohos.app.form.formInfo'; const MSG_SEND_METHOD: string = 'funA' // 在收到 call 事件后会触发 callee 监听的办法 function FunACall(data) { // 获取 call 事件中传递的所有参数 let params = JSON.parse(data.readString()) if (params.formId !== undefined) { let curFormId = params.formId; let message = params.detail; console.info(`UpdateForm formId: ${curFormId}, message: ${message}`); let formData = {"detail": message}; let formMsg = formBindingData.createFormBindingData(formData) formProvider.updateForm(curFormId, formMsg).then((data) => {console.info('updateForm success.' + JSON.stringify(data)); }).catch((error) => {console.error('updateForm failed:' + JSON.stringify(error)); }) } return null; } export default class EntryAbility extends UIAbility { // 如果 UIAbility 第一次启动,call 事件后会触发 onCreate 生命周期回调 onCreate(want, launchParam) {console.info('Want:' + JSON.stringify(want)); try { // 监听 call 事件所需的办法 this.callee.on(MSG_SEND_METHOD, FunACall); } catch (error) {console.log(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`) } } ... }
卡片数据交互
ArkTS 卡片框架提供了 updateForm() 接口和 requestForm() 接口被动触发卡片的页面刷新。
以后卡片框架提供了如下几种刷新卡片的形式:
-
定时刷新:示意在肯定工夫距离内调用 onUpdateForm 的生命周期回调函数主动刷新卡片内容。能够在 form_config.json 配置文件的 updateDuration 字段中进行设置。例如,能够将刷新工夫设置为每小时一次。留神:updateDuration(定时刷新)优先级比 scheduledUpdateTime(定点刷新)高,配置定时刷新后,定点刷新将生效。
{ "forms": [ { "name": "widget", "description": "This is a service widget.", "src": "./ets/widget/pages/WidgetCard.ets", "uiSyntax": "arkts", "window": { "designWidth": 720, "autoDesignWidth": true }, "colorMode": "auto", "isDefault": true, "updateEnabled": true, // 使能刷新性能 "scheduledUpdateTime": "10:30", "updateDuration": 2, // 设置卡片定时刷新的更新周期(单位为 30 分钟,取值为自然数)"defaultDimension": "2*2", "supportDimensions": ["2*2"] } ] }
-
定点刷新:示意每天在某个工夫点刷新,在 form_config.json 文件中配置,详见 scheduledUpdateTime 字段。例如,每天在 10:30 更新卡片内容。
{ "forms": [ { "name": "widget", "description": "This is a service widget.", "src": "./ets/widget/pages/WidgetCard.ets", "uiSyntax": "arkts", "window": { "designWidth": 720, "autoDesignWidth": true }, "colorMode": "auto", "isDefault": true, "updateEnabled": true, // 使能刷新性能 "scheduledUpdateTime": "10:30", // 设置卡片的定点刷新的时刻 "updateDuration": 0, "defaultDimension": "2*2", "supportDimensions": ["2*2"] } ] }
当同时配置了定时刷新(updateDuration)和定点刷新(scheduledUpdateTime)时,定时刷新的优先级更高。如果想要配置定点刷新,则须要将 updateDuration 配置为 0。
-
下次刷新:通过 setFormNextRefreshTime 接口指定卡片的下一次刷新工夫(最短时间 5 分钟),例如,在接口调用的 5 分钟后刷新卡片内容。
import formProvider from '@ohos.app.form.formProvider'; let formId = '123456789'; // 理论业务场景须要应用正确的 formId try { // 设置过 5 分钟后更新卡片内容 formProvider.setFormNextRefreshTime(formId, 5, (err, data) => {if (err) {console.error(`Failed to setFormNextRefreshTime. Code: ${err.code}, message: ${err.message}`); return; } else {console.info('Succeeded in setFormNextRefreshTimeing.'); } }); } catch (err) {console.error(`Failed to setFormNextRefreshTime. Code: ${err.code}, message: ${err.message}`); }
在触发定时、定点或被动刷新后,零碎会调用 FormExtensionAbility 的 onUpdateForm 生命周期回调,在回调中,能够应用 updateForm 进行提供方刷新卡片。onUpdateForm 生命周期回调参考通过 FormExtensionAbility 刷新卡片内容。
- 定时刷新有配额限度,每张卡片每天最多通过定时形式触发刷新 50 次,定时刷新蕴含卡片配置项 updateDuration 和调用 setFormNextRefreshTime 两种,当达到 50 次配额后,无奈通过定时形式再次触发刷新,刷新次数会在每天的 0 点重置。
- 以后定时刷新应用同一个计时器进行计时,因而卡片定时刷新的第一次刷新会有最多 30 分钟的偏差。比方第一张卡片 A(每隔半小时刷新一次)在 3 点 20 分增加胜利,定时器启动并每隔半小时触发一次事件,第二张卡片 B(每隔半小时刷新一次)在 3 点 40 分增加胜利,在 3 点 50 分定时器事件触发时,卡片 A 触发定时刷新,卡片 B 会在下次事件 (4 点 20 分) 中才会触发。
- 定时刷新和定点刷新仅在屏幕亮屏状况下才会触发,在灭屏场景下仅会将记录刷新动作,待亮屏时对立进行刷新。
参考
- https://developer.harmonyos.com/cn/docs/documentation/doc-gui…