本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

卡片页面的被动刷新不需要用户点击,也不需要应用主动调用,而是由系统根据配置自动触发。

被动刷新分为两大类:

  • 定时刷新:每隔一段时间自动刷新

  • 定点刷新:每天固定时间点自动刷新

一、定时刷新

定时刷新有两种实现方式:配置定时刷新设置下次刷新时间

1.1 方式一:配置定时刷新(updateDuration)

在卡片的配置文件form_config.json中设置updateDuration字段,系统会按照固定的时间间隔自动刷新。

配置示例
{
  "forms": [
    {
      "name": "UpdateDuration",
      "description": "$string:widget_updateduration_desc",
      "src": "./ets/updateduration/pages/UpdateDurationCard.ets",
      "uiSyntax": "arkts",
      "window": {
        "designWidth": 720,
        "autoDesignWidth": true
      },
      "isDefault": true,
      "updateEnabled": true,        // 必须设置为true,启用周期性刷新
      "scheduledUpdateTime": "10:30", // 定点刷新配置(本例中不生效)
      "updateDuration": 2,           // 每2个30分钟刷新一次,即1小时
      "defaultDimension": "2×2",
      "supportDimensions": ["2×2"]
    }
  ]
}

字段说明

  • updateEnabled:必须设置为true,否则不会触发任何刷新

  • updateDuration:刷新间隔,单位为30分钟

    • 设置为2表示每60分钟刷新一次(30×2)

    • 设置为1表示每30分钟刷新一次

    • 设置为0表示不启用定时刷新

1.2 方式二:设置下次刷新时间(setFormNextRefreshTime)

除了配置固定的刷新间隔,还可以通过代码动态设置下一次刷新时间。这种方式更灵活,可以根据业务需求随时调整。

代码示例
// entry/src/main/ets/updatebytimeformability/UpdateByTimeFormAbility.ts

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

const TAG: string = 'UpdateByTimeFormAbility';
const FIVE_MINUTE: number = 5;  // 5分钟
const DOMAIN_NUMBER: number = 0xFF00;

export default class UpdateByTimeFormAbility extends FormExtensionAbility {
    
    onAddForm(want: Want): formBindingData.FormBindingData {
        // 添加卡片时返回初始数据
        let formData = {};
        return formBindingData.createFormBindingData(formData);
    }

    // 处理卡片事件
    onFormEvent(formId: string, message: string): void {
        hilog.info(DOMAIN_NUMBER, TAG, 
            `FormAbility onFormEvent, formId = ${formId}, message: ${JSON.stringify(message)}`);

        try {
            // 设置5分钟后更新卡片内容
            formProvider.setFormNextRefreshTime(formId, FIVE_MINUTE, (err: BusinessError) => {
                if (err) {
                    hilog.error(DOMAIN_NUMBER, TAG,
                        `Failed to setFormNextRefreshTime. Code: ${err.code}, message: ${err.message}`);
                    return;
                } else {
                    hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in setFormNextRefreshTiming.');
                }
            });
        } catch (err) {
            hilog.error(DOMAIN_NUMBER, TAG,
                `Failed to setFormNextRefreshTime. Code: ${(err as BusinessError).code}, 
                message: ${(err as BusinessError).message}`);
        }
    }

    onAcquireFormState(want: Want): formInfo.FormState {
        // 卡片使用方查询卡片状态时触发
        return formInfo.FormState.READY;
    }
}

接口说明

  • setFormNextRefreshTime(formId: string, minutes: number, callback: AsyncCallback<void>):设置下次刷新时间

  • minutes:距离下次刷新的分钟数,最短为5分钟

1.3 定时刷新的统一回调

无论是通过配置触发的定时刷新,还是通过setFormNextRefreshTime设置的刷新,最终都会调用FormExtensionAbilityonUpdateForm生命周期回调:

// 定时刷新触发时,系统会调用此方法
onUpdateForm(formId: string): void {
    // 在这里更新卡片数据
    let formData = formBindingData.createFormBindingData({
        'title': '定时刷新后的标题',
        'detail': `刷新时间:${new Date().toLocaleString()}`
    });
    
    formProvider.updateForm(formId, formData)
        .catch(err => console.error('更新失败', err));
}

