
前言
HarmonyOS 从 API 9 开始全面推行 Stage 模型 ,替代了早期版本的 FA(Feature Ability)模型。Stage 模型的核心设计理念是将组件生命周期 、窗口管理 和任务调度 三者解耦,为应用提供更精细化的控制能力。本文基于 小事记(xiaoshiji_ohos_app) 项目,从 EntryAbility.ets 源码出发,深入剖析 Stage 模型下 UIAbility 的启动流程、生命周期回调顺序,以及 Want 参数在应用启动中的传递机制。
本文参考 HarmonyOS 官方文档:application-lifecycle.md 和 application-startup-options.md。
一、Stage 模型的核心架构
1.1 模型演进背景
在 FA 模型中,Ability 同时承担了生命周期管理和 UI 渲染的职责,导致组件间耦合度较高。Stage 模型将这一架构拆分为三层:
| 层级 | 组件 | 职责 |
|---|---|---|
| Ability 层 | UIAbility / ExtensionAbility | 应用入口、生命周期管理 |
| Window 层 | WindowStage / Window | 窗口创建、布局与销毁 |
| UI 层 | @Component / @Entry | 页面视图渲染与交互 |
Stage 模型 的核心优势:
- 组件解耦 --- Ability 不直接管理 UI,而是通过
WindowStage加载 UI 内容 - 多实例支持 --- 一个 Ability 可以创建多个窗口实例
- 后台任务独立 --- ExtensionAbility 体系分离了后台任务与前台 UI
- 模块化分包 --- 支持 HAP/HSP/HAR 多种包格式的灵活组合
1.2 小事记中的模型实践
在 xiaoshiji_ohos_app 项目中,EntryAbility.ets 是唯一的 UIAbility 实现,它负责:
- 应用启动时设置颜色模式
- 创建主窗口并加载
Index.ets页面 - 管理应用前后台切换的日志记录
typescript
// EntryAbility.ets --- 小事记应用的 UIAbility 实现
import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
const DOMAIN = 0x0000;
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
// 设置颜色模式
this.context.getApplicationContext().setColorMode(
ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET
);
hilog.info(DOMAIN, 'testTag', 'Ability onCreate');
}
// ... 其他生命周期方法
}
提示 :
@kit.AbilityKit是 API 12 引入的 Kit 化导入方式,替代了旧版@ohos.ability.abilityLifecycle等分散的模块路径。
二、UIAbility 的完整生命周期
2.1 生命周期回调顺序
Stage 模型中,UIAbility 的生命周期由以下回调组成,它们按严格的顺序执行:
图:UIAbility 从创建到销毁的完整生命周期流转
typescript
// 生命周期回调的完整执行顺序
onCreate(want, launchParam) // 第1步:Ability 创建时调用
→ onWindowStageCreate(windowStage) // 第2步:窗口阶段创建
→ onForeground() // 第3步:Ability 进入前台
→ [应用运行中...]
→ onBackground() // 第4步:Ability 进入后台
→ onForeground() // 第5步:再次回到前台(可重复)
→ [用户退出应用]
→ onBackground() // 第6步:进入后台
→ onWindowStageDestroy() // 第7步:窗口阶段销毁
→ onDestroy() // 第8步:Ability 销毁
2.2 各回调的核心职责
onCreate --- 应用初始化入口:
- 接收
Want参数(启动来源) - 接收
LaunchParam(启动原因,冷启动/热启动/后台启动) - 初始化全局配置(如颜色模式、日志系统)
- 不适合在此处做耗时操作,因为此时窗口尚未创建
onWindowStageCreate --- 窗口创建回调:
- 是加载页面内容的唯一时机
- 通过
windowStage.loadContent()加载首页 - 可以在此处设置窗口属性(如横竖屏、全屏)
typescript
onWindowStageCreate(windowStage: window.WindowStage): void {
hilog.info(DOMAIN, 'testTag', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
hilog.error(DOMAIN, 'testTag',
'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
return;
}
hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
});
}
onForeground / onBackground --- 前后台切换:
- 用户按 Home 键或切换应用时触发
onBackground - 用户回到应用时触发
onForeground - 适合在此处暂停/恢复动画、音乐播放等资源密集型操作
2.3 生命周期执行顺序对比
| 场景 | 回调顺序 | 说明 |
|---|---|---|
| 冷启动 | onCreate → onWindowStageCreate → onForeground | 进程首次创建 |
| 热启动 | onForeground | 进程已在后台 |
| 后台启动 | onCreate → onForeground | 不创建窗口,用于后台执行任务 |
| 按 Home 键 | onBackground | 进入后台,窗口保留 |
| 返回桌面 | onBackground → onWindowStageDestroy → onDestroy | 窗口被销毁,进程可能保留 |
三、Want 启动参数解析
3.1 Want 的数据结构
Want 是 HarmonyOS 中 Ability 间通信的通用载体,类似于 Android 的 Intent。它在 onCreate 中以参数形式传递给 Ability,携带了启动来源、目标、操作类型等信息。
Want 的核心字段:
| 字段 | 类型 | 说明 | 示例值 |
|---|---|---|---|
deviceId |
string | 目标设备 ID(跨设备时使用) | ""(本机) |
bundleName |
string | 目标应用的包名 | "com.example.xiaoshiji" |
abilityName |
string | 目标 Ability 类名 | "EntryAbility" |
uri |
string | URI 数据 | "https://..." |
type |
string | MIME 类型 | "text/plain" |
action |
string | 操作类型 | "ohos.want.action.home" |
entities |
string\[\] | 实体类别 | ["entity.system.home"] |
parameters |
Record<string, Object> | 自定义参数 | {"key": "value"} |
3.2 隐式匹配与显式启动
Want 的启动方式 分为两种:
显式启动 --- 直接指定目标 Ability 的 bundleName 和 abilityName:
typescript
// 显式启动 --- 精确指定目标
let want = {
bundleName: "com.example.xiaoshiji",
abilityName: "EntryAbility"
};
this.context.startAbility(want);
隐式启动 --- 通过 action 和 entities 让系统匹配:
typescript
// 隐式启动 --- 通过 action 和 entities 匹配
let want = {
action: "ohos.want.action.home",
entities: ["entity.system.home"]
};
this.context.startAbility(want);
3.3 module.json5 中的 skills 配置
在 module.json5 中,skills 数组定义了 Ability 能够响应的隐式 Want 匹配规则:
json5
{
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"exported": true,
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"ohos.want.action.home"
]
}
]
}
]
}
exported: true 表示该 Ability 允许被其他应用启动。当桌面点击应用图标时,系统会发送一个 action: ohos.want.action.home 且 entities: ["entity.system.home"] 的隐式 Want,通过 skills 匹配到 EntryAbility。
提示 :如果
exported设置为false,则只有本应用内可以启动该 Ability,外部应用无法通过startAbility唤起。
3.4 LaunchParam 的启动原因分析
onCreate 的第二个参数 LaunchParam 提供了启动原因的详细信息:
typescript
// 在 onCreate 中解析启动原因
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
// launchReason 表示启动原因
switch (launchParam.launchReason) {
case AbilityConstant.LaunchReason.START_ABILITY:
console.info('被其他应用启动');
break;
case AbilityConstant.LaunchReason.CALL:
console.info('被其他应用通过 call 调用');
break;
case AbilityConstant.LaunchReason.CONTINUATION:
console.info('跨设备流转启动');
break;
case AbilityConstant.LaunchReason.APP_RECOVERY:
console.info('应用恢复启动');
break;
default:
console.info('未知启动原因');
}
}
LaunchReason 枚举值包括:
START_ABILITY--- 通过startAbility启动CALL--- 通过call方法启动(后台运行)CONTINUATION--- 跨设备流转(从其他设备迁移)APP_RECOVERY--- 应用从异常崩溃中恢复
四、Index.ets 的启动逻辑
4.1 路由跳转的设计意图
小事记的 Index.ets 是一个启动过渡页 (Splash Screen),其核心逻辑是 aboutToAppear 中立即跳转到 HomePage:
typescript
// Index.ets --- 启动过渡页
import router from '@ohos.router';
@Entry
@Component
struct Index {
aboutToAppear(): void {
router.replaceUrl({ url: 'pages/HomePage' });
}
build() {
Column() {
Text('小事记')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.fontColor('#7B68EE')
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.backgroundColor('#F8F9FA')
}
}
这种设计有以下几个技术考量:
replaceUrl替换路由 --- 使用replaceUrl而非pushUrl,确保用户从 HomePage 返回时不会回到这个空白页aboutToAppear中执行 --- 该回调在组件即将可见时触发,比build中的onClick更早执行- 启动窗口背景 --- 从点击图标到
Index.ets渲染之间,会显示startWindowBackground配置的颜色
4.2 启动窗口的视觉优化
module.json5 中的启动窗口配置直接影响用户体验:
json5
{
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background"
}
startWindowIcon--- 启动时显示的图标,通常使用应用图标startWindowBackground--- 启动窗口的背景色,建议与应用首页背景色一致,减少视觉跳跃
五、完整启动流程时序图
5.1 从点击图标到首页渲染
以下是小事记应用从点击图标到 HomePage 完全渲染的完整时序:
[用户点击图标]
↓
系统解析 Want: action=ohos.want.action.home
↓
match skills → EntryAbility
↓
UIAbility.onCreate(want, launchParam)
↓ 设置颜色模式、初始化日志
UIAbility.onWindowStageCreate(windowStage)
↓
windowStage.loadContent('pages/Index')
↓
Index.ets @Component 创建
↓
Index.aboutToAppear() → router.replaceUrl('pages/HomePage')
↓
HomePage.ets @Component 创建
↓
HomePage.build() 执行
↓
UIAbility.onForeground()
↓
[用户看到首页]
5.2 各阶段耗时分析
| 阶段 | 耗时因素 | 优化方向 |
|---|---|---|
| 系统调起 Ability | 进程创建、包解析 | 减少 module.json5 配置复杂度 |
onCreate |
初始化逻辑 | 避免在此处执行网络请求 |
loadContent |
页面加载 | 首页使用轻量组件 |
| 首页渲染 | 组件树构建 | 使用 LazyForEach 懒加载 |
六、常见问题与最佳实践
6.1 生命周期回调中执行耗时操作
问题 :在 onCreate 中执行网络请求或数据库初始化。
解决方案 :使用 onWindowStageCreate 加载页面后,在首页的 aboutToAppear 中异步初始化数据。
typescript
// ❌ 错误:在 onCreate 中执行耗时操作
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
await this.initDatabase(); // 阻塞了生命周期
await this.fetchUserData(); // 阻塞了生命周期
}
// ✅ 正确:在首页组件中异步加载
onWindowStageCreate(windowStage: window.WindowStage): void {
windowStage.loadContent('pages/HomePage');
}
// HomePage.ets
aboutToAppear(): void {
// 异步初始化,不阻塞UI渲染
this.loadDataAsync();
}
6.2 Want 参数传递的最佳实践
在跨 Ability 启动时,推荐使用 parameters 字段传递序列化数据:
typescript
// 启动方
let want = {
bundleName: "com.example.xiaoshiji",
abilityName: "EntryAbility",
parameters: {
targetPage: "EventDetailPage",
eventId: "12345",
timestamp: Date.now()
}
};
this.context.startAbility(want, (err) => {
if (err.code) {
console.error(`startAbility failed: ${err.message}`);
}
});
提示 :
parameters中的值必须是可 JSON 序列化的类型,不支持传递函数或复杂对象。
6.3 启动超时处理
UIAbility 的 onCreate 和 onWindowStageCreate 有 5 秒的超时限制。如果超过 5 秒未返回,系统会认为该 Ability 无响应并终止。
typescript
// 使用 setTimeout 处理超时场景
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
const timeoutId = setTimeout(() => {
console.warn('onCreate 执行超时,进行降级处理');
this.performDegradeInit();
}, 3000);
// 正常初始化
this.initEssentialData();
clearTimeout(timeoutId); // 正常完成,清除超时计时器
}
七、与 FA 模型的关键差异
7.1 生命周期对比
| 对比维度 | FA 模型 | Stage 模型 |
|---|---|---|
| 生命周期类 | Ability |
UIAbility |
| 窗口管理 | 内置在 Ability 中 | 通过 WindowStage 独立管理 |
| UI 加载 | setUIContent() |
windowStage.loadContent() |
| 多实例 | 有限支持 | 原生支持 |
| 后台任务 | 通过 ServiceAbility | 通过 ExtensionAbility |
7.2 迁移注意事项
从 FA 模型迁移到 Stage 模型时,需要注意以下变化:
- 配置文件 ---
config.json变更为module.json5+AppScope/app.json5 - 导入路径 ---
@ohos.ability.xxx变更为@kit.AbilityKit - Context 获取 --- 从
this.context获取,而非this.getContext() - 页面路由 ---
PageAbility的setUIContent变更为WindowStage.loadContent
八、实际项目中的调试技巧
8.1 使用 hilog 跟踪生命周期
小事记项目中使用了 hilog 来记录每个生命周期回调的执行:
typescript
import { hilog } from '@kit.PerformanceAnalysisKit';
const DOMAIN = 0x0000;
// 在关键节点打印日志
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(DOMAIN, 'testTag', 'Ability onCreate');
}
onWindowStageCreate(windowStage: window.WindowStage): void {
hilog.info(DOMAIN, 'testTag', 'Ability onWindowStageCreate');
}
onForeground(): void {
hilog.info(DOMAIN, 'testTag', 'Ability onForeground');
}
onBackground(): void {
hilog.info(DOMAIN, 'testTag', 'Ability onBackground');
}
通过 hilog 日志,可以在 DevEco Studio 的 Log 面板中实时观察生命周期的执行顺序。
8.2 ThinkTime 分析
在 DevEco Studio 中使用 Profiler 工具,可以观察到每个生命周期回调的执行时间:
- 打开 DevEco Studio → Profiler → Launch Profiling
- 点击应用启动按钮
- 在 Timeline 面板中查看每个回调的耗时
总结
本文从 xiaoshiji_ohos_app 项目的 EntryAbility.ets 源码出发,深入剖析了 Stage 模型 下 UIAbility 的启动流程、生命周期回调顺序和 Want 参数传递机制。核心要点如下:
- Stage 模型的三层架构(Ability → Window → UI)实现了组件间的解耦,使生命周期管理更加清晰
- UIAbility 的生命周期 遵循
onCreate → onWindowStageCreate → onForeground的固定顺序,每个回调有明确的职责边界 - Want 参数 通过隐式匹配(skills)和显式启动两种方式,支持跨应用通信和参数传递
- 启动窗口配置 (
startWindowIcon/startWindowBackground)是优化用户体验的关键手段
下一篇文章将深入探讨 Context 类层级体系 ,解析 ApplicationContext、UIAbilityContext、UIContext 的区别与使用场景。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- 小事记项目源码:xiaoshiji_ohos_app
- 官方文档 - 应用生命周期:application-lifecycle.md
- 官方文档 - 启动选项:application-startup-options.md
- 官方文档 - Stage 模型:application-models.md
- 官方文档 - 配置文文件:application-configuration-file-stage.md
- 官方文档 - 显式 Want:ability-startup-with-explicit-want.md
- 官方文档 - Context:application-context-stage.md
- 开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net