抢占桌面入口,鸿蒙桌面卡片交互与高频刷新实战
·
产品经理非要给应用加个“实时待办”的桌面卡片,要求用户在主应用勾选完成后,桌面卡片上的数据必须瞬间刷新。我一开始为了省事,直接用了系统的定时刷新机制,结果被用户疯狂吐槽延迟太高。后来重构了数据更新链路,才把刷新延迟做到了毫秒级,这其中的进程隔离和跨端通信细节,值得好好复盘一下。

理解卡片进程的天然隔离
做卡片开发,最容易犯的错就是用写普通 ArkUI 页面的思维。你如果在卡片里直接写个定时器或者发网络请求,绝对会翻车。卡片是运行在系统的 FormExtensionAbility 宿主进程里的,跟主应用进程彻底隔离,且生命周期极短。它只负责渲染,绝不处理复杂逻辑。
构建主动推送机制
既然不能靠卡片自己拉数据,那就必须由主应用来“推”。但在主应用里,你根本不知道卡片的 formId 是多少。
所以,必须在卡片首次添加时,把它持久化存起来。
typescript
// 在 EntryFormAbility 中
onAddForm(want: Want) {
// 从 want 中解析出系统分配的 formId
const formId = want.parameters['ohos.extra.param.key.form_identity'] as string;
// 警示:必须将 formId 持久化,否则主应用没法跨进程通知它
saveFormIdToPrefs(formId);
return formBindingData.createFormBindingData({ text: '暂无待办' });
}
然后在主应用更新数据后,用 formProvider.updateForm 推过去。
typescript
import formProvider from '@ohos.app.form.formProvider';
import formBindingData from '@ohos.app.form.formBindingData';
async function notifyCardUpdate() {
const formId = await getFormIdFromPrefs();
if (formId) {
let formData = { text: '已完成 1 项' };
// 核心:直接通过 formId 发起跨进程更新
await formProvider.updateForm(formId, formBindingData.createFormBindingData(formData));
}
}
这段代码跑起来,卡片就能做到秒级响应了。

处理点击交互与冷启动还原
用户点击桌面卡片,必须能直接进入详情页。在卡片 UI 上,必须使用 postCardAction。
typescript
Text('查看详情')
.onClick(() => {
postCardAction(this, {
action: 'router',
abilityName: 'EntryAbility',
params: { targetPage: 'TodoDetail', id: 123 }
});
})
注意:主应用在 onCreate 或 onNewWant 收到参数后,千万别直接 router.pushUrl,因为冷启动时页面栈可能还没建好,会黑屏。必须把数据存进 AppStorage,等首页的 aboutToAppear 去消费。
综合来看,卡片开发的核心在于单向数据流。主应用管写和推,卡片管收和显,理清了进程隔离的边界,你的卡片才能成为真正的流量入口。
更多推荐

所有评论(0)