1.4 定时刷新的约束限制

限制项 说明
每日刷新配额 每张卡片每天最多触发50次定时刷新
配额重置时间 每天0点重置
首次刷新偏差 第一次刷新最多有30分钟偏差
可见性要求 卡片可见时才触发刷新,不可见时仅记录
配额计算示例
刷新间隔 每天理论次数 是否超出配额
30分钟一次 48次 正常
20分钟一次 72次 超出
1小时一次 24次 正常

注意:实际每天最多50次,超过后当天不再触发定时刷新

首次刷新偏差说明
时间轴:3:20     3:40     3:50     4:20
卡片A添加:[定时器启动]
卡片B添加:    [添加]
定时器触发:            [触发]     [下次触发]
卡片A刷新:            ✓刷新
卡片B刷新:                       ✓刷新
  • 卡片A在3:20添加,定时器启动

  • 卡片B在3:40添加

  • 定时器在3:50触发时,只有卡片A刷新

  • 卡片B在4:20的定时器触发时才刷新

二、定点刷新

定点刷新分为单定点刷新多定点刷新,都是在每天的固定时间点自动刷新。

2.1 方式一:单定点刷新(scheduledUpdateTime)

在配置文件中设置scheduledUpdateTime字段,指定每天的刷新时间。

{
  "forms": [
    {
      "name": "ScheduledUpdateTime",
      "description": "$string:widget_scheduledUpdateTime_desc",
      "src": "./ets/scheduledupdatetime/pages/ScheduledUpdateTimeCard.ets",
      "uiSyntax": "arkts",
      "window": {
        "designWidth": 720,
        "autoDesignWidth": true
      },
      "isDefault": true,
      "updateEnabled": true,           // 必须为true
      "scheduledUpdateTime": "10:30",  // 每天10:30刷新
      "updateDuration": 0,             // 必须设为0,否则定点刷新不生效
      "defaultDimension": "2×2",
      "supportDimensions": ["2×2"]
    }
  ]
}

2.2 方式二:多定点刷新(multiScheduledUpdateTime)

从API version 18开始,支持配置多个刷新时间点。

{
  "forms": [
    {
      "name": "ScheduledUpdateTime",
      "description": "$string:widget_scheduledUpdateTime_desc",
      "src": "./ets/scheduledupdatetime/pages/ScheduledUpdateTimeCard.ets",
      "uiSyntax": "arkts",
      "window": {
        "designWidth": 720,
        "autoDesignWidth": true
      },
      "isDefault": true,
      "updateEnabled": true,
      "scheduledUpdateTime": "10:30",           // 保留字段,兼容旧版本
      "multiScheduledUpdateTime": "11:30,16:30", // 每天11:30和16:30刷新
      "updateDuration": 0,
      "defaultDimension": "2×2",
      "supportDimensions": ["2×2"]
    }
  ]
}

配置说明

  • multiScheduledUpdateTime:多个时间用英文逗号分隔

  • 最多可设置24个时间点

  • 同时配置单定点和多定点时,多定点配置生效

2.3 定点刷新的优先级规则

配置情况 生效规则
同时配置updateDurationscheduledUpdateTime 定时刷新生效,定点刷新不执行
同时配置单定点和多定点 多定点刷新生效
只配置单定点 单定点刷新生效
只配置多定点 多定点刷新生效

重要:要使用定点刷新,必须将updateDuration设置为0

2.4 定点刷新的回调

与定时刷新一样,定点刷新触发时也会调用onUpdateForm生命周期回调:

onUpdateForm(formId: string): void {
    // 定点刷新时更新卡片数据
    let formData = formBindingData.createFormBindingData({
        'title': '定点刷新',
        'detail': `刷新于 ${new Date().toLocaleString()}`
    });
    
    formProvider.updateForm(formId, formData);
}

2.5 定点刷新的约束限制

限制项 说明
可见性要求 卡片可见时才触发刷新,不可见时仅记录
时间点数量 多定点最多24个
优先级 定时刷新优先级高于定点刷新

三、被动刷新配置对比

3.1 配置字段速查表

