HarmonyOS FormExtensionAbility(卡片扩展能力)使用指南

摘要:本文详细介绍 HarmonyOS FormExtensionAbility 的概念、生命周期、核心回调方法,以及如何通过该扩展能力实现桌面卡片的创建、更新和销毁管理。配合完整代码示例,帮助开发者快速上手应用卡片开发。


效果

一、概念概述

FormExtensionAbility 是 HarmonyOS 应用卡片的核心扩展能力,属于 @kit.FormKit。它作为卡片的服务端运行环境,负责管理卡片的完整生命周期,包括创建、更新、销毁等操作。

1.1 架构定位

┌─────────────────────────────────────────────┐
│                  桌面(Launcher)              │
│  ┌─────────────┐  ┌─────────────┐           │
│  │ 卡片 UI     │  │ 卡片 UI     │           │
│  │ (Widget)    │  │ (Widget)    │           │
│  └──────┬──────┘  └──────┬──────┘           │
└─────────┼────────────────┼──────────────────┘
          │  formBindingData  │
┌─────────┼────────────────┼──────────────────┐
│         ▼                ▼                  │
│  FormExtensionAbility(卡片服务端)           │
│  ├── onAddForm()     → 卡片创建              │
│  ├── onUpdateForm()  → 卡片更新              │
│  ├── onCastToNormalForm() → 临时转常态       │
│  ├── onRemoveForm()  → 卡片销毁              │
│  └── onAcquireFormState() → 查询状态         │
└─────────────────────────────────────────────┘

1.2 模块归属

属性
模块名 @ohos.app.form.FormExtensionAbility
Kit @kit.FormKit
引入方式 import { FormExtensionAbility } from '@kit.FormKit'

二、生命周期与回调方法

2.1 生命周期流程

用户添加卡片
    ↓
onAddForm(want)          ← 创建卡片,返回初始数据
    ↓
卡片在桌面显示
    ↓
onUpdateForm(formId)     ← 定时更新 / 手动触发
    ↓
onCastToNormalForm(formId) ← 临时卡片转正
    ↓
用户移除卡片
    ↓
onRemoveForm(formId)     ← 清理资源

2.2 核心回调方法

方法 触发时机 返回值
onAddForm(want) 用户添加卡片时 FormBindingData
onUpdateForm(formId) 定时更新或主动更新时 void
onCastToNormalForm(formId) 临时卡片转为常态卡片时 void
onRemoveForm(formId) 用户移除卡片时 void
onFormEvent(formId, message) 卡片触发消息事件时 void
onAcquireFormState(want) 查询卡片状态时 FormState

三、项目配置

3.1 创建 FormExtensionAbility

entry/src/main/ets/entryformability/ 目录下创建 EntryFormAbility.ets

import { formBindingData, FormExtensionAbility, formInfo } from '@kit.FormKit';
import { Want } from '@kit.AbilityKit';

export default class EntryFormAbility extends FormExtensionAbility {
  onAddForm(want: Want): formBindingData.FormBindingData {
    console.info('onAddForm called');

    // 从 want 中获取卡片信息
    let formId = want.parameters?.['ohos.extra.param.key.form_identity'] as string;
    let formName = want.parameters?.['ohos.extra.param.key.form_name'] as string;
    let formDimension = want.parameters?.['ohos.extra.param.key.form_dimension'] as string;

    console.info(`formId: ${formId}, formName: ${formName}, dimension: ${formDimension}`);

    // 构造卡片初始数据
    let formData = {
      formId: formId,
      title: '我的卡片',
      content: '欢迎使用应用卡片'
    };

    return formBindingData.createFormBindingData(formData);
  }

  onUpdateForm(formId: string): void {
    console.info(`onUpdateForm: ${formId}`);
    // 可在此处获取最新数据并更新卡片
  }

  onCastToNormalForm(formId: string): void {
    console.info(`onCastToNormalForm: ${formId}`);
  }

  async onRemoveForm(formId: string): Promise<void> {
    console.info(`onRemoveForm: ${formId}`);
    // 清理该卡片相关的资源
  }

  onFormEvent(formId: string, message: string): void {
    console.info(`onFormEvent: ${formId}, message: ${message}`);
  }

  onAcquireFormState(want: Want): formInfo.FormState {
    return formInfo.FormState.READY;
  }
}

3.2 配置 module.json5

module.json5extensionAbilities 中注册 FormExtensionAbility

{
  "module": {
    "extensionAbilities": [
      {
        "name": "EntryFormAbility",
        "srcEntry": "./ets/entryformability/EntryFormAbility.ets",
        "label": "$string:EntryFormAbility_label",
        "description": "$string:EntryFormAbility_desc",
        "type": "form",
        "metadata": [
          {
            "name": "ohos.extension.form",
            "resource": "$profile:form_config"
          }
        ]
      }
    ]
  }
}

3.3 配置 form_config.json

entry/src/main/resources/base/profile/form_config.json 中定义卡片:

{
  "forms": [
    {
      "name": "MyWidget",
      "displayName": "$string:MyWidget_display_name",
      "description": "$string:MyWidget_desc",
      "src": "./ets/widget/MyWidgetCard.ets",
      "uiSyntax": "arkts",
      "window": {
        "designWidth": 720,
        "autoDesignWidth": true
      },
      "colorMode": "auto",
      "isDynamic": true,
      "isDefault": true,
      "updateEnabled": false,
      "scheduledUpdateTime": "10:30",
      "updateDuration": 1,
      "defaultDimension": "2*2",
      "supportDimensions": ["2*2"]
    }
  ]
}

3.4 关键配置项说明

