写点什么

【FAQ】HarmonyOS SDK 闭源开放能力 — Form Kit

作者:HarmonyOS SDK
  • 2025-12-23
    贵州
  • 本文字数:3606 字

    阅读完需:约 12 分钟

1.问题描述:


卡片里的 Iamge 无法显示网络图片。


解决方案:


通过 FormExtensionAbility 在元服务卡片上加载网络图片有以下两种方案:


  • 方案一:先下载网络图片到本地,参考元服务卡片上加载本地图片示例代码在 EntryFormAbility 的 onAddForm 生命周期回调中实现本地文件的刷新。刷新后,在卡片页面通过 backgroundImage 属性展示 EntryFormAbility 传递过来的卡片内容。

  • 方案二:申请 ohos.permission.INTERNET 权限,创建 HTTP 请求,下载网络图片数据并保存到应用的临时文件中,在 EntryFormAbility 的 onFormEvent 生命周期回调中实现网络文件的刷新。刷新后,在卡片页面通过 backgroundImage 属性展示 EntryFormAbility 传递过来的卡片内容。使用这种方案在元服务卡片上加载网络图片示例代码详见元服务卡片上加载网络图片指南


2.问题描述:


如何在主应用中获取卡片的添加/移除?


解决方案:


一、卡片添加/移除的场景以及相关卡片生命周期由于目前卡片添加/移除至桌面目前没有直接完成的回调响应,可以通过 onAddForm 和 onRemoveForm 结合记录保存到桌面的卡片,onAddForm/onRemoveForm 添加至桌面的生命周期触发流程如下:


  1. 长按应用图标->服务卡片->打开卡片列表,触发 onAddForm (卡片列表中有几张卡片生命周期就会回调 onAddForm 几次)。例如:打开下面的卡片列表,卡片列表中有 3 张卡片,可以看到日志中 OnAddForm 回调了 3 次。

  2. 服务卡片列表取消->触发 onRemoveForm(卡片列表中有几张卡片生命周期就会回调触发 onRemoveForm 几次)。 例如:点击 x 号取消了服务卡片列表,则会出发 OnRemoveForm 回调 3 次。

  3. 服务卡片列表选择->某一张卡片添加到桌面(卡片生命周期 onAddForm 选中的卡片,onRemoveForm 其余卡片)。例如:添加一张卡片至桌面,则会 OnAddForm 选中的的卡片,OnRemove 另外两张卡片。

  4. 移除某一张卡片(卡片生命周期 onRemoveForm 移除的卡片)。例如:在桌面移除一张卡片,会 OnRemove 当前移除的卡片。综上流程,卡片整个添加至桌面的流程中,中间状态生命周期 onAddForm/onRemoveForm 会回调多次,但是最终卡片新增还是移除是确定的。


二、实现卡片添加/移除管理以及通知主应用的实现本方案使用首选项通过在服务卡片中 onAddForm/onRemoveForm 回调函数中,对 formId 进行持久化缓存,并在主应用中进行跨进程读取。以下是实现步骤:


  1. 实现一个公共的单例首选项类以供服务卡片/主应用共同使用,需要注意的是,这里首选项对于跨进程的场景下,需要使用同一个 context 上下文对象,后面在调用处均使用了 this.context.getApplicationContext()保持统一。


import { preferences } from '@kit.ArkData';
export class PreferencesHelper { private static instance: PreferencesHelper | null = null private preferences: preferences.Preferences | null = null private ctx: Context | null = null private PREFERENCE_NAME:string = "preferences"
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) { this.ctx = ctx this.preferences = preferences.getPreferencesSync(ctx, { name: this.PREFERENCE_NAME}) }
public get(key: string, defaultValue: Array<string>) { if (!this.preferences) { return } console.log("get ", defaultValue); let options: preferences.Options = { name: this.PREFERENCE_NAME }; preferences.removePreferencesFromCacheSync(this.ctx, options); return this.preferences.getSync(key, defaultValue) }
public put(key: string, defaultValue: preferences.ValueType) { if (!this.preferences) { return } console.log("put ", defaultValue); this.preferences.putSync(key, defaultValue) this.preferences.flushSync() }
public clear() { PreferencesHelper.instance = null this.preferences = null }}
复制代码


  1. 当长按应用图标拉起应用卡片列表时以及在卡片列表中选择一张服务卡片时,会触发 onAddForm,此时将卡片 id 保存下来:(注意:formlist 需要做去重)


      // 服务卡片FormExtensionAbility.ets      onAddForm(want: Want) {         console.log('onAddForm')        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          // 为了保证formId的唯一性,需要对formList去重          !formList.includes(formId) &amp;&amp; formList.push(formId)           PreferencesHelper.getInstance(ctx).put('formList', formList)        }        const formData = '';        return formBindingData.createFormBindingData(formData);      }