字段 类型 说明 默认值
updateEnabled boolean 是否启用周期性刷新 -(必填)
updateDuration number 定时刷新间隔(30分钟为单位) 0
scheduledUpdateTime string 单定点刷新时间(HH:mm) -
multiScheduledUpdateTime string 多定点刷新时间(逗号分隔) -

3.2 刷新方式对比

刷新方式 配置字段 特点 适用场景
定时刷新 updateDuration 固定间隔、有配额限制 周期性数据
下次刷新 setFormNextRefreshTime 灵活设置、最短5分钟 用户操作后延迟更新
单定点刷新 scheduledUpdateTime 每天固定时间 推送类卡片、日报卡片
多定点刷新 multiScheduledUpdateTime 每天多个固定时间 上下班打卡提醒

四、完整示例:结合定时和定点刷新

4.1 配置文件

{
  "forms": [
    {
      "name": "ComboWidget",
      "src": "./ets/widget/pages/ComboWidget.ets",
      "uiSyntax": "arkts",
      "updateEnabled": true,
      "updateDuration": 2,              // 每1小时定时刷新
      "scheduledUpdateTime": "08:00",    // 保留字段(兼容旧版本)
      "multiScheduledUpdateTime": "12:00,18:00", // 中午12点和下午6点定点刷新
      "defaultDimension": "2×2",
      "supportDimensions": ["2×2", "2×4"]
    }
  ]
}

4.2 FormExtensionAbility实现

export default class ComboFormAbility extends FormExtensionAbility {
    
    onUpdateForm(formId: string): void {
        // 判断当前时间,决定刷新内容
        const now = new Date();
        const hour = now.getHours();
        
        let title = '';
        let detail = '';
        
        if (hour >= 6 && hour < 12) {
            title = '早上好';
            detail = '美好的一天开始啦';
        } else if (hour >= 12 && hour < 14) {
            title = '午间休息';
            detail = '记得吃午饭哦';
        } else if (hour >= 18 && hour < 22) {
            title = '晚上好';
            detail = '放松一下吧';
        } else {
            title = '定时刷新';
            detail = `刷新于 ${now.toLocaleString()}`;
        }
        
        let formData = formBindingData.createFormBindingData({
            'title': title,
            'detail': detail
        });
        
        formProvider.updateForm(formId, formData);
    }
    
    onFormEvent(formId: string, message: string): void {
        if (message === 'delay_refresh') {
            // 用户点击"稍后提醒"按钮,设置30分钟后刷新
            formProvider.setFormNextRefreshTime(formId, 30, (err) => {
                if (!err) {
                    console.log('设置下次刷新成功');
                }
            });
        }
    }
}

五、常见问题

1、配置了定时刷新但没有触发?

检查以下几点:

  • updateEnabled是否设置为true

  • updateDuration是否大于0

  • 当日刷新次数是否已达到50次上限

  • 卡片当前是否可见

2、定时刷新和定点刷新同时配置时哪个生效?

定时刷新优先级更高。如果想使用定点刷新,必须将updateDuration设为0。

3、多定点刷新最多能设置几个时间点?

最多24个

4、设置了下次刷新时间,但没到时间就刷新了?

可能原因:

  • 同时配置了定时刷新且间隔更短

  • 其他刷新机制(如主动刷新)触发了更新

5、卡片不可见时刷新会怎样?

系统会记录刷新动作和数据,等卡片重新可见时统一刷新布局。这样可以避免不必要的资源消耗。

总结

ArkTS卡片被动刷新提供了两种自动更新机制:

  1. 定时刷新

    • 配置updateDuration实现固定间隔刷新

    • 调用setFormNextRefreshTime实现动态设置下次刷新

    • 每天最多50次,0点重置

  2. 定点刷新

    • 配置scheduledUpdateTime实现单定点刷新

    • 配置multiScheduledUpdateTime实现多定点刷新(最多24个)

    • 定时刷新优先级高于定点刷新

核心要点

  • updateEnabled必须为true

  • 定时刷新和定点刷新都走onUpdateForm回调

  • 卡片不可见时只记录不刷新

  • 配额用完当天不再触发

Logo

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

更多推荐