服务卡片概述
服务卡片(以下简称“卡片”)是一种界面展示形式,可以将应用的重要信息或操作前置到卡片,以达到服务直达、减少体验层级的目的。卡片常用于嵌入到其他应用(当前卡片使用方只支持系统应用,如桌面)中作为其界面显示的一部分,并支持拉起页面、发送消息等基础的交互功能。
服务卡片架构
图1 服务卡片架构
卡片的基本概念:
- 卡片使用方:如上图中的桌面,显示卡片内容的宿主应用,控制卡片在宿主中展示的位置。
- 卡片提供方:包含卡片的应用,提供卡片的显示内容、控件布局以及控件点击处理逻辑。
- FormExtensionAbility:卡片业务逻辑模块,提供卡片创建、销毁、刷新等生命周期回调。
- 卡片页面:卡片UI模块,包含页面控件、布局、事件等显示和交互信息。
卡片的常见使用步骤如下。
图2 卡片常见使用步骤
- 长按“桌面图标”,弹出操作菜单。
- 点击“服务卡片”选项,进入卡片预览界面。
- 点击“添加到桌面”按钮,即可在桌面上看到新添加的卡片。
服务卡片UI页面开发方式
在Stage模型下,服务卡片的UI页面支持通过ArkTS和JS两种语言进行开发:
- 基于声明式范式ArkTS UI开发的卡片,简称ArkTS卡片。
- 基于类Web范式JS UI开发的卡片,简称JS卡片。
ArkTS卡片与JS卡片具备不同的实现原理及特征,在场景能力上的差异如下表所示。
类别 | JS卡片 | ArkTS卡片 |
---|---|---|
开发范式 | 类Web范式 | 声明式范式 |
组件能力 | 支持 | 支持 |
布局能力 | 支持 | 支持 |
事件能力 | 支持 | 支持 |
自定义动效 | 不支持 | 支持 |
自定义绘制 | 不支持 | 支持 |
逻辑代码执行(不包含import能力) | 不支持 | 支持 |
相比于JS卡片,ArkTS卡片在能力和场景方面更加丰富,因此无论开发何种用途的卡片,都推荐使用ArkTS卡片,因为它可以提高开发效率并实现动态化。但如果只需要做静态页面展示的卡片,可以考虑使用JS卡片。
开发基于JS UI的卡片
以下内容介绍基于类Web范式的JS UI卡片开发指南。
运作机制
卡片框架的运作机制如图1所示。
图1 卡片框架运作机制(Stage模型)
卡片使用方包含以下模块:
- 卡片使用:包含卡片的创建、删除、请求更新等操作。
- 通信适配层:由OpenHarmony SDK提供,负责与卡片管理服务通信,用于将卡片的相关操作到卡片管理服务。
卡片管理服务包含以下模块:
- 周期性刷新:在卡片添加后,根据卡片的刷新策略启动定时任务周期性触发卡片的刷新。
- 卡片缓存管理:在卡片添加到卡片管理服务后,对卡片的视图信息进行缓存,以便下次获取卡片时可以直接返回缓存数据,降低时延。
- 卡片生命周期管理:对于卡片切换到后台或者被遮挡时,暂停卡片的刷新;以及卡片的升级/卸载场景下对卡片数据的更新和清理。
- 卡片使用方对象管理:对卡片使用方的RPC对象进行管理,用于使用方请求进行校验以及对卡片更新后的回调处理。
- 通信适配层:负责与卡片使用方和提供方进行RPC通信。
卡片提供方包含以下模块:
- 卡片服务:由卡片提供方开发者实现,开发者实现生命周期处理创建卡片、更新卡片以及删除卡片等请求,提供相应的卡片服务。
- 卡片提供方实例管理模块:由卡片提供方开发者实现,负责对卡片管理服务分配的卡片实例进行持久化管理。
- 通信适配层:由OpenHarmony SDK提供,负责与卡片管理服务通信,用于将卡片的更新数据主动推送到卡片管理服务。
说明
实际开发时只需要作为卡片提供方进行卡片内容的开发,卡片使用方和卡片管理服务由系统自动处理。
接口说明
FormExtensionAbility类拥有如下API接口,具体的API介绍详见接口文档。
接口名 | 描述 |
---|---|
onAddForm(want: Want): formBindingData.FormBindingData | 卡片提供方接收创建卡片的通知接口。 |
onCastToNormalForm(formId: string): void | 卡片提供方接收临时卡片转常态卡片的通知接口。 |
onUpdateForm(formId: string): void | 卡片提供方接收更新卡片的通知接口。 |
onChangeFormVisibility(newStatus: { [key: string]: number }): void | 卡片提供方接收修改可见性的通知接口。 |
onFormEvent(formId: string, message: string): void | 卡片提供方接收处理卡片事件的通知接口。 |
onRemoveForm(formId: string): void | 卡片提供方接收销毁卡片的通知接口。 |
onConfigurationUpdate(config: Configuration): void | 当系统配置更新时调用。 |
onShareForm?(formId: string): { [key: string]: any } | 卡片提供方接收卡片分享的通知接口。 |
formProvider类有如下API接口,具体的API介绍详见接口文档。
接口名 | 描述 |
---|---|
setFormNextRefreshTime(formId: string, minute: number, callback: AsyncCallback): void; | 设置指定卡片的下一次更新时间。 |
setFormNextRefreshTime(formId: string, minute: number): Promise; | 设置指定卡片的下一次更新时间,以promise方式返回。 |
updateForm(formId: string, formBindingData: FormBindingData, callback: AsyncCallback): void; | 更新指定的卡片。 |
updateForm(formId: string, formBindingData: FormBindingData): Promise; | 更新指定的卡片,以promise方式返回。 |
formBindingData类有如下API接口,具体的API介绍详见接口文档。
接口名 | 描述 |
---|---|
createFormBindingData(obj?: Object | string): FormBindingData | 创建一个FormBindingData对象。 |
开发步骤
Stage卡片开发,即基于Stage模型的卡片提供方开发,主要涉及如下关键步骤:
- 创建卡片FormExtensionAbility:卡片生命周期回调函数FormExtensionAbility开发。
- 配置卡片配置文件:配置应用配置文件module.json5和profile配置文件。
- 卡片信息的持久化:对卡片信息进行持久化管理。
- 卡片数据交互:通过updateForm更新卡片显示的信息。
- 开发卡片页面:使用HML+CSS+JSON开发JS卡片页面。
- 开发卡片事件:为卡片添加router事件和message事件。
创建卡片FormExtensionAbility
创建Stage模型的卡片,需实现FormExtensionAbility生命周期接口。先参考DevEco Studio服务卡片开发指南生成服务卡片模板。
-
在EntryFormAbility.ts中,导入相关模块。
import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility'; import formBindingData from '@ohos.app.form.formBindingData'; import formInfo from '@ohos.app.form.formInfo'; import formProvider from '@ohos.app.form.formProvider'; import dataStorage from '@ohos.data.storage';
-
在EntryFormAbility.ts中,实现FormExtension生命周期接口。
export default class EntryFormAbility extends FormExtensionAbility { onAddForm(want) { console.info('[EntryFormAbility] onAddForm'); // 使用方创建卡片时触发,提供方需要返回卡片数据绑定类 let obj = { "title": "titleOnCreate", "detail": "detailOnCreate" }; let formData = formBindingData.createFormBindingData(obj); return formData; } onCastToNormalForm(formId) { // 使用方将临时卡片转换为常态卡片触发,提供方需要做相应的处理 console.info('[EntryFormAbility] onCastToNormalForm'); } onUpdateForm(formId) { // 若卡片支持定时更新/定点更新/卡片使用方主动请求更新功能,则提供方需要重写该方法以支持数据更新 console.info('[EntryFormAbility] onUpdateForm'); let obj = { "title": "titleOnUpdate", "detail": "detailOnUpdate" }; let formData = formBindingData.createFormBindingData(obj); formProvider.updateForm(formId, formData).catch