ArkTS卡片主动刷新
===========

本文主要提供主动刷新的开发指导，刷新流程请参考[主动刷新概述](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-ui-widget-interaction-overview#主动刷新)。

#### 卡片提供方主动刷新卡片内容

卡片提供方可以通过[updateForm](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-app-form-formprovider#formproviderupdateform)接口进行主动刷新。推荐与卡片生命周期回调[onFormEvent](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-app-form-formextensionability#formextensionabilityonformevent)、[onUpdateForm](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-app-form-formextensionability#formextensionabilityonupdateform)、[onAddForm](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-app-form-formextensionability#formextensionabilityonaddform)接口搭配使用。

#### \[h2\]开发步骤

下面给出一个示例，实现如下功能：卡片添加至桌面后，点击卡片上的刷新按钮，刷新卡片信息。

1.  [创建卡片](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-ui-widget-creation)。
    
2.  实现卡片布局，在卡片上添加一个刷新按钮，点击按钮后通过[postCardAction](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-postcardaction#postcardaction-1)接口，触发onFormEvent回调。
    
    // entry/src/main/ets/updatebymessage/pages/UpdateByMessageCard.ets
    let storageUpdateByMsg = new LocalStorage();
    
    @Entry(storageUpdateByMsg)
    @Component
    struct UpdateByMessageCard {
      // $r('app.string.default\_title')和$r('app.string.DescriptionDefault')需要替换为开发者所需的资源文件
      @LocalStorageProp('title') title: ResourceStr = $r('app.string.default\_title');
      @LocalStorageProp('detail') detail: ResourceStr = $r('app.string.DescriptionDefault');
    
      build() {
        Column() {
          Column() {
            Text(this.title)
              .fontColor('#FFFFFF')
              .opacity(0.9)
              .fontSize(14)
              .margin({ top: '8%', left: '10%' })
            Text(this.detail)
              .fontColor('#FFFFFF')
              .opacity(0.6)
              .fontSize(12)
              .margin({ top: '5%', left: '10%' })
          }.width('100%').height('50%')
          .alignItems(HorizontalAlign.Start)
    
          Row() {
            // ...
            Button() {
              // $r('app.string.update')需要替换为开发者所需的资源文件
              Text($r('app.string.update'))
                .fontColor('#45A6F4')
                .fontSize(12)
            }
            .width(120)
            .height(32)
            .margin({ top: '30%', bottom: '10%' })
            .backgroundColor('#FFFFFF')
            .borderRadius(16)
            .onClick(() => {
              postCardAction(this, {
                action: 'message',
                params: { msgTest: 'messageEvent' }
              });
            })
          }.width('100%').height('40%')
          .justifyContent(FlexAlign.Center)
        }
        .width('100%')
        .height('100%')
        .alignItems(HorizontalAlign.Start)
        // $r('app.media.CardEvent')需要替换为开发者所需的资源文件
        .backgroundImage($r('app.media.CardEvent'))
        .backgroundImageSize(ImageSize.Cover)
      }
    }
    
3.  在onFormEvent回调函数的实现中，通过updateForm接口刷新卡片数据。
    
    // entry/src/main/ets/entryformability/EntryFormAbility.ts
    import { formBindingData, FormExtensionAbility, formInfo, formProvider } from '@kit.FormKit';
    import { Configuration, Want } from '@kit.AbilityKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    import { hilog } from '@kit.PerformanceAnalysisKit';
    
    
    // entry/src/main/ets/entryformability/EntryFormAbility.ts
    const TAG: string = 'EntryFormAbility';
    const DOMAIN\_NUMBER: number = 0xFF00;
    
    export default class EntryFormAbility extends FormExtensionAbility {
      onAddForm(want: Want): formBindingData.FormBindingData {
        hilog.info(DOMAIN\_NUMBER, TAG, '\[EntryFormAbility\] onAddForm');
        hilog.info(DOMAIN\_NUMBER, TAG, want.parameters?.\[formInfo.FormParam.NAME\_KEY\] as string);
        // 卡片使用方创建卡片时触发，卡片提供方需要返回卡片数据绑定类
        let obj: Record<string, string> = {
          'title': 'titleOnAddForm',
          'detail': 'detailOnAddForm'
        };
        let formData: formBindingData.FormBindingData = formBindingData.createFormBindingData(obj);
        return formData;
      }
    
      onCastToNormalForm(formId: string): void {
        // ...
        hilog.info(DOMAIN\_NUMBER, TAG, '\[EntryFormAbility\] onCastToNormalForm');
      }
    
      onUpdateForm(formId: string): void {
        // 若卡片支持定时更新/定点更新/卡片使用方主动请求更新功能，则提供方需要重写该方法以支持数据更新
        hilog.info(DOMAIN\_NUMBER, TAG, '\[EntryFormAbility\] onUpdateForm');
        let obj: Record<string, string> = {
          'title': 'titleOnUpdateForm',
          'detail': 'detailOnUpdateForm'
        };
        let formData: formBindingData.FormBindingData = formBindingData.createFormBindingData(obj);
        formProvider.updateForm(formId, formData).catch((error: BusinessError) => {
          hilog.info(DOMAIN\_NUMBER, TAG, '\[EntryFormAbility\] updateForm, error:' + JSON.stringify(error));
        });
      }
    
      onChangeFormVisibility(newStatus: Record<string, number>): void {
        // ...
        hilog.info(DOMAIN\_NUMBER, TAG, '\[EntryFormAbility\] onChangeFormVisibility');
      }
    
      onFormEvent(formId: string, message: string): void {
        // 若卡片支持触发事件，则需要重写该方法并实现对事件的触发
        hilog.info(DOMAIN\_NUMBER, TAG, \`FormAbility onFormEvent, formId = ${formId}, message: ${message}\`);
        class FormDataClass {
          title: string = 'Title Update.'; // 和卡片布局中对应
          detail: string = 'Description update success.'; // 和卡片布局中对应
        }
    
        // 请根据业务替换为实际刷新的卡片数据
        let formData = new FormDataClass();
        let formInfo: formBindingData.FormBindingData = formBindingData.createFormBindingData(formData);
        formProvider.updateForm(formId, formInfo).then(() => {
          hilog.info(DOMAIN\_NUMBER, TAG, 'FormAbility updateForm success.');
        }).catch((error: BusinessError) => {
          hilog.error(DOMAIN\_NUMBER, TAG, \`Operation updateForm failed. Cause: ${JSON.stringify(error)}\`);
        });
      }
    
      onRemoveForm(formId: string): void {
        // ...
        hilog.info(DOMAIN\_NUMBER, TAG, '\[EntryFormAbility\] onRemoveForm');
        // ...
      }
    
      onConfigurationUpdate(config: Configuration) {
        // ...
        hilog.info(DOMAIN\_NUMBER, TAG, '\[EntryFormAbility\] onConfigurationUpdate:' + JSON.stringify(config));
      }
    
    
      onAcquireFormState(want: Want): formInfo.FormState {
        // ...
        return formInfo.FormState.READY;
      }
    
    }
    
4.  资源文件如下。
    
    // entry/src/main/resources/zh\_CN/element/string.json
    {
       "string": \[
       // ...
         {
           "name": "default\_title",
           "value": "Title default."
         },
         {
           "name": "DescriptionDefault",
           "value": "Description default."
         },
         {
           "name": "update",
           "value": "刷新"
         }
       \]
    }
    

#### \[h2\]运行结果

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/9c/v3/hWdrz1rOSDijlVrD-Q8MSw/zh-cn_image_0000002625108031.gif?HW-CC-KV=V1&HW-CC-Date=20260612T073341Z&HW-CC-Expire=86400&HW-CC-Sign=BC0A2172A2920FFD294341005E4026625D6AD9A321E334A8E4A857560417FAB3)

#### 卡片提供方批量请求刷新卡片内容

从API version 22开始，支持卡片提供方批量请求刷新卡片内容。卡片提供方可以通过[reloadForms](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-app-form-formprovider#formproviderreloadforms22)和[reloadAllForms](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-app-form-formprovider#formproviderreloadallforms22)接口在应用主进程中通知FormExtension进程进行批量更新，仅支持在[UIAbility](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-app-ability-uiability)中调用。

#### \[h2\]开发步骤

下面给出一个示例，实现如下功能：添加应用的多张卡片至桌面后，点击应用UIAbility中的刷新按钮，批量刷新卡片信息。

1.  [创建卡片](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-ui-widget-creation)。
    
2.  实现卡片布局，在卡片上创建两个待刷新的Text。
    
    // entry/src/main/ets/reloadbyuiability/pages/ReloadByUIAbilityCard.ets
    let storageReloadForm = new LocalStorage();
    
    @Entry(storageReloadForm)
    @Component
    struct ReloadByUIAbilityCard {
      // 创建两个待刷新的Text，Text初始内容分别为'Title default'、'Description default'。资源文件定义请参见下方步骤5
      @LocalStorageProp('title') title: ResourceStr = $r('app.string.default\_title');
      @LocalStorageProp('detail') detail: ResourceStr = $r('app.string.DescriptionDefault');
    
      build() {
        Column() {
          Column() {
            Text(this.title)
              .fontSize(14)
              .margin({ top: '8%', left: '10%' })
            Text(this.detail)
              .fontSize(12)
              .margin({ top: '5%', left: '10%' })
          }.width('100%').height('50%')
          .alignItems(HorizontalAlign.Start)
        }
        .width('100%')
        .height('100%')
        .alignItems(HorizontalAlign.Start)
      }
    }
    
3.  在FormExtensionAbility中实现onUpdateForm回调，通过updateForm接口定义卡片刷新逻辑。
    
    // entry/src/main/ets/entryformability/EntryFormAbility.ets
    import { formBindingData, FormExtensionAbility, formInfo, formProvider } from '@kit.FormKit';
    import { Want } from '@kit.AbilityKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    import { hilog } from '@kit.PerformanceAnalysisKit';
    
    const TAG: string = 'EntryFormAbility';
    const DOMAIN\_NUMBER: number = 0xFF00;
    
    export default class EntryFormAbility extends FormExtensionAbility {
      onAddForm(want: Want) {
        const formData = '';
        return formBindingData.createFormBindingData(formData);
      }
    
      onCastToNormalForm(formId: string): void {
        hilog.info(DOMAIN\_NUMBER, TAG, '\[EntryFormAbility\] onCastToNormalForm');
      }
    
      onUpdateForm(formId: string) {
    
        class FormDataClass {
          title: string = 'Title: ' + Math.random();
          detail: string = 'Description: ' + Math.random();
        }
    
        let formData = new FormDataClass();
        let formInfo: formBindingData.FormBindingData = formBindingData.createFormBindingData(formData);
        formProvider.updateForm(formId, formInfo).then(() => {
          hilog.info(DOMAIN\_NUMBER, TAG, 'FormAbility updateForm success.');
        }).catch((error: BusinessError) => {
          hilog.error(DOMAIN\_NUMBER, TAG, \`Operation updateForm failed. code: ${error.code}, message: ${error.message}\`);
        });
      }
    
      onFormEvent(formId: string, message: string) {
        hilog.info(DOMAIN\_NUMBER, TAG, '\[EntryFormAbility\] onFormEvent');
      }
    
      onRemoveForm(formId: string) {
        hilog.info(DOMAIN\_NUMBER, TAG, '\[EntryFormAbility\] onRemoveForm');
      }
    
      onAcquireFormState(want: Want) {
        hilog.info(DOMAIN\_NUMBER, TAG, '\[EntryFormAbility\] onAcquireFormState');
        return formInfo.FormState.READY;
      }
    }
    
4.  在UIAbility的界面中添加两个批量刷新按钮，点击按钮后通过reloadForms或reloadAllForms接口，批量触发FormExtensionAbility中的onUpdateForm回调。
    
    // entry/src/main/ets/pages/index.ets
    import { common } from '@kit.AbilityKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    import { formProvider } from '@kit.FormKit';
    
    @Entry
    @Component
    struct Index {
      build() {
        Column({ space: 20 }) {
          Button('reloadForms')
            .onClick(() => {
              try {
                let context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
                let moduleName: string = 'entry';
                let abilityName: string = 'EntryFormAbility';
                let formName: string = 'reloadByUIAbilityCard';
                formProvider.reloadForms(context, moduleName, abilityName, formName).then((reloadNum: number) => {
                  console.info(\`reloadForms success, reload number: ${reloadNum}\`);
                }).catch((error: BusinessError) => {
                  console.error(\`promise error, code: ${error.code}, message: ${error.message})\`);
                });
              } catch (error) {
                console.error(\`catch error, code: ${(error as BusinessError).code}, message: ${(error as BusinessError).message})\`);
              }
            })
          Button('reloadAllForms')
            .onClick(() => {
              try {
                let context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext;
                formProvider.reloadAllForms(context).then((reloadNum: number) => {
                  console.info(\`reloadAllForms success, reload number: ${reloadNum}\`);
                }).catch((error: BusinessError) => {
                  console.error(\`promise error, code: ${error.code}, message: ${error.message})\`);
                });
              } catch (error) {
                console.error(\`catch error, code: ${(error as BusinessError).code}, message: ${(error as BusinessError).message})\`);
              }
            })
        }
        .height('100%')
        .width('100%')
        .justifyContent(FlexAlign.Center)
      }
    }
    
5.  资源文件如下。
    
    // entry/src/main/resources/base/element/string.json
    {
       "string": \[
       // ...
         {
           "name": "default\_title",
           "value": "Title default."
         },
         {
           "name": "DescriptionDefault",
           "value": "Description default."
         }
       \]
    }
    

#### \[h2\]运行结果

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/59/v3/_X36kkulSiSlCLuh4S-W5g/zh-cn_image_0000002594668514.gif?HW-CC-KV=V1&HW-CC-Date=20260612T073341Z&HW-CC-Expire=86400&HW-CC-Sign=0A9C703619975C5C312D70A76D2407AAE458F629CF30DA2985467DBD8C2AF4FE)