鸿蒙 Ability Kit 之 UIAbility 组件生命周期深度解析与实战
在鸿蒙(HarmonyOS)应用开发中,是核心基石,而UIAbility作为与用户交互的核心组件,其生命周期管理直接决定了应用的行为逻辑。本文将从UIAbility的生命周期流程、关键回调方法、实战场景(如 Want 参数传递与清空)等维度,结合完整代码案例,深入剖析鸿蒙应用的生命周期管理。
目录
1. onCreate(want: Want, launchParam: AbilityConstant.LaunchParam)
2. onWindowStageCreate(windowStage: window.WindowStage)
3. onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam)
4. onForeground()与onBackground()
5. onWindowStageDestroy()与onDestroy()
解决方案 2:在onBackground中清空变量(谨慎使用)
在鸿蒙(HarmonyOS)应用开发中,Ability Kit(程序框架服务) 是核心基石,而UIAbility作为与用户交互的核心组件,其生命周期管理直接决定了应用的行为逻辑。本文将从UIAbility的生命周期流程、关键回调方法、实战场景(如 Want 参数传递与清空)等维度,结合完整代码案例,深入剖析鸿蒙应用的生命周期管理。
一、UIAbility 生命周期全景图
鸿蒙的UIAbility组件生命周期可分为创建、前台 / 后台切换、销毁三大阶段,每个阶段对应一系列回调方法。理解这些方法的触发时机,是掌握鸿蒙应用流程的关键。
UIAbility的生命周期示意图如下所示:

