HarmonyOS 鸿蒙Next服务卡片开发速览
HarmonyOS 鸿蒙Next服务卡片开发速览
1、创建服务卡片
服务卡片分动态和静态两种,静态卡片适合不怎么更新数据的卡片,会以图片形式在桌面呈现;动态卡片适用于数据交互比较多的卡片,一般我们用动态卡片即可。
按照步骤创建完成后主要生成三个文件 FormExtensionAbility实现类、xxWidgetCard组件、form_config配置文件,以及在module.json5中增加了extensionAbilities卡片配置
2、 卡片约束
主要两点:1、不能导入,比如用到bean需要重新写一份;2、不能写定时器
ArkTS卡片相较于JS卡片具备了更加丰富的能力,但也增加了使用卡片进行恶意行为的风险。由于ArkTS卡片显示在使用方应用中,使用方应用一般为桌面应用,为确保桌面的使用体验以及功耗相关考虑,对ArkTS卡片的能力做了以下约束:
1、当导入模块时,仅支持导入标识“支持在ArkTS卡片中使用”的模块。
2、不支持导入共享包。
3、不支持使用native语言开发。
4、仅支持声明式范式的部分组件、事件、动效、数据管理、状态管理和API能力。
卡片的事件处理和使用方的事件处理是独立的,建议在使用方支持左右滑动的场景下卡片内容不要使用左右滑动功能的组件,以防手势冲突影响交互体验。
除此之外,当前ArkTS卡片还存在如下约束:
1、暂不支持极速预览。
2、暂不支持断点调试能力。
3、暂不支持Hot Reload热重载。
4、暂不支持setTimeOut。
3、三方通信流程图
4、管理卡片Id
我们需要写一个管理类FormIdStore用来存储添加到桌面上的卡片的id,用来进行根据id向卡片推送数据,同一个卡片可以添加多次,因此要维护一个id数组。
如果创建了多种卡片,不同卡片需要的数据不同,最好分开存储,方便管理
onAddForm(want: Want) {
// Called to return a FormBindingData object.
const formId = want.parameters![formInfo.FormParam.IDENTITY_KEY] as string;
SubscriberClass.publish(PublishEventType.FORM_EVENT_ADD_FROM, formId)
FormIdStore.context = this.context
FormIdStore.addFormId(formId)
return formBindingData.createFormBindingData({
formId
});
}
5、进程通信:FormAbility->EntryAbility
onAddform需要做两件事1、保存卡片id;2、通知App向卡片推送数据,用于在长按图标添加卡片时预览弹窗中显示数据
保存卡片id可以直接通过FormIdStore首选项实现,
通知卡片推送数据有两种方案
方案1:曲线救国
在onAddForm中return formBindingData传递formId,卡片即可通过@LocalStorageProp接收数据,在上面添加@watch观察方法调用postCardAction发送call事件,在EntryAbility通过this.callee接收后,再通过formProvider向卡片推送数据
onAddForm(want: Want) {
// Called to return a FormBindingData object.
const formId = want.parameters![formInfo.FormParam.IDENTITY_KEY] as string;
SubscriberClass.publish(PublishEventType.FORM_EVENT_ADD_FROM, formId)
FormIdStore.context = this.context
FormIdStore.addFormId(formId)
return formBindingData.createFormBindingData({
formId
});
}
方案2:进程间通信
即commonEventManager,详见SubscriberClass工具类,需要再EntryAbility中订阅事件,再FormAbility中发布事件即可,无需通过卡片中转
export class SubscriberClass {
static publishCount: number = 1
static publish(eventType: PublishEventType, data: string) {
commonEventManager.publish(eventType, { data }, (err) => {
if (err) {
Logger.debug(TAG, <span class="javascript">发布事件失败:${<span class="hljs-built_in">JSON</span>.stringify(err)}</span>
)
} else {
Logger.debug(TAG, <span class="javascript">发布事件成功:${<span class="hljs-built_in">JSON</span>.stringify(err)}</span>
)
}
})
}
static subscribe(eventType: PublishEventType, subscriber: commonEventManager.CommonEventSubscriber | null,
callback: (event?: string) => void) {
let subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
events: [eventType]
};
commonEventManager.createSubscriber(subscribeInfo, (err, data) => {
if (err) {
Logger.debug(TAG, <span class="javascript">创建订阅者error ${<span class="hljs-built_in">JSON</span>.stringify(err)}</span>
)
}
Logger.debug(TAG, <span class="javascript">创建订阅者success</span>
)
subscriber = data
if (subscriber !== null) {
//订阅事件
commonEventManager.subscribe(subscriber, (err, data) => {
if (err) {
return Logger.debug(TAG, ‘订阅事件失败’)
}
Logger.debug(TAG,<span class="javascript">接受订阅事件:${data.data}</span>
)
callback(data.data)
})
} else {
Logger.debug(TAG,<span class="javascript">需要创建subscriber</span>
);
}
})
}
}
6、推送数据:App->卡片
App通过formProvider向卡片推送数据,这里注意钱包内卡信息不能在后台获取,需要启动时候获取并缓存
formProvider.updateForm(formId, formBindingData.createFormBindingData({
cardList: cardList
}))
卡片接收数据
卡片通过@LocalStorageProp接收数据
@Watch(‘makeStateList’)
@LocalStorageProp(‘cardList’)
cardList: FormCardInfo[] = [];
7、卡片事件:卡片->EntryAbility/FormAbility
卡片通过点击时调用postCardAction,这里面action分为三种 router,call,message,接收方式也有区别
postCardAction(this, {
action: ‘router’,
abilityName: ‘EntryAbility’,
params: {
targetPage: ‘MobileCard’,
formId: this.formId
}
});
1、EntryAbility接收router类型事件
router 顾名要打开页面,根据app是否开启会调用EnterAbility中的onCreate或者onNewWant我们从want中获取参数进行跳转
static doNavWithWant(want: Want) {
if (want.parameters!.params) {
let params: Record<string, Object> = JSON.parse(want.parameters!.params as string) as Record<string, Object>;
let targetPage = params.targetPage as string;
switch (targetPage) {
.…
}
}
}
2、EntryAbility接收call类型事件
app接收卡片calll类型事件,需要再EntryAbility的onCreate中添加监听
uiAbility.callee.on(“getFormId”, (data) => {
const res = JSON.parse(data.readString()) as ParamsForm
FormIdStore.addFormId(res.formId).then(() => {
FormManager.pushCardData(res.formId)
})
return new Params()
})
3、FormAbility接收message类型事件
message类型事件是卡片和FormAbility之间通信 在FormAbility中onFormEvent接收,FormAbility同样也是通过formProvider.updateForm刷新卡片
onFormEvent(formId: string, message: string): void {}
8、加载网络图片
网络图片需要按照指定配置下载到内存,按照约定格式’memory://’ + this.imgName显示
// 假设在当前卡片应用的tmp目录下有一个本地图片:head.PNG
let tempDir = this.context.getApplicationContext().tempDir;
hilog.info(DOMAIN_NUMBER, TAG, tempDir: ${tempDir}
);
let imgMap: Record<string, number> = {};
try {
// 打开本地图片并获取其打开后的fd
let file = fileIo.openSync(tempDir + ‘/’ + ‘head.PNG’);
imgMap[‘imgBear’] = file.fd;
} catch (e) {
hilog.error(DOMAIN_NUMBER, TAG, openSync failed: ${JSON.stringify(e <span class="hljs-keyword">as</span> BusinessError)}
);
}
class FormDataClass {
text: string = ‘Image: Bear’;
loaded: boolean = true;
// 卡片需要显示图片场景, 必须和下列字段formImages 中的key ‘imgBear’ 相同。
imgName: string = ‘imgBear’;
// 卡片需要显示图片场景, 必填字段(formImages 不可缺省或改名), ‘imgBear’ 对应 fd
formImages: Record<string, number> = imgMap;
}
let formData = new FormDataClass();
// 将fd封装在formData中并返回至卡片页面
return formBindingData.createFormBindingData(formData);
}
更多关于HarmonyOS 鸿蒙Next服务卡片开发速览的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS 鸿蒙Next服务卡片开发速览的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
HarmonyOS 鸿蒙Next服务卡片开发基于分布式技术,允许开发者将应用的核心功能和服务以卡片形式展现,用户无需进入应用即可快速获取所需信息。开发Next服务卡片时,需利用鸿蒙系统的Ability框架,通过特定的XML布局文件定义卡片UI,并通过TS(TypeScript)或JS(JavaScript)编写逻辑处理。
卡片类型分为静态和动态两种。静态卡片内容固定,展示应用的基础信息;动态卡片则能实时更新数据,如天气、新闻等。开发动态卡片时,需集成数据订阅与推送机制,确保卡片内容能根据后端数据变化而更新。
为提升用户体验,开发者需遵循鸿蒙系统的设计规范,确保卡片尺寸、布局、色彩等元素与系统整体风格一致。同时,还需考虑卡片在不同设备、不同屏幕尺寸下的适配性,确保卡片在各种场景下都能良好显示。
此外,开发者需利用鸿蒙系统提供的API,实现卡片间的交互与联动,提升服务的连贯性和便捷性。例如,用户可通过点击卡片中的某个按钮,快速跳转到应用内的相关页面或执行特定操作。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html