鸿蒙卡片

遇到的问题
1、卡片环境(FormAbility)不能直接发消息给 Flutter!
2、不能用定时器
3、不能用复杂组件
4、长按点击卡片会走FormAbility的add方法,未添加会调用remove
5、使用preferences主进程和卡片进程也会有问题

import formInfo from '@ohos.app.form.formInfo';
import formProvider from '@ohos.app.form.formProvider';
import preferences from '@ohos.data.preferences';
import emitter from '@ohos.events.emitter';

// 事件ID,主应用发事件通知卡片更新
export const EVENT_REFRESH_WIDGET = 8888;
const PREF_FILE = "widget_form_ids";

export default class EntryFormAbility extends FormExtensionAbility {
  // 全局保存实例,方便内部调用
  static instance: EntryFormAbility;

  async aboutToAppear() {
    EntryFormAbility.instance = this;
    // 监听主应用发来的更新指令
    emitter.on(EVENT_REFRESH_WIDGET, async () => {
      await this.refreshAllWidgets();
    });
  }

  aboutToDisappear() {
    emitter.off(EVENT_REFRESH_WIDGET);
  }

  //==================== Preferences 持久化:formId 增删查 ====================
  private async getPref() {
    // dataGroupId 空 = 应用级共享,卡片/主应用互通
    return preferences.getPreferences(this.context, {
      name: PREF_FILE,
      dataGroupId: ""
    });
  }

  private async saveFormId(formId: string, isTemp: boolean) {
    // 临时卡片直接丢弃不保存(关键!刚添加不刷新就是这个)
    if (isTemp) return;

    const pref = await this.getPref();
    const str = await pref.getSync("formIds", "[]");
    let list: string[] = JSON.parse(str);
    if (!list.includes(formId)) {
      list.push(formId);
    }
    await pref.putSync("formIds", JSON.stringify(list));
    await pref.flush();
  }

  private async removeFormId(formId: string) {
    const pref = await this.getPref();
    const str = await pref.getSync("formIds", "[]");
    let list: string[] = JSON.parse(str);
    list = list.filter(id => id !== formId);
    await pref.putSync("formIds", JSON.stringify(list));
    await pref.flush();
  }

  public async getAllFormIds(): Promise<string[]> {
    const pref = await this.getPref();
    const str = await pref.getSync("formIds", "[]");
    return JSON.parse(str);
  }

  //==================== 卡片生命周期 ====================
  async onAddForm(want) {
    const formId = want.parameters[formInfo.FormParam.IDENTITY_KEY] as string;
    const isTemp = want.parameters[formInfo.FormParam.TEMPORARY_KEY] as boolean;
    await this.saveFormId(formId, isTemp);
  }

  // 这里拿到的是【正式可用formId】,覆盖保存
  async onUpdateForm(formId: string) {
    await this.saveFormId(formId, false);
    await this.refreshSingleWidget(formId);
  }

  async onRemoveForm(formId: string) {
    await this.removeFormId(formId);
  }

  //==================== 刷新逻辑(稳定必刷)====================
  /**
   * 刷新单个卡片
   * 加 _ts 时间戳强制系统刷新,解决新卡片不刷新
   */
  async refreshSingleWidget(formId: string) {
    const data: Record<string, Object> = {
      // 这里放你自己的业务字段
      _ts: Date.now()
    };
    try {
      await formProvider.updateForm(formId, data);
    } catch (e) {
      console.error("更新卡片失败", formId, JSON.stringify(e));
    }
  }

  /**
   * 刷新全部卡片
   */
  async refreshAllWidgets() {
    const ids = await this.getAllFormIds();
    for (const id of ids) {
      await this.refreshSingleWidget(id);
    }
  }
}
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容