复制代码


  1. 服务卡片列表取消时或者在桌面移除卡片时,会触发 onRemoveForm,此时将记录里对应的数据删除,剩余的即是添加到桌面的卡片:(注意:formlist 需要做去重)


        // 服务卡片FormExtensionAbility.ets        onRemoveForm(formId: string) {          let ctx = this.context.getApplicationContext()          let formList: Array<string> = PreferencesHelper.getInstance(ctx).get('formList', []) as Array<string>          // 为了保证formId的唯一性,需要对formList去重          formList = formList.filter(item =&gt; item !== formId)           PreferencesHelper.getInstance(ctx).put('formList', formList)        }
复制代码


4.然后,在主应用中对 formId 进行查询:(注意:主应用需要和卡片使用同一个 context)


        // EntryAbility.ets        build() {          RelativeContainer() {            Text(this.message)              .id('HelloWorld')          }          .height('100%')          .width('100%')          .onClick(()=&gt;{            let formList: Array<string> =               PreferencesHelper.getInstance(this.context.getApplicationContext()).get('formList', []) as Array<string>             console.log("formList size %d", formList.length);            for (let index = 0; index &lt; formList.length; index++) {              const element = formList[index];               console.log("formId %d", element);            }          })        } 
复制代码


3.问题描述:


卡片列表如何展示网络图片?


解决方案:


  1. 卡片里面没有直接联网的权限,加载网络图片需要先将网络图片下载到本地,下载网络图片需要使用到网络能力,需要申请ohos.permission.INTERNET权限。


  let filesDir = context.getApplicationContext().filesDir  let filePath = filesDir + 'xxx.png'  request.downloadFile(context, {    url: 'xxx', // 此处为图片下载地址    filePath,  }).then((downloadTask: request.DownloadTask) =&gt; {    downloadTask.on('complete', () =&gt; {      console.log('download complete')    })  }).catch((err: BusinessError) =&gt; {    console.error(`Invoke downloadTask failed, code is ${err.code}, message is ${err.message}`);  });
复制代码


  1. EntryFormAbility 中的 onFormEvent 生命周期回调中实现网络文件的刷新。


  // 卡片需要显示图片场景,formData中formImages必填且不可改名,key值与thumb(结构和名称可自定义)的值需保持一致,值为key对应的fd
class News { thumb?: string = ''; title: string = ''; }
class FormData { list: News[] = [] formImages?: Record<string, number> = {}; }
onFormEvent(formId: string) { // 下载网络图片到本地,通过formImages let imgPath = await download(ctx) let file = fs.openSync(imgPath) let imageMap: Record<string, number> = {} imageMap[imgPath] = file.fd let res: FormData = { list: [ { title: 'new', thumb: imgPath, // 需要与formImages的key值一致 } ], formImages: imageMap } await formProvider.updateForm(formId, formBindingData.createFormBindingData(res)) fs.closeSync(file) }
复制代码


  1. 在卡片中通过 memory:// + fileName 的格式展示。


  Image('memory://' + item?.thumb)
复制代码


用户头像

HarmonyOS SDK

关注

HarmonyOS SDK 2022-06-16 加入

HarmonyOS SDK通过将HarmonyOS系统级能力对外开放,支撑开发者高效打造更纯净、更智能、更精致、更易用的鸿蒙应用,和开发者共同成长。

评论

发布
暂无评论
【FAQ】HarmonyOS SDK 闭源开放能力 — Form Kit_HarmonyOS NEXT_HarmonyOS SDK_InfoQ写作社区