生命周期阶段与核心回调:
| 阶段 | 核心回调方法 | 触发时机 |
|---|---|---|
| 创建阶段 | onCreate、onWindowStageCreate |
应用首次启动时,UIAbility实例化后触发onCreate,窗口舞台创建后触发onWindowStageCreate |
| 前台 / 后台切换 | onForeground、onBackground、onNewWant |
应用从后台切到前台触发onForeground;前台切后台触发onBackground;已启动的UIAbility再次被请求时触发onNewWant |
| 销毁阶段 | onWindowStageDestroy、onDestroy |
窗口舞台销毁时触发onWindowStageDestroy,UIAbility实例销毁前触发onDestroy |
二、UIAbility 核心生命周期方法解析
1. onCreate(want: Want, launchParam: AbilityConstant.LaunchParam)
-
作用:
UIAbility实例创建时的初始化入口,适合做全局配置、数据预加载等操作。 -
参数:
want是鸿蒙的 “意图” 对象,用于组件间数据传递;launchParam包含启动参数。
代码示例(UserAbility.ets):
在onCreate中,我们从want对象中提取参数info,并将其存储到globalThis(全局对象)中,供后续页面使用。
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
const DOMAIN = 0x0000;
export default class UserAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
// 从Want中获取参数并存储到全局变量
let paramValue = want.parameters?.info;
globalThis.value = paramValue;
}
// 其他生命周期方法...
}
2. onWindowStageCreate(windowStage: window.WindowStage)
-
作用:窗口舞台(
WindowStage)创建完成后触发,是加载 UI 页面的关键入口。 -
参数:
windowStage是窗口管理的核心对象,通过它可加载页面、管理窗口生命周期。
代码示例(OtherAbility.ets):
在onWindowStageCreate中,我们根据want1中的路由参数router,动态决定加载OtherIndex或PageA页面,实现了 “一个 Ability 加载多个页面” 的场景。
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
let currentWindowStage: window.WindowStage;
export default class OtherAbility extends UIAbility {
want1: Want | undefined = undefined;
url: string = "";
onWindowStageCreate(windowStage: window.WindowStage): void {
console.log("OtherAbility is onWindowStageCreate start....");
// 从want1中获取路由参数,决定加载哪个页面
let paramValue = this.want1?.parameters?.router as string;
console.log("获取的paramValue的值为:" + paramValue);
// 根据路由参数设置页面路径
if (paramValue === "default" || paramValue === undefined) {
this.url = "pages/other/OtherIndex";
}
if (paramValue === "a") {
this.url = "pages/other/PageA";
}
currentWindowStage = windowStage;
// 加载指定页面
windowStage.loadContent(this.url, (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.');
});
}
// 其他生命周期方法...
}
3. onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam)
-
作用:已启动的
UIAbility再次被请求时触发(如应用在后台,被再次唤起时),不会触发onWindowStageCreate。 -
场景:需处理 “应用切后台后再次唤起,参数更新” 的业务逻辑。
代码示例(OtherAbility.ets):
onNewWant中接收新的want参数,更新全局变量want1后,手动调用onWindowStageCreate重新加载页面,保证页面根据新参数刷新。
export default class OtherAbility extends UIAbility {
want1: Want | undefined = undefined;
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
console.log("OtherAbility is onNewWant start....");
// 刷新want1为新的请求参数
this.want1 = want;
// 当用户 再次 将UIAbility切换到前台时,系统会依次触发onNewWant()、onForeground()生命周期回调。不触发onWindowStageCreate回调。
// 所以在onNewWant()里面再手动调用onWindowStageCreate()
this.onWindowStageCreate(currentWindowStage);
}
// 其他生命周期方法...
}
4. onForeground()与onBackground()
-
onForeground():应用从后台切到前台时触发,适合恢复前台业务(如重新请求数据、刷新 UI)。 -
onBackground():应用从前台切到后台时触发,适合暂停前台业务(如停止轮询、保存临时数据)。
代码示例(OtherAbility.ets):
export default class OtherAbility extends UIAbility {
onForeground(): void {
console.log("OtherAbility is onForeground start....");
}
onBackground(): void {
console.log("OtherAbility is onBackground start....");
// 可选:清空want1(注意业务影响)
// this.want1 = undefined;
}
// 其他生命周期方法...
}
5. onWindowStageDestroy()与onDestroy()
-
onWindowStageDestroy():窗口舞台销毁时触发,适合释放窗口相关资源。 -
onDestroy():UIAbility实例销毁前触发,是应用 “最后一次” 资源清理机会。
代码示例(AdminAbility.ets):
export default class AdminAbility extends UIAbility {
onDestroy(): void {
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
}
onWindowStageDestroy(): void {
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
// 其他生命周期方法...
}
三、实战:Want 参数的传递与清空
在鸿蒙应用中,Want是组件间数据传递的核心载体。但在 “应用切后台后再次唤起” 的场景中,需特别注意Want参数的清空与更新,否则会出现 “参数残留导致页面异常” 的问题。
场景复现:onNewWant与want参数残留
当UIAbility处于后台时,若再次通过新的Want唤起它,会触发onNewWant而非onWindowStageCreate。若不及时更新全局want变量,页面会继续使用旧参数,导致逻辑异常。
解决方案 1:在onNewWant中直接更新全局变量
-
在
onNewWant中,将入参want直接赋值给全局变量want1,确保后续页面加载时使用最新参数。
const DOMAIN = 0x0000;
let currentWindowStage:window.WindowStage ;
export default class OtherAbility extends UIAbility {
//全局变量
want1:Want|undefined = undefined
url : string =""
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
console.log("OtherAbility is onCreate start....")
this.want1 = want
}
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
console.log("OtherAbility is onNewWant start....")
// 刷新want1为新的请求参数
this.want1 = want
// 当用户 再次 将UIAbility切换到前台时,系统会依次触发onNewWant()、onForeground()生命周期回调。不触发onWindowStageCreate回调。
// 所以在onNewWant()里面再手动调用onWindowStageCreate()
this.onWindowStageCreate(currentWindowStage);
// 其他生命周期方法...
}
解决方案 2:在onBackground中清空变量(谨慎使用)
-
此方案在 “快捷方式唤起 + 页面按钮跳转” 的混合场景中可能引发问题(如跳转默认页面而非目标页面),需根据业务场景谨慎选择。
export default class OtherAbility extends UIAbility {
want1: Want | undefined = undefined;
onBackground(): void {
console.log("OtherAbility is onBackground start....");
// 切后台时清空want1(注意:可能影响“切后台后再次唤起”的业务逻辑)
this.want1 = undefined;
}
}
四、跨 Ability 与跨应用的 Want 传递实战
鸿蒙的Want不仅支持应用内UIAbility间的参数传递,还能实现跨应用唤起与深度链接(DeepLink) 功能。
4.1 应用内UIAbility间传递 Want
在页面中通过startAbility或startAbilityForResult触发Want传递。
4.1.1 启动应用内Ability
通过context.startAbility启动UserAbility并传递parameters。
import { Want, common, OpenLinkOptions } from "@kit.AbilityKit"
@Entry
@Component
struct Index {
context = this.getUIContext().getHostContext() as common.UIAbilityContext
build() {
Column({ space: 30 }) {
// 启动UserAbility并传递Want参数
Button("点击启动应用内的用户的Ability").onClick(() => {
let wantInfo1: Want = {
deviceId: "",
bundleName: "com.pp.chapterability1",
abilityName: "UserAbility",
parameters: {
info: "1.这是入口的ability给userability传递的消息"
}
}
//启动Userbility,首先要获取上下文对象context对象
this.context.startAbility(wantInfo1).then(() => {
}).catch(() => {
})
})
}
}
}
4.1.2 启动Ability并获取返回结果
通过startAbilityForResult启动AdminAbility,并在回调中处理返回结果。
// 启动AdminAbility并获取返回结果
Button("点击启动应用内的管理员的Ability并得到返回的结果信息").onClick(() => {
let wantInfo1: Want = {
deviceId: "",
bundleName: "com.pp.chapterability1",
abilityName: "AdminAbility",
parameters: {
info: "2.这是入口的ability给adminability传递的消息"
}
}
//跳转到另外一个ability并得到返回的结果
this.context.startAbilityForResult(wantInfo1).then((data) => {
console.log("1.返回的信息为:" + JSON.stringify(data))
if (data?.resultCode === 1001) {
let resultInfo = data?.want?.parameters?.info as string
this.getUIContext().getPromptAction().showToast({
message: resultInfo,
duration: 6000
})
}
})
})
4.1.3 目标Ability返回结果
import { Want, common } from "@kit.AbilityKit"
@Entry
@Component
struct Admin {
@State message: string = 'admin视图';
context = this.getUIContext().getHostContext() as common.UIAbilityContext
build() {
Column({ space: 30 }) {
Text(this.message).fontSize(20).fontWeight(FontWeight.Bold)
Text("传递的参数的值为:" + globalThis.value).fontSize(20).fontWeight(FontWeight.Bold).fontColor(Color.Red)
Button("返回到来时的ability并给出返回的结果").onClick(() => {
let abilityResult: common.AbilityResult = {
resultCode: 1001,
want: {
bundleName: "com.pp.chapterability1",
abilityName: "EntryAbility",
parameters: {
info: "来自于AdminAbility的页面的返回消息"
}
}
}
this.context.terminateSelfWithResult(abilityResult)
})
}.width("100%").height("100%").justifyContent(FlexAlign.Center)
}
}
4.1.4 快捷方式(Shortcuts)配置
需要爱module.json5中注册快捷方式,并在profile目录下新建shortcuts_config配置文件。

