关于元服务项目的创建与多线程
本文介绍了鸿蒙元服务项目中卡片的创建与数据交互流程。首先说明卡片是应用的入口,需要通过创建卡片才能访问服务。接着详细讲解了卡片开发的关键步骤:在指定目录新建ServiceWidget文件后生成卡片逻辑文件(mywidget.ts)和入口文件(EntryFormAbility.ts),其中EntryFormAbility定义了卡片属性和生命周期。重点阐述了卡片数据交互机制,包括使用formBindi
·
1. 元服务项目
刚建立的元服务项目类似一个微信小程序,它需要创建一个卡片来建立联系,通过点击卡片可以进入元服务项目。
例如,该项目只有一个HelloWorld页面,如果不建立卡片在退出该元服务项目页面并清空后台将无法再次进入该元服务项目。
2. 创建卡片
在根目录的src/main/ets下新建Service Widget下的Service Widget文件,选择完模版格式后,编译器会提供两个文件,entryformability和你自己命
名的卡片文件名 如我的文件名是mywideget,那么编译器会在这两个文件夹生成两个文件,mywidget.ts和entryformability.ts
3. EntryFormAbility文件
该文件是卡片的入口文件,里面定义了卡片的属性,比如卡片的图标,名称,描述,以及卡片的启动方式
onAddForm(want: Want){...}是卡片启动方式,当点击卡片时,会调用这个方法
用户添加卡片到桌面时,系统会创建并初始化 EntryFormAbility,执行 onAddForm 完成卡片数据绑定。
生命周期回调执行完毕后,EntryFormAbility 不会一直运行,大约 10 秒后会被系统回收销毁
<!----------------------------------------------------------------------------------->
formBindingData.createFormBindingData(formDate2)
formBindingData: 鸿蒙提供的表单数据绑定模块,可以将数据绑定到表单中。
createFormBindingData: 将普通的 JS/TS 对象 (formDate2) 转换成系统能识别的 FormBindingData 对象。
这一步是卡片运行在桌面进程,你的应用运行在应用进程,数据需要序列化打包才能跨进程传递,formDate2是普通对象,需要转换成FormBindingData对象。
return formBindingData.createFormBindingData(formData); 可以返回数据给卡片,卡片接收到数据后,会显示在卡片上。
wantParams: Record<string, Object> 是一种用于在 Ability 之间传递数据的键值对参数类型,它是 Want 对象中 parameters 属性的类型定义。
<!------------------------------------------------------------------------------------>
formProvider.updateForm(formId, bindData);
formProvider: 表单提供者模块。
updateForm: 这是真正触发桌面卡片刷新的 API。
参数:
formId: 告诉系统更新哪一张卡片。
bindData: 告诉系统用什么新数据来渲染。
结果: 执行后,用户桌面上的卡片文字会从“卡片标题 1"和“卡片内容 1"立刻变成“卡片标题 2"和“卡片内容 2"。
<!----------------------------------------------------------------------------------->
wantParams[formInfo.FormParam.IDENTITY_KEY] as string
formInfo.FormParam.IDENTITY_KEY: 这是一个系统常量(通常对应字符串 "formId")。
wantParams[...]: 从参数中取出这个 key 对应的值。
formId: 这是当前卡片实例的唯一身份证。
如果用户在桌面上添加了两个相同的卡片,它们会有不同的 formId。
你要更新哪一个卡片,就必须知道它的 formId
4. mywidget.ts文件
该文件是卡片的逻辑文件,里面定义了卡片的逻辑,比如点击卡片后跳转到新的页面,点击卡片后执行某个方法,点击卡片后显示某个弹窗等等
<!------------------------------------------------------------------------------------>
@Entry(localStorage) 将 LocalStorage 实例注入到页面根组件,使得:
当前页面内所有子组件自动获得对该 LocalStorage 实例的访问权限
无需逐层传递状态,子组件通过 @LocalStorageProp 或 @LocalStorageLink 即可绑定状态
实现跨组件状态同步,兄弟组件、父子组件可通过同一个 LocalStorage 实例通信
<!------------------------------------------------------------------------------------>
5. dataPreferences 是鸿蒙提供的 轻量级键值对(key-value)持久化存储。简单理解:一个可以跨进程访问的公共记事本。
适用场景
保存少量简单数据:formId、用户名、设置项
主应用 ↔ 卡片 之间共享数据(多进程场景)
重启 APP 数据不丢失
特点
键值对存储,简单好用
异步 API,必须用 async/await
跨进程共享(卡片 & 主应用都能读写)
持久化:存在手机本地文件
AppStorage与其不同,AppStorage是只能在同一进程下使用,卡片和主页面是两个独立进程,共享数据必须用公共存储 dataPreferences
卡片和主页面 不在同一个房间(进程隔离),卡片 = 房间 A,主页面 = 房间 B,两个房间完全隔离,不能互相看见对方的变量,AppStorage 是房间内的备忘录
只能在自己房间用,不能跨房间共享
导入模块 (EntryFormAbility与Index都要加)
import dataPreferences from '@ohos.data.preferences';
异步保存到 dataPreferences(不阻塞卡片加载)卡片中保存 formId
(async () => {
let pref = await dataPreferences.getPreferences(this.context, 'my_form_store');
await pref.put('formId', formId);
console.log('卡片保存 formId 成功:', formId);
})();
主页面读取 formId 并更新卡片
let pref = await dataPreferences.getPreferences(getContext(), 'my_form_store');
this.formId = await pref.get('formId', '') as string;
上下文 context 区别
卡片中(EntryFormAbility)使用:this.context
主页面中(Index.ets)使用:getContext()
为什么卡片保存要用 (async () => {})() 包裹
onAddForm 是同步生命周期方法,不允许加 async
包裹异步函数可以不阻塞卡片初始化,保证卡片正常显示
存储名称必须一致
保存和读取时第二个参数必须相同,如 my_form_store
名称不同会导致数据找不到,formId 读取为空
数据类型说明
dataPreferences 支持存储字符串、数字、布尔等简单类型
不支持直接存储对象,复杂数据需转为 JSON 字符串
删除某条数据:await pref.delete('formId')
清空所有数据:await pref.clear()
<!-------------------------------------------------------------------------------->
更多推荐




所有评论(0)