配置项 说明
name 卡片唯一标识名,对应 @Entry 组件名
src 卡片 UI 组件的文件路径
isDynamic 是否为动态卡片(支持实时更新)
updateEnabled 是否启用定时更新
scheduledUpdateTime 定时更新时间(HH:mm 格式)
defaultDimension 默认尺寸(2*22*44*4
supportDimensions 支持的尺寸列表

四、卡片 UI 组件开发

4.1 基础卡片组件

entry/src/main/ets/widget/MyWidgetCard.ets 中创建:

let localStorage = new LocalStorage();

@Entry(localStorage)
@Component
struct MyWidgetCard {
  @LocalStorageProp('formId') formId: string = '';
  @LocalStorageProp('title') title: string = '';
  @LocalStorageProp('content') content: string = '';

  build() {
    Column({ space: 12 }) {
      Text(this.title)
        .fontSize(16)
        .fontWeight(FontWeight.Bold)
        .fontColor('#333333')

      Text(this.content)
        .fontSize(14)
        .fontColor('#666666')
        .maxLines(3)
        .textOverflow({ overflow: TextOverflow.Ellipsis })
    }
    .width('100%')
    .height('100%')
    .padding(16)
    .backgroundColor(Color.White)
    .borderRadius(16)
  }
}

4.2 卡片组件要点

要点 说明
必须使用 @Entry(localStorage) 卡片入口需要绑定 LocalStorage
数据通过 @LocalStorageProp 获取 数据由 FormBindingData 注入到 LocalStorage
卡片不支持网络请求 数据需要从服务端通过 Preferences 传递
支持有限的事件 仅支持 postCardActionroutercallmessage 事件

4.3 注册到 main_pages.json

{
  "src": [
    "pages/Index",
    "widget/MyWidgetCard"
  ]
}

五、onAddForm 详解:根据卡片名称返回不同数据

当一个应用有多个卡片时,可以在 onAddForm 中根据 formName 返回不同的初始数据:

onAddForm(want: Want): formBindingData.FormBindingData {
  let formId = want.parameters?.['ohos.extra.param.key.form_identity'] as string;
  let formName = want.parameters?.['ohos.extra.param.key.form_name'] as string;

  if (formName === 'BatteryWidget') {
    // 电量卡片数据
    let data = {
      formId: formId,
      batteryLevel: 85,
      chargingStatus: '充电中'
    };
    return formBindingData.createFormBindingData(data);
  }

  if (formName === 'StorageWidget') {
    // 存储卡片数据
    let data = {
      formId: formId,
      usedGB: 64.5,
      totalGB: 256.0,
      usedPercent: 25
    };
    return formBindingData.createFormBindingData(data);
  }

  if (formName === 'DeviceInfoWidget') {
    // 设备信息卡片数据
    let data = {
      formId: formId,
      deviceName: 'Mate 60 Pro',
      brand: 'HUAWEI',
      batteryLevel: 85,
      usedGB: 64.5,
      totalGB: 256.0
    };
    return formBindingData.createFormBindingData(data);
  }

  return formBindingData.createFormBindingData('');
}

六、onRemoveForm 详解:清理卡片资源

当用户从桌面移除卡片时,onRemoveForm 被调用。开发者需要在此方法中清理相关资源:

import { preferences } from '@kit.ArkData';

async onRemoveForm(formId: string): Promise<void> {
  console.info(`卡片被移除: ${formId}`);

  // 从 Preferences 中移除该卡片的 formId 记录
  let prefs = preferences.getPreferencesSync(this.context, { name: 'myStore' });
  let formIdList = prefs.getSync('formIdList', []) as string[];
  let index = formIdList.indexOf(formId);
  if (index !== -1) {
    formIdList.splice(index, 1);
    prefs.putSync('formIdList', formIdList);
    prefs.flush();
  }
}

七、onAcquireFormState 详解:卡片状态查询

onAcquireFormState 用于返回卡片的当前状态:

onAcquireFormState(want: Want): formInfo.FormState {
  // FormState 枚举:
  // UNKNOWN  - 未知状态
  // READY    - 卡片就绪
  // TEMP     - 临时卡片(无数据)
  return formInfo.FormState.READY;
}
状态值 说明
UNKNOWN 未知状态
READY 卡片就绪,可以展示数据
TEMP 临时卡片,暂无数据

八、常见问题与注意事项

8.1 FormExtensionAbility 运行在哪个进程?

FormExtensionAbility 运行在应用的主进程中,与 UIAbility 共享进程。但卡片 UI(Widget)渲染在桌面进程中。

8.2 onAddForm 中可以访问网络吗?

不建议在 onAddForm 中进行耗时操作(如网络请求),因为它需要快速返回 FormBindingData。建议从 Preferences 读取已缓存的数据。

8.3 如何区分多个卡片?

通过 want.parameters['ohos.extra.param.key.form_name'] 获取卡片名称来区分不同卡片,返回对应数据。

8.4 isDynamic 和 updateEnabled 的区别?

配置项 说明
isDynamic 卡片是否支持实时更新(通过 formProvider.updateForm
updateEnabled 是否启用系统定时自动更新(onUpdateForm 被周期调用)

九、总结

知识点 内容
核心类 FormExtensionAbility(继承自 ExtensionAbility
Kit @kit.FormKit
创建卡片 onAddForm(want) 返回 FormBindingData
更新卡片 onUpdateForm(formId)
销毁卡片 onRemoveForm(formId)
数据传递 formBindingData.createFormBindingData(data)
配置文件 module.json5 + form_config.json + main_pages.json

FormExtensionAbility 是 HarmonyOS 应用卡片开发的核心基础设施,掌握其生命周期和回调方法,是实现动态卡片数据交互的关键。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