{
"shortcuts": [
{
"shortcutId": "id_test1",
"label": "$string:User_label",
"icon": "$media:user",
"wants": [
{
"bundleName": "com.pp.chapterability1",
"moduleName": "entry",
"abilityName": "UserAbility",
"parameters": {
"info": "shortcuts_userinfo"
}
}
]
},
{
"shortcutId": "id_test2",
"label": "$string:Admin_label",
"icon": "$media:admin",
"wants": [
{
"bundleName": "com.pp.chapterability1",
"moduleName": "entry",
"abilityName": "AdminAbility",
"parameters": {
"info": "shortcuts_admininfo"
}
}
]
},
{
"shortcutId": "id_test3",
"label": "$string:Other_label",
"icon": "$media:other",
"wants": [
{
"bundleName": "com.pp.chapterability1",
"moduleName": "entry",
"abilityName": "OtherAbility",
"parameters": {
"router": "default"
}
}
]
}
]
}
4.2 跨应用交互实现
4.2.1 启动其他应用的Ability
// 唤起其他应用的Ability
Button("点击启动同一个设备其他app应用的Ability").onClick(()=>{
let wantInfo1: Want = {
deviceId: "",
bundleName: "com.pp.chapterapp1", // 其他应用的包名
abilityName: "EntryAbility",
}
this.context.startAbility(wantInfo1)
})
4.2.2 使用DeepLink方式拉起应用
鸿蒙支持通过openLink方法唤起其他应用,并通过深度链接直接跳转至目标页面。
// 通过DeepLink唤起其他应用
Button("点击启动同一个设备其他app应用的Ability[通过deeplink方式拉起]").onClick(()=>{
let linkUrl : string = "link://www.pp.cn"
let option:OpenLinkOptions ={
appLinkingOnly:false
}
this.context.openLink(linkUrl,option)
})
4.2.3 DeepLink配置
在目标应用的module.json5中配置DeepLink:

更多推荐



所有评论(0)