OpenHarmony开发者论坛
标题:
OpenHarmony服务卡片的用法详解
[打印本页]
作者:
Laval社区小助手
时间:
2024-1-8 10:55
标题:
OpenHarmony服务卡片的用法详解
[md]## 卡片概述
**卡片是一种界面展示形式,可以将应用的重要信息或操作前置到卡片,以达到服务直达,减少体验层级的目的。**
![卡片展示](
https://devpress.csdnimg.cn/5fc03ddb643546708341acbb16292af8.png
)
卡片展示
**卡片常用于嵌入到其他应用(当前仅支持系统应用,例如Launcher)中作为其界面的一部分显示,并支持拉起页面,发送消息等基础的交互功能。**
**卡片的基本概念:**
**卡片提供方**:提供卡片显示内容原子化服务,控制卡片的显示内容、控件布局以及控件点击事件。
**包含以下模块:**
* **卡片服务:由卡片提供方开发者实现,开发者实现onCreate、onUpdate和onDestroy处理创建卡片、更新卡片以及销毁卡片等请求,提供相应的卡片服务。**
* **卡片实例管理模块:由卡片提供方开发者实现,负责对卡片管理服务分配的卡片实例进行持久化管理。**
* **通信适配层:由OpenHarmony SDK提供,负责与卡片管理服务通信,用于将卡片的更新数据主动推送到卡片管理服务。**
**卡片使用方**:显示卡片内容的宿主应用,负责显示卡片,控制卡片在宿主中展示的位置。
**卡片管理服务**:用于管理系统中所添加卡片的常驻代理服务,包括卡片对象的管理与使用,以及卡片周期性刷新等。
**包含以下模块:**
* **周期性刷新:在卡片添加后,根据卡片的刷新策略启动定时任务周期性触发卡片的刷新。**
* **卡片缓存管理:在卡片添加到卡片管理服务后,对卡片的视图信息进行缓存,以便下次获取卡片时可以直接返回缓存数据,降低时延。**
* **卡片生命周期管理:对于卡片切换到后台或者被遮挡时,暂停卡片的刷新;以及卡片的升级/卸载场景下对卡片数据的更新和清理。**
* **卡片使用方对象管理:对卡片使用方的RPC对象进行管理,用于使用方请求进行校验以及对卡片更新后的回调处理。**
* **通信适配层:负责与卡片使用方和提供方进行RPC通信。**
![](
https://devpress.csdnimg.cn/4bef60c80222438e9d24a9df2224fbef.png
)
![]()
**卡片使用方和提供方不要求常驻运行,在需要添加/删除/请求更新卡片时,卡片管理服务会拉起卡片提供方获取卡片信息。**
**开发者仅需作为卡片提供方进行卡片内容的开发,卡片使用方和卡片管理服务由系统自动处理。**
## 场景介绍
**基于****FA模型**的卡片提供方开发,主要涉及如下功能逻辑:
* **开发卡片生命周期回调函数LifecycleForm**
* **创建卡片数据FormBindingData对象**
* **通过FormProvider更新卡片**
* **开发卡片页面**
**基于****Stage模型**的卡片提供方开发,主要涉及如下功能逻辑:
* **卡片生命周期回调函数FormExtension开发**
* **创建卡片数据FormBindingData对象**
* **通过FormProvider更新卡片**
* **卡片页面开发**
## 卡片开发指导
### 卡片提供方创建卡片
1. **打开DevEco 3.0.0.993新建一个项目**
2. **选择一个module创建卡片,每个module最多创建16张卡片,此处以entry为例。**
**选中entry文件夹,右键New-->Extension Ability -->Service Widget**
* **FA模型项目** ![FA模型项目](
https://devpress.csdnimg.cn/be3b90ebc9ca4bee9881e103e5886fc2.png
)
* **Stage模型项目** ![Stage模型项目](
https://devpress.csdnimg.cn/411d0c3eb9e94ae9a3b7cc43dd059b05.png
)
3. **任选一种卡片模板。OpenHarmony 目前支持以下三种卡片模板:**
**HelloWorld** : 支持低代码开发的HelloWorld卡片。 **Image With Information** : 图文卡片。图文卡片模板主要在于展现图片和一定数量文本的搭配,在这种布局下,图片和文本属于同等重要的信息。在不同尺寸下,图片大小和文本数量会发生一定变化,用于凸显关键信息。 **Immersive Information** : 沉浸式卡片。 沉浸式卡片的装饰性较强,能够较好的提升卡片品质感并起到装饰桌面的作用,合理的去布局信息与背景图片之间的空间比例,可以提升用户的个性化使用体验。
![](
https://devpress.csdnimg.cn/1c5047d95e704a36a757cb4d9ffd3c19.png
)
![]()
4. **设置卡片信息。**
**Service widget name**:卡片的名称,卡片名称不能重复,且只能包含数字、字母和下划线。
**Description**:卡片的描述信息。
**Enable Super Visual**:是否选择低代码方式开发。
**Language**:界面开发语言,目前只支持js。
**Support dimensions**:选择卡片的规格。部分卡片支持同时设置多种规格。 **Ability name**:选择一个挂靠服务卡片的Page Ability,或者创建一个新的Page Ability。 **Module name**:卡片所属的模块。
![]()
![](
https://devpress.csdnimg.cn/36f2481c93f641c393cafbc3efe97a6a.png
)
5. **点击Finish,完成卡片的创建之后,会生成如下文件。**
* **FA模型项目**
![](
https://devpress.csdnimg.cn/485a8cc184774e818801b62b9c13439c.png
)
![]()
* **Stage模型项目**
![](
https://devpress.csdnimg.cn/55186096309d4969b38e10344208ac36.png
)
![]()
6. **安装应用到设备上,在设备的桌面上长按应用图标,等待出现服务卡片字样,点击后选择需要的卡片尺寸,添加到屏幕。**
![卡片展示](
https://devpress.csdnimg.cn/a114918a06bf4226baf2110ce6e46b62.png
)
### 卡片页面文件说明
**JS卡片页面通过hml+css+json开发**
* `index.hml`文件:
**卡片的显示页面,卡片上显示的数据及事件均在** `index.json`中定义,在FormAbility.ts中修改和处理。
`index.hml` 中标签为OpenHarmony专用,目前支持div、list、list-item、swiper、stack、image、text、span、progress、button(定制:chart 、clock、calendar)。hml文件中可使用类似vue的模板语法,支持{{}},if,show,for等。
**代码示例:**
```xml
<div class="container">
<stack >
<div class="container-inner" onclick="routerPage" >
<!-- $t('strings.temperature') 是从string.json资源文件中读取值-->
<!-- temperature 是获取index.json文件的data中定义的变量 -->
<text class="title" show="true">{{ $t('strings.temperature') }}{{temperature}} ℃</text>
<text class="title" onclick="onUpdateEvent">{{ $t('strings.time') }} {{time}}</text>
</div>
</stack>
</div>
```
* `index.css`文件:
**存放** `index.hml`页面中使用的 `css`样式。
**代码示例:**
```
.container {
flex-direction: column;
justify-content: center;
align-items: center;
}
```
* `index.json`文件:
**存放卡片页面** `index.hml`中的变量及事件。
**内部字段结构说明:**
* `data`:存放的是 `index.hml`中使用到的变量
**代码示例:**
```
"data": {
"temperature": "0",
"time": "00:00:00"
}
```
* `actions`: 存放的是 `index.hml`中使用的事件,有两种类型:`router`和 `message`。
**router类型事件**:用于卡片提供方进行跳转,需相应配置 `abilityName`属性用于存放目标 `Ability`名称。
**message类型事件**:用于卡片与卡片提供方进行交互,会触发卡片生命周期中的 `onEvent`方法。
**代码示例:**
```
"actions": {
"routerPage": {
"action": "router",
"abilityName": "ohos.samples.FormApplication.MainAbility",
"params": {
"message": "add detail"
}
},
"onUpdateEvent": {
"action": "message",
"params": {
"name" : "onUpdateEvent",
"message": "add detail"
}
},
}
```
### 卡片配置文件
#### Stage模型下的卡片配置文件
##### module.json5
**卡片需要在应用配置文件** `module.json5`中的 `extensionAbilities`标签下,配置 `ExtensionAbility`相关信息。
**内部字段结构说明:**
| **属性名称** | **含义** | **数据类型** | **是否可缺省** |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | ------------------------------ |
| **name** | **表示ExtensionAbility的名字。** | **字符串** | **否** |
| **srcEntrance** | **表示ExtensionAbility所对应的生命周期代码的路径。** | **字符串** | **否** |
| **description** | **表示ExtensionAbility的描述。可以是表示描述内容的字符串,也可以是对描述内容的资源索引以支持多语言。** | **字符串** | **可缺省,缺省值为空。** |
| **icon** | **表示ExtensionAbility的图标资源文件的索引。** | **字符串** | **可缺省,缺省值为空。** |
| **label** | **表示ExtensionAbility的标签信息,即ExtensionAbility对外显示的文字描述信息。取值可以是描述性内容,也可以是标识label的资源索引。** | **字符串** | **可缺省,缺省值为空。** |
| **type** | **表示ExtensionAbility的类型,对于当前FormExtensionAbility的开发,需要将其配置为form。** | **字符串** | **否** |
| **permissions** | **表示其他应用的Ability调用此ExtensionAbility时需要申请的权限。** | **字符串数组** | **可缺省,缺省值为空。** |
| **metadata** | **表示ExtensionAbility的元信息,用于描述ExtensionAbility的配置信息。** | **对象** | **可缺省,缺省值为空** |
| **uri** | **为当前ExtensionAbility提供的 uri 数据。** | **字符串** | **可缺省,缺省值为空。** |
| **readPermission** | **另一个应用程序的 ExtensionAbility调用当前ExtensionAbility所需的读权限。** | **字符串** | **可缺省,缺省值为空。** |
| **writePermission** | **另一个应用程序的 ExtensionAbility调用当前ExtensionAbility所需的写权限。** | **字符串** | **可缺省,缺省值为空。** |
| **visible** | **表明当前ExtensionAbility能否被其他应用调起。** | **布尔** | **false** |
**对于FormExtensionAbility来说,需要填写metadata元信息标签,其中键名称为固定字符串"ohos.extension.form",资源为卡片的具体配置信息的索引。**
**示例:**
```
"extensionAbilities": [
{
"name": "FormAbility",
"srcEntrance": "./ets/FormAbility/FormAbility.ts",
"label": "$string:form_FormAbility_label",
"description": "$string:form_FormAbility_desc",
"type": "form",
"metadata": [
{
"name": "ohos.extension.form",
"resource": "$profile:form_config",
},
],
},
]
```
##### form\_config.json
**卡片的具体配置信息。在上述 FormExtensionAbility 的元信息中,指定了的卡片具体配置信息的资源索引,如使用 \$profile:form\_config 指定开发视图的 resources/base/profile/ 目录下的 form\_config.json 作为卡片profile配置文件。**
**内部字段结构说明:**
| **属性名称** | **含义** | **数据类型** | **是否可缺省** |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | ------------------------------------ |
| **name** | **表示卡片的类名,字符串最大长度为127字节。** | **字符串** | **否** |
| **description** | **表示卡片的描述。取值可以是描述性内容,也可以是对描述性内容的资源索引,以支持多语言。字符串最大长度为255字节。** | **字符串** | **可缺省,缺省为空。** |
| **src** | **表示卡片对应的UI代码的完整路径。** | **字符串** | **否** |
| **window** | **用于定义与显示窗口相关的配置。** | **对象** | **可缺省** |
| **isDefault** | **表示该卡片是否为默认卡片,每个Ability有且只有一个默认卡片。 true:默认卡片。 false:非默认卡片。** | **布尔值** | **否** |
| **colorMode** | **表示卡片的主题样式,取值范围如下: auto:自适应。 dark:深色主题。 light:浅色主题。** | **字符串** | **可缺省,缺省值为“auto”。** |
| **supportDimensions** | **表示卡片支持的外观规格,取值范围: 1 \* 2:表示1行2列的二宫格。 2 \* 2:表示2行2列的四宫格。 2 \* 4:表示2行4列的八宫格。 4 \* 4:表示4行4列的十六宫格。** | **字符串数组** | **否** |
| **defaultDimension** | **表示卡片的默认外观规格,取值必须在该卡片supportDimensions配置的列表中。** | **字符串** | **否** |
| **updateEnabled** | **表示卡片是否支持周期性刷新,取值范围: true:表示支持周期性刷新,可以在定时刷新(updateDuration)和定点刷新(scheduledUpdateTime)两种方式任选其一,优先选择定时刷新。 false:表示不支持周期性刷新。** | **布尔类型** | **否** |
| **scheduledUpdateTime** | **表示卡片的定点刷新的时刻,采用24小时制,精确到分钟。** | **字符串** | **可缺省,缺省值为“0:0”。** |
| **updateDuration** | **表示卡片定时刷新的更新周期,单位为30分钟,取值为自然数。 当取值为0时,表示该参数不生效。 当取值为正整数N时,表示刷新周期为30\*N分钟。** | **数值** | **可缺省,缺省值为“0”。** |
| **formConfigAbility** | **表示卡片的配置跳转链接,采用URI格式。** | **字符串** | **可缺省,缺省值为空。** |
| **formVisibleNotify** | **标识是否允许卡片使用卡片可见性通知。** | **字符串** | **可缺省,缺省值为空。** |
| **metaData** | **表示卡片的自定义信息,包含customizeData数组标签。** | **对象** | **可缺省,缺省值为空。** |
**示例:**
```
{
"forms": [
{
"name": "widget",
"description": "This is a service widget.",
"src": "./js/widget/pages/index/index",
"formConfigAbility": "ability://ohos.samples.FormApplication.MainAbility",
"window": {
"designWidth": 720,
"autoDesignWidth": true
},
"colorMode": "auto",
"isDefault": true,
"updateEnabled": true,
"scheduledUpdateTime": "11:32",
"updateDuration" : 1,
"defaultDimension": "2*4",
"supportDimensions": ["2*4", "4*4"]
}
]
}
```
#### FA模型下的卡片配置文件
**FA模型的卡片只需在项目的配置文件** `config.json`中进行配置,分为js模块和ability模块两个部分。
* **js模块,用于对应卡片的js相关资源,内部字段结构说明:**
| **属性名称** | **含义** | **数据类型** | **是否可缺省** |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | ------------------------------------ |
| **name** | **表示JS Component的名字,要与“abilities”模块中的jsComponentName字段的值一致,为js资源的实例名。该标签不可缺省,默认值为default。** | **字符串** | **否** |
| **pages** | **表示JS Component的页面用于列举JS Component中每个页面的路由信息[页面路径+页面名称]。该标签不可缺省,取值为数组,数组第一个元素代表JS FA首页。** | **数组** | **否** |
| **window** | **用于定义与显示窗口相关的配置。** | **对象** | **可缺省** |
| **type** | **表示JS应用的类型。取值范围如下: normal:标识该JS Component为应用实例。 form:标识该JS Component为卡片实例。** | **字符串** | **可缺省,缺省值为“normal”** |
| **mode** | **定义JS组件的开发模式。** | **对象** | **可缺省,缺省值为空** |
**配置示例如下:**
```
"js": [{
"name": "widget",
"pages": ["pages/index/index"],
"window": {
"designWidth": 720,
"autoDesignWidth": true
},
"type": "form"
}]
```
* **abilities模块,用于对应卡片的LifecycleForm,内部字段结构说明:**| **属性名称** | **含义** | **数据类型** | **是否可缺省** |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | ------------------------------------- |
| **name** | **表示卡片名,即在onCreate方法中根据want.parameters["ohos.extra.param.key.form\_name"]可取到的值。字符串最大长度为127字节。** | **字符串** | **否** |
| **description** | **表示卡片的描述。取值可以是描述性内容,也可以是对描述性内容的资源索引,以支持多语言。字符串最大长度为255字节。** | **字符串** | **可缺省,缺省为空。** |
| **isDefault** | **表示该卡片是否为默认卡片,每个Ability有且只有一个默认卡片。 true:默认卡片。 false:非默认卡片。** | **布尔值** | **否** |
| **type** | **表示卡片的类型。取值范围如下: JS:JS卡片。** | **字符串** | **否** |
| **colorMode** | **表示卡片的主题样式,取值范围如下: auto:自适应。 dark:深色主题。 light:浅色主题。** | **字符串** | **可缺省,缺省值为“auto”。** |
| **supportDimensions** | **表示卡片支持的外观规格,取值范围: 1 \* 2:表示1行2列的二宫格。 2 \* 2:表示2行2列的四宫格。 2 \* 4:表示2行4列的八宫格。 4 \* 4:表示4行4列的十六宫格。** | **字符串数组** | **否** |
| **defaultDimension** | **表示卡片的默认外观规格,取值必须在该卡片supportDimensions配置的列表中。** | **字符串** | **否** |
| **updateEnabled** | **表示卡片是否支持周期性刷新,取值范围: true:表示支持周期性刷新,可以在定时刷新(updateDuration)和定点刷新(scheduledUpdateTime)两种方式任选其一,优先选择定时刷新。 false:表示不支持周期性刷新。** | **布尔类型** | **否** |
| **scheduledUpdateTime** | **表示卡片的定点刷新的时刻,采用24小时制,精确到分钟。** | **字符串** | **可缺省,缺省值为“0:0”。** |
| **updateDuration** | **表示卡片定时刷新的更新周期,单位为30分钟,取值为自然数。 当取值为0时,表示该参数不生效。 当取值为正整数N时,表示刷新周期为30\*N分钟。** | **数值** | **可缺省,缺省值为“0”。** |
| **formConfigAbility** | **表示卡片的配置跳转链接,采用URI格式。** | **字符串** | **可缺省,缺省值为空。** |
| **formVisibleNotify** | **标识是否允许卡片使用卡片可见性通知。** | **字符串** | **可缺省,缺省值为空。** |
| **jsComponentName** | **表示JS卡片的Component名称。字符串最大长度为127字节。** | **字符串** | **否** |
| **metaData** | **表示卡片的自定义信息,包含customizeData数组标签。** | **对象** | **可缺省,缺省值为空。** |
| **customizeData** | **表示自定义的卡片信息。** | **对象数组** | **可缺省,缺省值为空。** |
| **formsEnabled** | **标识Ability是否支持卡片(forms)功能。该标签仅适用于page类型的Ability。** **true:支持卡片能力。** **false:不支持卡片能力。** | **布尔值** | **可缺省,缺省值为“false”。** |
**配置示例如下:**
```
"abilities": [{
"name": "FormAbility",
"description": "This is a FormAbility",
"formsEnabled": true,
"icon": "$media:icon",
"label": "$string:form_FormAbility_label",
"srcPath": "FormAbility",
"type": "service",
"srcLanguage": "ets",
"formsEnabled": true,
"forms": [{
"colorMode": "auto",
"defaultDimension": "2*2",
"description": "This is a service widget.",
"formVisibleNotify": true,
"isDefault": true,
"jsComponentName": "widget",
"name": "widget",
"scheduledUpdateTime": "10:30",
"supportDimensions": ["2*2"],
"type": "JS",
"updateDuration": 1,
"updateEnabled": true
}]
}]
```
### 页面拉起功能
**为卡片配置跳转类型的事件routerEvent,实现点击卡片拉起卡片应用。**
**跳转事件通过拉起本应用的Ability来打开应用,跳转事件中配置的参数** `params`会被包含在Ability的onCreate生命周期函数的want参数中。
**实现步骤如下:**
1. **在index.hml页面添加点击事件** `routerEvent`。
```
<div class="container-inner" onclick="routerEvent"></div>
```
2. **在index.json中的actions标签下定义** `routerEvent`事件
> **action字段填router,表明是跳转事件** **abilityName填写要跳转的Ability名**
>
```
"actions": {
"routerEvent": {
"action": "router",
"abilityName": "ohos.samples.FormApplication.MainAbility",
"params": {
"message": "add detail"
}
},
}
```
### 数据交互功能
**卡片提供了动态刷新卡片数据的能力。**
**例如,在index.hml页面中展示两个数据:temperature 和 time**
```xml
<text class="title" >{{ $t('strings.temperature') }}{{temperature}} ℃</text>
<text class="title" onclick="messageEvent">{{ $t('strings.time') }} {{time}}</text>
```
**数据 temperature 和 time 已在index.json中定义:**
```
{
"data": {
"temperature": "0",
"time": "00:00:00"
}
}
```
**可以通过以下方式来实现卡片的数据交互。**
#### 手动刷新数据
**通过调用message类型的事件触发卡片生命周期函数onEvent,在onEvent函数中可以获取到当前卡片实例的Id及传入的事件信息。**
**在onEvent函数中根据事件名来进行不同的操作,当传入的是更新数据的事件名时,调用formProvider接口的updateForm方法来更新卡片数据。**
![](
https://devpress.csdnimg.cn/bf6e688f06434c4182b145205e2e4359.png
)
![]()
1. **在index.hml文件中创建按钮,绑定** `onUpdateEvent`事件
```
<button class="button" type="capsule" onclick="onUpdateEvent" >手动更新</button>
```
2. **在index.json文件中声明** `onUpdateEvent`事件,action类型为 `message`
```
{
"data": {
"temperature": "0",
"time": "00:00:00"
},
"actions":{
"onUpdateEvent": {
"action": "message",
"params": {
"name" : "onUpdateEvent",
"message": "add detail"
}
}
}
}
```
3. **在FormAbility.ts中的onEvent方法中,获取事件名onUpdateEvent,然后进行卡片数据更新操作。**
```
import formBindingData from '@ohos.application.formBindingData';
import formProvider from '@ohos.application.formProvider';
var timer: number = 0
//卡片页面数据刷新函数
async function updateFormData(formId: string) {
let obj = {
"temperature": getTemperature(formId, formInfo.updateCount).toString(),
"time": getTime()
}
let formData = formBindingData.createFormBindingData(obj)
formProvider.updateForm(formId, formData).catch(err => {
Logger.error("updateOne err : " + JSON.stringify(err))
})
}
onEvent(formId, message) {
console.log("FormAbility onEvent, formId = " + formId + ", message:" + JSON.stringify(message));
let jsonParams = JSON.parse(message)
//获取事件名
let eventName = jsonParams.params.name
switch (eventName) {
case "onUpdateEvent":
updateFormData(formId);
break;
default:
console.log("(onEvent) formId :" + formId + " message : " + message)
break;
}
}
```
#### 定点刷新数据
**在卡片配置文件中可以配置** `scheduledUpdateTime`属性来实现卡片定点刷新数据,
`scheduledUpdateTime`表示卡片的定点刷新的时刻,采用24小时制,精确到分钟。
**时间到达** `scheduledUpdateTime`参数设置的时刻时,会触发卡片生命周期的 `onUpdate`方法,在 `onUpdate`方法中执行卡片数据更新操作。
**代码示例:**
**Stage模型**在 `form_config.json`文件中配置 `scheduledUpdateTime`属性:
```
{
"forms": [
{
//...
"scheduledUpdateTime": "11:32",
"updateDuration" : 0,
//...
}
]
}
```
**FA模型**在 `config.json`文件中配置 `scheduledUpdateTime`属性:
```
{
"forms": [
{
//...
"scheduledUpdateTime": "11:32",
"updateDuration" : 0,
//...
}
]
}
```
`FormAbility.ts`中的 `onUpdate`生命周期函数:
```
onUpdate(formId) {
console.log("FormAbility onUpdate, formId:" + formId);
//卡片数据更新方法
updateFormData(formId);
}
```
#### 定时刷新数据
##### 方式一:通过配置文件,配置定时刷新数据
**在卡片配置文件** `form_config.json`中可以配置来实现卡片定时刷新数据,
`updateDuration`属性表示卡片定时刷新的更新周期,单位为30分钟,取值为自然数(正整数或0)。
**当取值为0时,表示该参数不生效。**
**当取值为正整数N时,表示刷新周期为30×N分钟,每隔30×N分钟会触发卡片生命周期的** `onUpdate`方法,在 `onUpdate`方法中执行卡片数据更新操作。
**当取值为正整数N时,定点刷新数据不生效。**
**示例:**
**Stage模型**在 `form_config.json`文件中配置 `updateDuration`属性:
```
{
"forms": [
{
...
"updateDuration" : 1,
...
}
]
}
```
**FA模型**在 `config.json`文件中配置 `updateDuration`属性:
```
{
"forms": [
{
...
"updateDuration" : 1,
...
}
]
}
```
`FormAbility.ts`中的 `onUpdate`生命周期函数:
```
onUpdate(formId) {
console.log("FormAbility onUpdate, formId: " + formId);
//卡片数据更新方法
updateFormData(formId);
}
```
##### 方式二:通过FormProvider 接口,设置过多少分钟刷新一次。
**最少设置为过5分钟刷新一次**
```
import formProvider from '@ohos.application.formProvider';
formProvider.setFormNextRefreshTime(formId,5,err => {
Logger.error("setFormNextRefreshTime err : " + JSON.stringify(err))
})
```
### 卡片信息持久化
**因大部分卡片提供方都不是常驻服务,只有在需要使用时才会被拉起获取卡片信息,且卡片管理服务支持对卡片进行多实例管理。因此若卡片提供方支持对卡片数据进行配置,则需要对卡片的业务数据按照卡片ID进行持久化管理,以便在后续获取、更新以及拉起时能获取到正确的卡片业务数据,且需要适配onDestroy卡片销毁通知接口,在其中实现卡片实例数据的删除。**
**卡片根据业务数据是否需要持久化分为以下两类:**
* **常态卡片:卡片使用方会持久化的卡片;**
* **临时卡片:卡片使用方不会持久化的卡片;**
**卡片管理服务创建卡片时会调用卡片提供方的卡片生命周期函数** `onCreate`,在 `onCreate`的入参 `want`中会包含 `ohos.extra.param.key.form_temporary`字段,该字段表明当前新建的卡片是临时卡片还是常态卡片,当前默认创建的是常态卡片。
![](
https://devpress.csdnimg.cn/41aa2b6c76bc4ee0a04dd5b5029beb1b.png
)
![]()
**临时卡片的数据具有非持久化的特殊性,某些场景比如卡片服务框架死亡重启,此时临时卡片数据在卡片管理服务中已经删除,且对应的卡片ID不会通知到提供方,所以卡片提供方需要自己负责清理长时间未删除的临时卡片数据。同时对应的卡片使用方可能会将之前请求的临时卡片转换为常态卡片。如果转换成功,卡片提供方也需要对对应的临时卡片ID进行处理,把卡片提供方记录的临时卡片数据转换为常态卡片数据,防止提供方在清理长时间未删除的临时卡片时,把已经转换为常态卡片的临时卡片信息删除,导致卡片信息丢失。**
**如果需要将临时卡片转化为常态卡片,可参考轻量级数据存储,将卡片示例的业务数据进行存储调用。**
```
import dataStorage from '@ohos.data.storage';
const DATA_STORAGE_PATH = "/data/storage/el2/base/haps/form_store";
async function storeFormInfo(formId: string, formName: string, tempFlag: boolean) {
let formInfo = {
"formName": formName,
"tempFlag": tempFlag,
"updateCount": 0
};
try {
const storage = await dataStorage.getStorage(DATA_STORAGE_PATH);
// put form info
await storage.put(formId, JSON.stringify(formInfo));
Logger.log("storeFormInfo, put form info successfully, formId: " + formId);
await storage.flush();
} catch (err) {
Logger.error("failed to storeFormInfo, err: " + JSON.stringify(err));
}
}
```
**持久化存储后如图:**
![](
https://devpress.csdnimg.cn/bc123252c97d41f19a08d04cb9b63094.png
)
![]()
**框架只是提供了临时卡片这种机制,具体的使用场景根据不同的使用方来确定,使用方根据自己的业务场景可以选择使用或者不使用临时卡片的机制。建议咨询对应使用方(比如桌面、服务中心等等)来确认使用临时卡片的场景。**
## 接口说明
### 卡片提供方
**Stage模型**中卡片提供方涉及如下四个接口:**FormExtension**、FormExtensionContext、FormProvider、FormBindingData。
**FA模型**中卡片提供方涉及如下四个接口:**LifecycleForm**、FormExtensionContext、FormProvider、FormBindingData。
#### LifecycleForm (FA)
**该接口提供了卡片生命周期函数。**
**在卡片提供方应用中的FormAbility.ts文件中继承FormExtension并实现这些卡片的生命周期函数。**
| **接口名** | **描述** |
| ------------------------------------------------------------------------ | ------------------------------------------------------ |
| **onCreate(want: Want): formBindingData.FormBindingData** | **卡片提供方接收创建卡片的通知接口。** |
| **onCastToNormal(formId: string): void** | **卡片提供方接收临时卡片转常态卡片的通知接口。** |
| **onUpdate(formId: string): void** | **卡片提供方接收更新卡片的通知接口。** |
| **onVisibilityChange(newStatus: { [key: string]: number }): void** | **卡片提供方接收修改可见性的通知接口。** |
| **onEvent(formId: string, message: string): void** | **卡片提供方接收处理卡片事件的通知接口。** |
| **onDestroy(formId: string): void** | **卡片提供方接收销毁卡片的通知接口。** |
| **onAcquireFormState?(want: Want): formInfo.FormState** | **卡片提供方接收查询卡片状态的通知接口。** |
#### FormExtension(Stage)
**该接口提供了卡片生命周期函数。**
**在卡片提供方应用中的FormAbility.ts文件中继承FormExtension并实现这些卡片的生命周期函数。**
| **接口名** | **描述** |
| ------------------------------------------------------------------------ | ------------------------------------------------------ |
| **onCreate(want: Want): formBindingData.FormBindingData** | **卡片提供方接收创建卡片的通知接口。** |
| **onCastToNormal(formId: string): void** | **卡片提供方接收临时卡片转常态卡片的通知接口。** |
| **onUpdate(formId: string): void** | **卡片提供方接收更新卡片的通知接口。** |
| **onVisibilityChange(newStatus: { [key: string]: number }): void** | **卡片提供方接收修改可见性的通知接口。** |
| **onEvent(formId: string, message: string): void** | **卡片提供方接收处理卡片事件的通知接口。** |
| **onDestroy(formId: string): void** | **卡片提供方接收销毁卡片的通知接口。** |
| **onConfigurationUpdated(config: Configuration): void;** | **当系统配置更新时调用。** |
| **onAcquireFormState(want)** | **卡片提供方接收查询卡片状态的通知接口。** |
**FormExtension类还拥有成员context ,为FormExtensionContext类。**
#### FormExtensionContext
**卡片上下文环境类**
| **接口名** | **描述** |
| ------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- |
| **updateForm(formId: string, formBindingData: formBindingData.FormBindingData, callback: AsyncCallback**<void>**): void** | **回调形式主动更新卡片。** |
| **updateForm(formId: string, formBindingData: formBindingData.FormBindingData): Promise**<void> | **Promise形式主动更新卡片。** |
#### FormProvider
**卡片提供方,可以更新卡片信息、设置卡片下一次刷新时间。**
| **接口名** | **描述** |
| ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| **setFormNextRefreshTime(formId: string, minute: number, callback: AsyncCallback**<void>**): void;** | **设置指定卡片的下一次更新时间,参数minute表示过多少分钟更新卡片,最低为5分钟。** |
| **setFormNextRefreshTime(formId: string, minute: number): Promise**<void>**;** | **设置指定卡片的下一次更新时间,以promise方式返回。** |
| **updateForm(formId: string, formBindingData: FormBindingData, callback: AsyncCallback**<void>**): void;** | **更新指定的卡片。** |
| **updateForm(formId: string, formBindingData: FormBindingData): Promise**<void>**;** | **更新指定的卡片,以promise方式返回。** |
#### FormBindingData
**卡片绑定数据,与卡片页面的变量绑定。**
| **接口名** | **描述** |
| -------------------------------------------- | ----------------------------------- |
| **createFormBindingData(obj?: Object** | **string): FormBindingData;** |
### 卡片管理服务
**卡片管理服务主要提供如下两个接口:@ohos.application.formHost.d.ts、@ohos.application.formInfo。**
#### FormHost
> **在API8以前该接口是@ohos.ability.formManager.d.ts**
**该接口提供了卡片使用方相关接口的能力,包括删除、释放、请求更新卡片,发送通知到指定卡片,获取卡片信息、状态等。**
**系统能力**:SystemCapability.Ability.Form
**权限**:ohos.permission.REQUIRE\_FORM、ohos.permission.GET\_BUNDLE\_INFO\_PRIVILEGED
| **接口名** | **所需权限** | **描述** |
| ---------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **deleteForm**(formId: string): Promise<void>**;** | **ohos.permission.REQUIRE\_FORM** | **根据卡片ID删除卡片。调用此方法后,应用程序将无法使用卡片,并且卡片管理服务不再保留有关卡片的缓存信息。** |
| **releaseForm**(formId: string, isReleaseCache?: boolean): Promise<void>**;** | **ohos.permission.REQUIRE\_FORM** | **根据卡片ID释放卡片。调用此方法后,应用程序将无法使用该卡片,但卡片管理器服务仍保留该卡片的缓存信息,以便应用程序根据卡片ID快速获取** |
| **requestForm**(formId: string): Promise<void>**;** | **ohos.permission.REQUIRE\_FORM** | **根据卡片ID请求卡片更新。当应用程序检测到正在侦听的系统设置项(例如语言、分辨率或屏幕方向)已更改时,必须调用此方法。卡片提供者收到更新请求后,会通过卡片框架自动更新卡片数据(如果有更新),更新过程是应用程序无法感知的。** |
| **castTempForm**(formId: string): Promise<void>**;** | **ohos.permission.REQUIRE\_FORM** | **将应用程序已获取的指定临时卡片转换为普通卡片。** |
| **notifyVisibleForms**(formIds: Array<string>**): Promise**<void>**;** | **ohos.permission.REQUIRE\_FORM** | **向卡片框架发送通知以使指定的卡片可见。该方法调用成功后,会调用onVisibilityChange通知卡片提供者卡片可见性改变事件。** |
| **notifyInvisibleForms**(formIds: Array<string>**): Promise**<void>**;** | **ohos.permission.REQUIRE\_FORM** | **向卡片框架发送通知以使指定的卡片不可见。该方法调用成功后,会调用onVisibilityChange通知卡片提供者卡片可见性改变事件。** |
| **enableFormsUpdate**(formIds: Array<string>**): Promise**<void>**;** | **ohos.permission.REQUIRE\_FORM** | **通知卡片框架使指定的卡片可更新。可以使用此方法将卡片刷新状态设置为 true,卡片可以接收来自服务的新更新。** |
| **disableFormsUpdate**(formIds: Array<string>**): Promise**<void>**;** | **ohos.permission.REQUIRE\_FORM** | **通知卡片框架使指定的卡片不可更新。可以使用此方法将卡片刷新状态设置为 false,卡片不接收来自服务的新更新。** |
| **isSystemReady**(): Promise<void>**;** | **/** | **检查系统是否准备就绪。** |
| **getAllFormsInfo**(): Promise<Array<formInfo.FormInfo>>; | **ohos.permission.GET\_BUNDLE\_INFO\_PRIVILEGED** | **获取设备上所有应用程序提供的 FormInfo 对象。** |
| **getFormsInfo**(bundleName: string, moduleName?: string): Promise<Array<formInfo.FormInfo>>; | **ohos.permission.GET\_BUNDLE\_INFO\_PRIVILEGED** | **获取设备上指定应用程序提供的FormInfo对象。** |
| **deleteInvalidForms**(formIds: Array<string>**): Promise**<number>**;** | **ohos.permission.REQUIRE\_FORM** | **根据卡片ID数组删除卡片管理服务中的无效卡片。** |
| **acquireFormState**(want: Want): Promise<formInfo.FormStateInfo>; | **ohos.permission.GET\_BUNDLE\_INFO ohos.permission.GET\_BUNDLE\_INFO\_PRIVILEGED** | **获取卡片状态。** |
| **on**(type: "formUninstall", callback: Callback<string>**): void;** | **/** | **监听卡片卸载事件。** |
| **off**(type: "formUninstall", callback?: Callback<string>**): void;** | **/** | **取消监听卡片卸载事件。** |
| **notifyFormsVisible**(formIds: Array<string>**, isVisible: boolean): Promise**<void>**;** | **ohos.permission.REQUIRE\_FORM** | **通知卡片可见。可以使用此方法通知卡片可见状态。** |
| **notifyFormsEnableUpdate**(formIds: Array<string>**, isEnableUpdate: boolean): Promise**<void>**;** | **ohos.permission.REQUIRE\_FORM** | **通知卡片启用更新状态。可以使用此方法通知卡片启用更新状态。** |
#### FormInfo
**卡片信息**
**系统能力**:SystemCapability.Ability.Form
| **名称** | **读写属性** | **类型** | **描述** |
| ----------------------------- | ------------------ | ---------------------------------------------------------------------------------------- | ---------------------------------------- |
| **bundleName** | **只读** | **string** | **表示卡片所属包的包名。** |
| **moduleName** | **只读** | **string** | **表示卡片所属模块的模块名。** |
| **abilityName** | **只读** | **string** | **表示卡片所属的Ability名称。** |
| **name** | **只读** | **string** | **表示卡片名称。** |
| **description** | **只读** | **string** | **表示卡片描述。** |
| **type** | **只读** | [FormType](
https://laval.csdn.net/6480409d0 ... ype?login=from_csdn
) | **表示卡片类型,当前支持JS卡片。** |
| **jsComponentName** | **只读** | **string** | **表示js卡片的组件名。** |
| **colorMode** | **只读** | [ColorMode](
https://laval.csdn.net/6480409d0 ... ode?login=from_csdn
) | **表示卡片颜色模式。** |
| **isDefault** | **只读** | **boolean** | **表示是否是默认卡片。** |
| **updateEnabled** | **只读** | **boolean** | **表示卡片是否使能更新。** |
| **formVisibleNotify** | **只读** | **string** | **表示卡片是否使能可见通知。** |
| **relatedBundleName** | **只读** | **string** | **表示卡片所属的相关联包名。** |
| **scheduledUpdateTime** | **只读** | **string** | **表示卡片更新时间。** |
| **formConfigAbility** | **只读** | **string** | **表示卡片配置ability。** |
| **updateDuration** | **只读** | **string** | **表示卡片更新周期。** |
| **defaultDimension** | **只读** | **number** | **表示卡片规格** |
| **supportDimensions** | **只读** | **Array**<**number**> | **表示卡片支持的规格。** |
| **customizeData** | **只读** | **{[key: string]: [value: string]}** | **表示卡片用户数据。** |
##### FormType
**枚举,支持的卡片类型。**
**系统能力**:SystemCapability.Ability.Form
**SystemCapability.Ability.Form**
| **名称** | **值** | **说明** |
| -------------- | ------------ | ------------------------ |
| **JS** | **1** | **卡片类型为JS。** |
##### ColorMode
**枚举,卡片支持的颜色模式。**
**系统能力**:SystemCapability.Ability.Form
**SystemCapability.Ability.Form**
| **名称** | **值** | **说明** |
| --------------------- | ------------ | -------------------- |
| **MODE\_AUTO** | **-1** | **自动模式。** |
| **MODE\_DARK** | **0** | **暗色。** |
| **MODE\_LIGHT** | **1** | **亮色。** |
##### FormStateInfo
**卡片状态信息。**
**系统能力**:SystemCapability.Ability.Form
**SystemCapability.Ability.Form**
| **名称** | **读写属性** | **类型** | **描述** |
| ------------------- | ------------------ | ---------------------------------------------------------------------------------------- | ------------------------ |
| **formState** | **只读** | [FormState](
https://laval.csdn.net/6480409d0 ... ate?login=from_csdn
) | **表示卡片状态。** |
| **want** | **只读** | **Want** | **Want文本内容。** |
##### FormState
**枚举,卡片状态。**
**系统能力**:SystemCapability.Ability.Form
**SystemCapability.Ability.Form**
| **名称** | **值** | **说明** |
| ----------------- | ------------ | -------------------- |
| **UNKNOWN** | **-1** | **未知状态。** |
| **DEFAULT** | **0** | **默认状态。** |
| **READY** | **1** | **就绪状态。** |
##### FormParam
**枚举,卡片参数。**
**系统能力**:SystemCapability.Ability.Form
**SystemCapability.Ability.Form**
| **名称** | **值** | **说明** |
| --------------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------ |
| **IDENTITY\_KEY** | **"ohos.extra.param.key.form\_identity"** | **卡片标识。** **系统API**: 此接口为系统接口,三方应用不支持调用。 |
| **DIMENSION\_KEY** | **"ohos.extra.param.key.form\_dimension"** | **卡片规格样式。** |
| **NAME\_KEY** | **"ohos.extra.param.key.form\_name"** | **卡片名称。** |
| **MODULE\_NAME\_KEY** | **"ohos.extra.param.key.module\_name"** | **卡片所属模块名称。** |
| **WIDTH\_KEY** | **"ohos.extra.param.key.form\_width"** | **卡片宽度。** |
| **HEIGHT\_KEY** | **"ohos.extra.param.key.form\_height"** | **卡片高度。** |
| **TEMPORARY\_KEY** | **"ohos.extra.param.key.form\_temporary"** | **临时卡片。** |
### 卡片使用方
**卡片服务方主要负责卡片的展示,通过FormComponent组件来展示卡片信息。**
#### FormComponent
```
interface FormComponentInterface {
(value: {
id: number; //卡片id
name: string; //卡片名称
bundle: string; //卡片提供方的bundle名
ability: string; //卡片提供方的ability名
module: string; //卡片提供方的module名
dimension ? : FormDimension; //卡片支持的尺寸
temporary ? : boolean; //当前卡片实例是否是临时卡片
}): FormComponentAttribute;
}
declare class FormComponentAttribute extends CommonMethod < FormComponentAttribute > {
//设置卡片的宽高大小
size(value: { width: number;height: number }): FormComponentAttribute;
//获取卡片的moduleName
moduleName(value: string): FormComponentAttribute;
//获取卡片的尺寸
dimension(value: FormDimension): FormComponentAttribute;
//卡片是否允许更新
allowUpdate(value: boolean): FormComponentAttribute;
//卡片是否可见
visibility(value: Visibility): FormComponentAttribute;
//当卡片的信息获取完善后,会触发此方法,返回卡片id
onAcquired(callback: (info: { id: number }) => void): FormComponentAttribute;
//加载卡片报错时调用
onError(callback: (info: { errcode: number;msg: string }) => void): FormComponentAttribute;
//卡片重定向时调用
onRouter(callback: (info: any) => void): FormComponentAttribute;
//卸载卡片时调用
onUninstall(callback: (info: { id: number }) => void): FormComponentAttribute;
}
```
**代码示例:**
```
FormComponent({
id: formItem.cardId,
name: formItem.cardName,
bundle: formItem.bundleName,
ability: formItem.abilityName,
module: formItem.moduleName,
dimension: dimensionItem,
})
.clip(new Rect({
width: this.mFormComponentWidth[dimensionItem - 1],
height: this.mFormComponentHeight[dimensionItem - 1],
radius: 24
}))
.size({
width: this.mFormComponentWidth[dimensionItem - 1],
height: this.mFormComponentHeight[dimensionItem - 1]
})
.allowUpdate(this.allowUpdate)
.visibility(Visibility.Visible)
.onAcquired((form) => {
Log.showInfo(TAG, `Form : ${JSON.stringify(form)}`);
Log.showInfo(TAG, `FormComponent card id is: ${form.id}`);
this.mFormIdList.push(form.id);
})
.onError((error) => {
Log.showInfo(TAG, `FormComponent error msg: ${error.msg}`);
})
```
## 参考文献
**[1]OpenHarmony Stage卡片开发指导.**[
https://gitee.com/openharmony/do ... ge-formextension.md
](
https://gitee.com/openharmony/do ... .md?login=from_csdn
)
**[2]OpenHarmony FA卡片开发指导.**[
https://gitee.com/openharmony/do ... y/fa-formability.md
](
https://gitee.com/openharmony/do ... .md?login=from_csdn
)
[/md]
欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/)
Powered by Discuz! X3.5