应用模型与系统能力
应用模型回答三个问题:应用怎么声明、组件怎么被系统拉起、权限与后台任务怎么管。鸿蒙现行的是 Stage 模型(HarmonyOS NEXT 唯一模型,老的 FA 模型不再演进)。示例语境:HarmonyOS NEXT / API 12+,需在 DevEco Studio 中验证。
三个核心概念先分清
- UIAbility:一个「界面入口」,类似一屏一职责的应用单元。用户点图标进入的首页、被其他应用 Want 拉起的页面,本质都是某个 UIAbility 的实例;
- ExtensionAbility:无界面的后台能力单元(卡片、数据共享、输入法、后台任务等),按类型区分(FormExtensionAbility、DataShareExtensionAbility 等);
- module:工程的独立构建单元,对应一个 HAP/HAR/HSP(详见工程与发布)。每个 UIAbility 都注册在所属 module 的
module.json5里。
module.json5:应用与组件的「户口本」
Stage 工程的双层配置:顶层 AppScope/app.json5 声明应用(包名 bundleName、版本、图标);每个 module 的 src/main/module.json5 声明模块与组件。UIAbility 示例片段:
json5
{
module: {
name: 'entry',
type: 'entry', // entry:入口模块
abilities: [
{
name: 'EntryAbility',
srcEntry: './ets/entryability/EntryAbility.ets',
exported: true,
skills: [
{ entities: ['entity.system.home'],
actions: ['action.system.home'] }
],
launchType: 'singleton'
}
]
}
}要点:skills 里 entity.system.home + action.system.home 让该 Ability 成为「桌面点击后拉起」的入口;launchType 决定实例策略(singleton 单例、standard 每次新建、multiton 多实例)。
UIAbility 生命周期
能力类继承 UIAbility,关键回调:
| 回调 | 触发 | 你要做的 |
|---|---|---|
onCreate | 进程/Ability 创建 | 初始化全局、恢复持久数据 |
onWindowStageCreate | 窗口舞台就绪 | 设置页面 windowStage.loadContent() |
onForeground | 到前台 | 开始 UI 相关活跃工作 |
onBackground | 退后台 | 存草稿、释放可回收资源 |
onDestroy | 销毁 | 收尾清理 |
纪律与 iOS/Android 一致:不要在
onBackground才想起来保存数据——任何关键状态变更时都落盘;后台只能做有限时间的工作,长任务要申请系统能力。
Want:跨组件「说一声就拉起」
Want 是拉起目标的标准描述,类似 Intent:
- 显式拉起:指定
bundleName+abilityName(或经 moduleName),确定性强,应用内/跨应用都可用; - 隐式拉起:只给
action/uri/entities,由系统按skills匹配;目标不确定时用startAbility前先做可用性查询; - 传参走
parameters键值;需要回传结果用startAbilityForResult配对回调。
typescript
import { common, Want } from '@kit.AbilityKit'
let want: Want = {
bundleName: 'com.example.target',
abilityName: 'EntryAbility',
parameters: { target: 'detail', id: '42' }
}
let ctx = getContext(this) as common.UIAbilityContext
ctx.startAbility(want)纪律:显式优于隐式;不可假设目标应用存在,启动失败要有兜底;敏感数据不要整包塞进 parameters。
权限模型
鸿蒙权限分三级:normal(申请即给)、system_basic(弹窗授权)、system_core(仅系统应用,需 ACL)。开发要点:
- 普通权限在
module.json5的requestPermissions里声明即可; - 敏感权限(定位、相机、麦克风等)先声明,再运行时用
requestPermissionsFromUser弹窗申请,结果回调里分流处理; - 权限用途说明要写清楚,商店审核会核验「声明 ≠ 实际调用」。
后台与任务限制
- 应用退后台后有运行窗口,窗口期耗尽系统会挂起;需要持续执行(播放、通话、导航)要申请对应长时任务类型的能力,不能钻空子轮询;
- 前台任务(如下载)用系统提供的任务 API,带进度与通知能力;
- 做「真·后台保活」的思路在鸿蒙同样不成立:把需求往系统支持的场景(长时任务/分布式能力)靠,而不是对抗系统回收。
常见坑速查
| 坑 | 现象 | 解法 |
|---|---|---|
| 忘了在 json5 注册 Ability | 拉起失败、IDE 报未知 Ability | module.json5 abilities 补齐 |
| 图标入口不生效 | 桌面图标点了没反应 | skills 配 home 实体 + action |
| launchType 理解错 | 页面状态串了/实例过多 | 按场景选 singleton/standard |
| 隐式拉起目标多 | 行为不确定 | 先查询再拉起,给选择兜底 |
| 权限没做运行时申请 | 功能失效+审核拒 | requestPermissionsFromUser |
| 退后台后强跑任务 | 被系统挂起 | 长时任务/合理时机收口 |
检查清单
- [ ] 每个 UIAbility 都在 module.json5 注册,入口 skills 正确;
- [ ]
onBackground/onDestroy清理及时,无后台泄漏; - [ ] 拉起统一走显式 Want,失败兜底齐全;
- [ ] 敏感权限完成声明 + 运行时申请 + 拒绝分流;
- [ ] 后台需求落到系统支持的场景,无对抗回收式 hack。