文章目录
-
-
- 效果图
- 项目里的 LiveForm Ability 在哪里
- 最小代码长什么样
- onLiveFormCreate 是入口
- 为什么要用 LocalStorage
- session.loadContent 的路径怎么写
- 页面必须 useSharedStorage
- module.json5 也要注册
- 从项目里学到的好习惯
- 排查清单
- 写在最后
-

普通卡片负责显示在桌面上,LiveForm Ability 负责加载展开后的互动页面。
这篇不讲复杂业务,先写一个最小版本,让小白知道 LiveFormExtensionAbility 到底干什么。
效果图
先看最终要加载出来的 LiveForm 效果。普通卡片只是入口,真正展开后的互动页面,就是由 LiveForm Ability 加载出来的。

项目里的 LiveForm Ability 在哪里
当前项目有四个:
- entry/src/main/ets/livecardability/SleepLiveCardAbility.ets
- entry/src/main/ets/livecardability/DeliveryLiveCardAbility.ets
- entry/src/main/ets/livecardability/ExerciseLiveCardAbility.ets
- entry/src/main/ets/livecardability/MusicLiveCardAbility.ets
它们的结构很像:创建 LocalStorage,塞数据,调用 session.loadContent()。
最小代码长什么样
你可以先看这个简化版:
import { formInfo, LiveFormExtensionAbility, LiveFormInfo } from '@kit.FormKit';
import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession';
export class DemoLiveCardAbility extends LiveFormExtensionAbility {
onLiveFormCreate(liveFormInfo: LiveFormInfo, session: UIExtensionContentSession): void {
const storage = new LocalStorage();
storage.setOrCreate('context', this.context);
storage.setOrCreate('session', session);
storage.setOrCreate('formId', liveFormInfo.formId);
storage.setOrCreate('borderRadius', liveFormInfo.borderRadius);
const rect: formInfo.Rect = liveFormInfo.rect;
storage.setOrCreate('formRect', rect);
session.loadContent('livecardability/pages/DemoLiveCard', storage);
}
}
这段就是一个能工作的 LiveForm Ability 骨架。
onLiveFormCreate 是入口
onLiveFormCreate(liveFormInfo: LiveFormInfo, session: UIExtensionContentSession): void
系统创建互动区域时,会调用这个方法。
liveFormInfo 里有当前卡片的信息,比如:
- formId
- rect
- borderRadius
session 是加载 UI 的会话对象。你最后要通过它加载页面。
为什么要用 LocalStorage
Ability 和 ArkUI 页面不是一个普通函数调用关系。你不能直接把参数传进组件构造函数。
项目里用 LocalStorage 传数据:
const storage = new LocalStorage();
storage.setOrCreate('formId', liveFormInfo.formId);
storage.setOrCreate('formRect', liveFormInfo.rect);
页面里再这样接:
@Entry({ useSharedStorage: true })
@Component
struct DemoLiveCard {
@LocalStorageProp('formId') formId: string = '';
@LocalStorageProp('formRect') formRect?: formInfo.Rect = undefined;
}
字段名要一致。Ability 里写 formRect,页面里也要写 formRect。
session.loadContent 的路径怎么写
session.loadContent('livecardability/pages/DemoLiveCard', storage);
注意几点:
- 不写 entry/src/main/ets。
- 不写 .ets 后缀。
- 路径从 ets 目录下开始算。
比如项目里的音乐页面是:
entry/src/main/ets/livecardability/pages/MusicLiveCard.ets
加载时写:
session.loadContent('livecardability/pages/MusicLiveCard', storage);
页面必须 useSharedStorage
LiveForm 页面要这样写:
@Entry({ useSharedStorage: true })
@Component
struct DemoLiveCard {
@LocalStorageProp('formId') formId: string = '';
build() {
Column() {
Text(`formId: ${this.formId}`)
}
.width('100%')
.height('100%')
}
}
没有 useSharedStorage: true,页面拿不到 Ability 传进来的 LocalStorage。
这是小白很容易漏的一行。
module.json5 也要注册
写了 Ability 文件还不够,必须在 module.json5 注册:
{
"name": "DemoLiveCardAbility",
"srcEntry": "./ets/livecardability/DemoLiveCardAbility.ets",
"type": "liveForm"
}
然后 form_config.json 里绑定:
"sceneAnimationParams": {
"abilityName": "DemoLiveCardAbility"
}
这两处名字必须一致。
从项目里学到的好习惯
项目里的 MusicLiveCardAbility 不只是加载页面,还会准备业务数据:
storage.setOrCreate('triggerAction', actionData.triggerAction);
storage.setOrCreate('songList', initSongs);
storage.setOrCreate('currentSong', currentSong);
storage.setOrCreate('previousSong', previousSong);
也就是说,LiveForm Ability 适合做“页面打开前的数据准备”。
页面专心画 UI 和动画,不要把所有初始化逻辑都堆到页面里。
排查清单
LiveForm 页面加载不出来时,按这个顺序查:
写在最后
LiveForm Ability 的核心不是写 UI,而是“接住系统创建事件,然后加载互动页面”。
小白可以先跑通最小版本,再慢慢加音乐列表、传感器、Canvas 动画这些复杂内容。





