跳转到正文
YGJoon 技术博客

HarmonyOS 元服务卡片:从空生命周期到可更新的数据链路

发布于:
·1.4k 字 · 约 3 分钟·作者:
核对 ArkTS 服务卡片从 module.json5 注册、form_config 声明到 FormExtensionAbility 数据绑定与更新的完整链路。
HarmonyOS 元服务卡片:从空生命周期到可更新的数据链路文章封面
目录

类文件存在,不代表卡片已经接通

这次检查的工程里有一个 FormExtensionAbility 子类,也有 ArkTS 卡片 UI。生命周期方法大多还是空模板:创建时绑定空字符串,更新、事件和删除回调没有业务处理。更关键的是,模块清单里没有注册 type: "form" 的扩展,资源目录也没有 form_config.json。

所以现状不是“卡片已完整可用”,而是卡片 UI 与 Provider 的代码雏形已经存在,系统发现和调度所需的声明链路还缺一段。ArkTS 卡片至少要把模块注册、卡片元数据、数据绑定、更新策略和交互目标连起来。

第一步:在模块清单里注册 Provider

在 entry/src/main/module.json5 的 module 对象中补充扩展声明。名称与源码路径按自己的目录结构调整:

{
  "module": {
    "extensionAbilities": [
      {
        "name": "OverviewFormAbility",
        "srcEntry": "./ets/formability/OverviewFormAbility.ets",
        "type": "form",
        "label": "$string:overview_form_label",
        "metadata": [
          {
            "name": "ohos.extension.form",
            "resource": "$profile:form_config"
          }
        ]
      }
    ]
  }
}

metadata 将扩展与卡片资源关联起来。对应的资源文件可放在 entry/src/main/resources/base/profile/form_config.json:

{
  "forms": [
    {
      "name": "OverviewCard",
      "description": "信息摘要",
      "src": "./ets/widget/pages/OverviewCard.ets",
      "uiSyntax": "arkts",
      "isDefault": true,
      "colorMode": "auto",
      "defaultDimension": "2*2",
      "supportDimensions": ["2*2"],
      "updateEnabled": false
    }
  ]
}

上面的卡片关闭定时刷新,适合展示由应用主动更新的轻量摘要。若要使用系统定时刷新,应结合目标 API 版本核对 updateEnabled、updateDuration 和刷新频率限制;不要为了“看起来实时”而设置过密的刷新周期。

第二步:让生命周期返回稳定的数据结构

卡片 UI 声明自己需要哪些字段,Provider 就返回相同结构。这样首次创建与后续更新使用同一份数据契约,避免第一次有内容、刷新后字段消失。

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

interface OverviewData {
  title: string;
  summary: string;
}

function createOverviewData(): OverviewData {
  return {
    title: '服务概览',
    summary: '当前状态:已同步'
  };
}

export default class OverviewFormAbility extends FormExtensionAbility {
  onAddForm(want: Want): formBindingData.FormBindingData {
    const data: OverviewData = createOverviewData();
    return formBindingData.createFormBindingData(data);
  }

  onUpdateForm(formId: string): void {
    this.updateSnapshot(formId);
  }

  onFormEvent(formId: string, message: string): void {
    try {
      const payload: Record<string, Object> = JSON.parse(message) as Record<string, Object>;
      if (payload['message'] === 'refresh') {
        this.updateSnapshot(formId);
      }
    } catch (error) {
      console.error(`Invalid form event: ${JSON.stringify(error)}`);
    }
  }

  onCastToNormalForm(formId: string): void {
    // 临时卡片转为常驻卡片时,按需调整实例状态。
  }

  private updateSnapshot(formId: string): void {
    const data: OverviewData = createOverviewData();
    const binding = formBindingData.createFormBindingData(data);

    formProvider.updateForm(formId, binding).catch((error: BusinessError) => {
      console.error(`updateForm failed: ${JSON.stringify(error)}`);
    });
  }

  onRemoveForm(formId: string): void {
    // 如有按 formId 保存的实例状态,在这里清理。
  }

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

UI 侧用相同的字段名接收绑定数据,例如:

@Component
struct OverviewCard {
  @LocalStorageProp('title') title: string = '加载中';
  @LocalStorageProp('summary') summary: string = '';

  build() {
    Column() {
      Text(this.title).fontSize(16).fontWeight(FontWeight.Medium)
      Text(this.summary).fontSize(13).maxLines(2)
      Button('刷新').onClick(() => {
        postCardAction(this, {
          action: 'message',
          params: { message: 'refresh' }
        });
      })
    }
    .width('100%')
    .height('100%')
    .padding(16)
  }
}

这份代码是数据流示例:onAddForm 返回首次数据,ArkUI 用 LocalStorage 属性渲染;系统更新回调和卡片消息事件都进入同一个轻量刷新函数。onRemoveForm 则负责按 formId 清理实例状态。实际项目还要根据支持的卡片尺寸检查文本折行、图片快照和深浅色模式。

生命周期里不要跑长任务

FormExtensionAbility 不是常驻后台服务。官方生命周期说明指出,回调完成后进程最多只会短暂保留,超过约 10 秒没有新的生命周期调用就会退出。因此卡片 Provider 适合快速读取已有摘要、更新绑定或处理轻量消息;长网络请求、复杂计算和持续任务应交给正常应用流程处理,完成后再更新卡片。

按 formId 保存卡片状态时,要处理创建和删除的对称关系:onAddForm 读取创建参数并初始化状态,onRemoveForm 删除对应状态;多个卡片实例不能共享一个无区分的全局值。刷新失败也应保留上次可用内容,记录有限的错误信息,避免每次系统回调都触发昂贵的重试。

接回现有工程时的检查顺序

  1. 清单里的 extensionAbilities 名称、源码路径和 type 能对应起来。
  2. ohos.extension.form 的资源路径指向实际存在的 form_config.json。
  3. src 指向真实 ArkTS 卡片页面,且数据键与 Provider 返回对象一致。
  4. onUpdateForm 成功调用 formProvider.updateForm,错误路径也可观察。
  5. 每种尺寸和主题都能显示;移除实例后不会留下陈旧状态。
  6. 最后按目标元服务产物验证卡片的系统入口与分发限制。

工程快照中的空回调和未注册资源,使这份检查清单尤其重要:先让系统识别卡片,再谈刷新频率与业务数据。

参考资料

上一篇:HarmonyOS 元服务配置核查:atomicService 与 installationFree 的边界 · 下一篇:HarmonyOS 元服务深链路由:处理 Want 冷热启动与页面栈时序。


分享这篇文章:


相关文章

上一篇
HarmonyOS 元服务配置核查:atomicService 与 installationFree 的边界
下一篇
HarmonyOS 元服务深链路由:处理 Want 冷热启动与页面栈时序