HarmonyOS鸿蒙Next中在桌面移除卡片之后卡片的onRemoveForm钩子为什么没触发

HarmonyOS鸿蒙Next中在桌面移除卡片之后卡片的onRemoveForm钩子为什么没触发?

5 回复

已经解决了

更多关于HarmonyOS鸿蒙Next中在桌面移除卡片之后卡片的onRemoveForm钩子为什么没触发的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


楼主是怎么解决的?

楼主代码是怎么写的?我使用这个文档上的代码(主应用如何获取卡片列表中某个卡片添加/移除)移除卡片时可以正常触发onRemoveForm的。

楼主是使用IDE查看onRemoveForm中的日志没有输出吗?是不是没有选择到对应的卡片应用日志面板?onRemoveForm是卡片的生命周期,日志是在对应的卡片应用日志面板下输出的。

demo如下:

import { formBindingData, FormExtensionAbility, formInfo } from '@kit.FormKit';
import { Want } from '@kit.AbilityKit';
import { PreferencesHelper } from '../pages/PreferencesHelper';
import { commonEventManager } from '@kit.BasicServicesKit';

export default class EntryFormAbility extends FormExtensionAbility {
  onAddForm(want: Want) {
    let ctx = this.context.getApplicationContext()
    let formList: Array<string> = PreferencesHelper.getInstance(ctx).get('formList', []) as Array<string>
    if (want.parameters) {
      let formId = (want.parameters['ohos.extra.param.key.form_identity']) as string
      if (!formList.includes(formId)) {
        formList.push(formId)
      }
      PreferencesHelper.getInstance(ctx).put('formList', formList)
    }
    const formData = '';
    return formBindingData.createFormBindingData(formData);
  }
  onCastToNormalForm(formId: string) {
    // Called when the form provider is notified that a temporary form is successfully
    // converted to a normal form.
  }

  onUpdateForm(formId: string) {
    // Called to notify the form provider to update a specified form.
  }

  onFormEvent(formId: string, message: string) {
    // Called when a specified message event defined by the form provider is triggered.
  }

  onRemoveForm(formId: string) {
    let ctx = this.context.getApplicationContext()
    let formList: Array<string> = PreferencesHelper.getInstance(ctx).get('formList', []) as Array<string>
    formList = formList.filter(item => item !== formId)
    PreferencesHelper.getInstance(ctx).put('formList', formList)
    // bundleName表示订阅者包名称,只有包名为bundleName的订阅者才能收到该公共事件
    commonEventManager.publish('delCard', { data: formId, bundleName: 'xxx' }, err => {
      if (err) {
        console.info('onRemoveForm publish fail, err:' + err)
      }
      console.info('onRemoveForm publish success')
    })
  }

  onAcquireFormState(want: Want) {
    // Called to return a {@link FormState} object.
    return formInfo.FormState.READY;
  }
}
import { preferences } from '@kit.ArkData'

export class PreferencesHelper {
  private static instance: PreferencesHelper | null = null
  private preferences: preferences.Preferences | null = null
  private constructor() {
  }

  public static getInstance(ctx: Context) {
    if (PreferencesHelper.instance === null) {
      PreferencesHelper.instance = new PreferencesHelper()
    }
    PreferencesHelper.instance.init(ctx)
    return PreferencesHelper.instance
  }

  // 初始化首选项
  private init(ctx: Context) {
    if (this.preferences === null) {
      this.preferences = preferences.getPreferencesSync(ctx, { name: 'preferences' })
    }
  }

  // 从缓存的Preferences实例中获取键对应的值
  public get(key: string, defaultValue: preferences.ValueType) {
    if (!this.preferences) {
      return
    }
    return this.preferences.getSync(key, defaultValue)
  }

  // 将数据写入缓存的Preferences实例中,可通过flush将Preferences实例持久化
  put(key: string, defaultValue: preferences.ValueType) {
    if (!this.preferences) {
      return
    }
    this.preferences.putSync(key, defaultValue)
    this.preferences.flushSync()
  }

  clear() {
    PreferencesHelper.instance = null
    this.preferences = null
  }
}

在HarmonyOS Next中,当用户从桌面移除卡片时,系统会直接销毁卡片实例,不会触发onRemoveForm生命周期回调。这是系统设计的默认行为,旨在快速释放资源。若需执行清理操作,建议在onDestroy()回调中处理,该回调在卡片销毁时会被调用。

在HarmonyOS Next中,当从桌面移除卡片时,onRemoveForm钩子未触发通常与以下原因相关:

  1. 卡片生命周期管理问题

    • 确保卡片在formProvider中正确注册了生命周期回调。若卡片未正确绑定或配置,系统可能无法调用onRemoveForm
    • 检查卡片的form_config.json配置,确认isDynamicupdateEnabled等属性是否与移除行为冲突。
  2. 移除方式的影响

    • 若用户通过“移除”操作(非拖动到垃圾桶)删除卡片,部分场景下系统可能直接销毁卡片实例,跳过onRemoveForm。建议测试不同移除方式(如长按移除、设置中禁用)是否均存在问题。
  3. API版本与系统兼容性

    • 确认HarmonyOS Next的SDK版本与卡片开发时使用的API版本匹配。低版本API可能在事件回调机制上存在差异。
  4. 卡片状态异常

    • 若卡片处于异常状态(如持久化数据损坏、资源未释放),系统可能静默处理移除操作,导致回调未触发。可通过日志检查卡片移除前是否有错误抛出。

建议通过DevEco Studio的日志系统(HiLog)跟踪卡片生命周期,验证移除操作时系统是否调用了相关回调。若问题持续,需排查卡片代码中是否存在阻塞主线程或未处理异常的行为。

回到顶部