很多刚接触鸿蒙 Stage 模型的新手,最容易踩的第一个坑就是「生命周期混淆」:onCreateonForegroundaboutToAppearonWindowStageCreate……一堆回调长得像,触发时机和作用却天差地别,再加上旧 FA 模型的记忆干扰,经常搞不清哪步该初始化、哪步该释放资源。
在这里插入图片描述

鸿蒙 7(API 26)全面推进 @kit 体系后,AbilityKit 进一步规范了 Stage 模型的生命周期,将应用逻辑、窗口管理、页面渲染三层彻底解耦,逻辑其实比旧版更清晰。本文就从层级区分、回调详解、时序流程到最佳实践,带你一次性搞懂 Stage 模型的完整生命周期,看完再也不会搞混。

一、先分清层级:别把 Ability 和页面生命周期混为一谈

这是新手最核心的误区:鸿蒙的生命周期不是一套,而是三层独立又关联的体系,每一层管不同的事,对应不同的回调。

生命周期层级 管理对象 核心作用 所属套件
UIAbility 应用级 应用入口组件 管理应用整体的创建、前后台切换、销毁 @kit.AbilityKit
WindowStage 窗口级 应用窗口容器 管理窗口的创建、加载页面、窗口状态 @kit.ArkUI(window 模块)
页面组件级 单个 ArkUI 页面 管理单个页面的渲染、显示、隐藏 ArkUI 原生能力

简单理解:

  • 打开应用 → 先创建 UIAbility 实例 → 再创建窗口 WindowStage → 窗口加载页面 → 页面渲染显示
  • 退出应用 → 页面销毁 → 窗口销毁 → UIAbility 实例销毁

绝大多数新手的困惑,都来自把这三层的回调混在一起。下面我们逐层拆解,每个回调讲清「什么时候触发、该做什么、不该做什么」。

二、核心:UIAbility 完整生命周期(AbilityKit 标准)

UIAbility 是 Stage 模型应用的唯一入口,对应旧版 FA 模型的 PageAbility,但生命周期做了大幅简化和重构,全程基于 @kit.AbilityKit 标准导入。

2.1 四大核心状态与回调

一个 UIAbility 从创建到销毁,完整经历四个核心状态,对应四个必掌握的核心回调。

1. onCreate:实例创建(整个生命周期仅触发一次)

在这里插入图片描述

  • 触发时机:应用冷启动,UIAbility 实例首次被创建时触发,全程只执行一次
  • 核心作用:执行全局一次性初始化,比如全局状态初始化、数据库连接创建、全局配置加载
  • 注意:此时窗口还没创建,绝对不能操作 UI 和窗口,也不要执行耗时阻塞操作
  • 代码示例:
import { UIAbility, Want, AbilityConstant } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';

const TAG = 'EntryAbility';

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    hilog.info(0x0000, TAG, 'onCreate:应用实例创建');
    // ✅ 正确操作:初始化全局数据、配置、数据库
    // ❌ 错误操作:加载页面、操作UI、获取窗口对象
  }
}
2. onWindowStageCreate:窗口创建(Stage 模型特有)

在这里插入图片描述

  • 触发时机:UIAbility 创建完成后,系统为其分配窗口管理器 WindowStage 时触发,在进入前台之前执行
  • 核心作用加载应用首页、配置窗口属性、注册窗口事件监听,这是 Stage 模型最核心的区别回调
  • 注意:这是加载页面的唯一正确时机,旧版 FA 模型的页面加载逻辑都迁移到了这里
  • 代码示例:
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  private windowStage: window.WindowStage | null = null;

  onWindowStageCreate(windowStage: window.WindowStage): void {
    hilog.info(0x0000, TAG, 'onWindowStageCreate:窗口已创建');
    this.windowStage = windowStage;

    // 1. 配置窗口属性:全屏、背景色等
    windowStage.getMainWindow().then((win) => {
      win.setWindowBackgroundColor('#FFFFFF');
      win.setWindowLayoutFullScreen(false);
    });

    // 2. 加载首页,这是应用显示的核心入口
    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        hilog.error(0x0000, TAG, `页面加载失败:${JSON.stringify(err)}`);
        return;
      }
      hilog.info(0x0000, TAG, '首页加载成功');
    });
  }
}
3. onForeground:进入前台(用户可见可交互)
  • 触发时机:应用从后台切换到前台、页面完全显示并可交互时触发;冷启动也会在窗口创建后触发一次
  • 核心作用:恢复暂停的任务、刷新实时数据、重启动画/定时器、恢复网络连接
  • 典型场景:视频应用恢复播放、聊天应用刷新消息、地图应用恢复定位
  • 代码示例:
onForeground(): void {
  hilog.info(0x0000, TAG, 'onForeground:应用进入前台');
  // ✅ 恢复定时器、刷新数据、重启定位
}
4. onBackground:退到后台(用户不可见)
  • 触发时机:用户按 Home 键、切换其他应用,应用从前台退到后台时触发
  • 核心作用:暂停耗电操作、保存临时状态、释放非必要资源、停止动画/定时器
  • 注意:后台存活时间受系统管控,不要在这里执行长时间后台任务
  • 代码示例:
onBackground(): void {
  hilog.info(0x0000, TAG, 'onBackground:应用退到后台');
  // ✅ 暂停定时器、保存数据、停止定位
}
5. onWindowStageDestroy:窗口销毁
  • 触发时机:应用销毁前,窗口即将被回收时触发
  • 核心作用:释放窗口相关资源、注销窗口事件监听、清理弹窗/悬浮窗
  • 补充:API 20 后新增 onWindowStageWillDestroy,在窗口销毁前触发,此时窗口对象仍可使用,适合做资源注销
  • 代码示例:
onWindowStageDestroy(): void {
  hilog.info(0x0000, TAG, 'onWindowStageDestroy:窗口已销毁');
  this.windowStage = null;
  // ✅ 释放窗口资源、注销窗口监听
}
6. onDestroy:实例彻底销毁
  • 触发时机:UIAbility 实例即将被系统销毁时触发,整个生命周期仅一次
  • 核心作用:释放所有全局资源、保存持久化数据、注销所有广播/监听
  • 注意:系统强制回收时可能不触发,重要数据建议在 onBackground 时就保存
  • 代码示例:
onDestroy(): void {
  hilog.info(0x0000, TAG, 'onDestroy:应用实例销毁');
  // ✅ 释放数据库、清理全局定时器、注销所有监听
}

2.2 高频补充回调

除了核心生命周期,还有两个业务中常用的补充回调:

onNewWant:二次启动(单实例模式)
  • 触发时机:Ability 已在运行,再次被启动(比如从桌面点击图标、通知跳转)时触发,不会重新走 onCreate
  • 核心作用:处理新的启动参数、跳转到指定页面、更新页面数据
  • 代码示例:
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): boolean {
  hilog.info(0x0000, TAG, `onNewWant:收到新启动参数`);
  // 读取参数,跳转到对应页面
  const targetPage = want.parameters?.targetPage as string;
  if (targetPage && this.windowStage) {
    // 执行页面跳转
  }
  return true;
}
onPrepareToTerminateAsync:销毁前拦截
  • 触发时机:用户主动关闭应用时触发,可返回 true 拦截销毁
  • 核心作用:提示用户保存未提交内容、确认退出
  • 代码示例:
async onPrepareToTerminateAsync(): Promise<boolean> {
  // 返回true:拦截销毁,不退出应用
  // 返回false:允许销毁,继续退出流程
  return false;
}

三、容易忽略的一层:WindowStage 窗口生命周期

Stage 模型的核心改进就是「Ability 与窗口解耦」,WindowStage 作为中间层,也有自己的状态变化,适合做更精细的窗口状态监听。

通过给 WindowStage 注册事件监听,可以获取更细粒度的窗口状态:

onWindowStageCreate(windowStage: window.WindowStage): void {
  // 注册窗口生命周期事件监听
  windowStage.on('windowStageLifecycleEvent', (event) => {
    switch (event) {
      case window.WindowStageLifeCycleEventType.SHOWN:
        // 窗口已显示
        break;
      case window.WindowStageLifeCycleEventType.RESUMED:
        // 窗口可交互
        break;
      case window.WindowStageLifeCycleEventType.PAUSED:
        // 窗口暂停交互(比如被弹窗遮挡)
        break;
      case window.WindowStageLifeCycleEventType.HIDDEN:
        // 窗口已隐藏
        break;
    }
  });
}

新手提示:普通业务开发不需要单独监听窗口事件,用好 UIAbility 的前后台回调就足够了;只有做悬浮窗、多窗口适配时才需要精细化管控。

四、页面级生命周期:每个页面独立的渲染周期

UIAbility 管整个应用,页面级生命周期管单个 ArkUI 页面的显示与隐藏,和 Ability 生命周期完全独立,每个页面都有自己的生命周期回调。

4.1 核心页面生命周期回调

1. aboutToAppear:页面即将渲染
  • 触发时机:页面 build 执行之前,组件即将挂载显示时触发
  • 核心作用:初始化页面数据、请求接口数据、准备渲染所需资源
  • 注意:此时 UI 还没渲染完成,不能操作 DOM 节点
2. aboutToDisappear:页面即将销毁
  • 触发时机:页面返回、被替换,即将从渲染树移除时触发
  • 核心作用:清理页面级定时器、注销事件监听、取消未完成的网络请求
3. onPageShow / onPageHide:页面显示/隐藏
  • 触发时机:页面完全显示/完全隐藏时触发,包括前后台切换、页面跳转导致的显隐
  • 区别aboutToAppear 只在首次创建时触发一次;onPageShow 每次页面回到前台都会触发
  • 典型场景:页面每次显示都刷新数据,用 onPageShow;只初始化一次,用 aboutToAppear

4.2 页面生命周期完整示例

在这里插入图片描述

@Entry
@Component
struct DetailPage {
  @State data: string = '';

  aboutToAppear() {
    console.info('aboutToAppear:页面首次创建,初始化数据');
    // 只执行一次的初始化逻辑
  }

  onPageShow() {
    console.info('onPageShow:页面显示,刷新数据');
    // 每次显示都执行的逻辑,比如刷新列表
  }

  onPageHide() {
    console.info('onPageHide:页面隐藏');
    // 页面隐藏时暂停的逻辑
  }

  aboutToDisappear() {
    console.info('aboutToDisappear:页面销毁,清理资源');
    // 清理页面专属资源
  }

  build() {
    Column() {
      Text(this.data)
        .fontSize(20);
    }
    .width('100%')
    .height('100%');
  }
}

五、完整时序流程:一次搞懂调用顺序

很多人记不住回调顺序,我们用四个典型场景把完整流程串起来,对照日志一眼就能懂。

场景1:冷启动应用(首次打开)

onCreate(应用实例创建)
↓
onWindowStageCreate(窗口创建,加载首页)
↓
页面 aboutToAppear → 页面 build()
↓
页面 onPageShow
↓
onForeground(应用进入前台,可交互)

场景2:按 Home 键退到后台

页面 onPageHide
↓
onBackground(应用退到后台)

场景3:从后台回到前台

onForeground(应用回到前台)
↓
页面 onPageShow

注意:回前台不会重新走 onCreate 和 onWindowStageCreate,实例和窗口都还在

场景4:正常退出应用

页面 aboutToDisappear
↓
onBackground
↓
onWindowStageDestroy(窗口销毁)
↓
onDestroy(应用实例销毁)

六、最佳实践:每个生命周期该做什么不该做什么

新手最容易犯的错就是把逻辑放错生命周期,要么导致初始化失败,要么导致内存泄漏、后台耗电。

生命周期 推荐做的事 不推荐做的事
onCreate 全局配置初始化、数据库初始化、全局状态注册 加载页面、操作UI、执行耗时任务、获取窗口对象
onWindowStageCreate 加载首页、配置窗口属性、注册窗口监听 大量业务逻辑、耗时数据请求
onForeground 刷新数据、恢复定时器/动画、重启定位/播放 重度计算、大量IO操作
onBackground 保存临时数据、暂停耗电任务、释放非必要资源 长时间后台任务、复杂业务逻辑
onDestroy 释放全局资源、注销监听、清理定时器 保存核心数据(可能不触发,建议放onBackground)
aboutToAppear 页面数据初始化、首次接口请求 操作已渲染的UI元素
aboutToDisappear 清理页面级定时器、取消请求、注销监听 执行耗时保存操作

七、新手高频踩坑避坑指南

1. 混淆 Ability 生命周期和页面生命周期

  • 典型表现:在 EntryAbility 的 onCreate 里请求页面数据,或者在页面里写应用退出逻辑
  • 解决:记住「全局逻辑写 Ability,页面逻辑写页面」,数据请求优先放在页面的 aboutToAppear 里

2. 在 onCreate 里操作窗口和UI

  • 典型报错:获取不到 windowStage 对象,页面加载失败
  • 解决:所有和窗口、页面相关的操作,统一写在 onWindowStageCreate 回调里,这是 Stage 模型的硬性规则

3. 退后台不清理资源导致耗电异常

  • 典型问题:定时器、定位、播放没暂停,后台持续耗电
  • 解决:在 onBackground 里统一暂停所有前台相关任务,onForeground 里恢复

4. 单实例模式下二次启动不刷新页面

  • 典型问题:应用已打开,从通知跳转进来,页面数据没更新
  • 解决:在 onNewWant 回调中处理新参数,主动调用页面跳转或数据刷新,不要等 onCreate

5. 重要数据只在 onDestroy 保存

  • 典型问题:应用被系统强制回收时数据丢失
  • 解决:核心数据在 onBackground 时就持久化保存,onDestroy 只做资源清理,不做关键数据存储

八、总结

Stage 模型的生命周期看似回调多,其实逻辑非常清晰,核心就是「三层解耦」:

  1. Ability 层管应用生死和前后台,负责全局资源
  2. WindowStage 层管窗口,负责加载页面和窗口配置
  3. 页面层管单个页面的渲染和显隐,负责页面业务

对于新手,优先掌握 UIAbility 的 4 个核心回调 + 页面的 2 个核心回调,就能覆盖 90% 的开发场景;等熟悉之后,再根据业务需求学习窗口事件、销毁拦截等进阶能力。

和旧 FA 模型相比,Stage 模型的生命周期虽然多了 WindowStage 一层,但职责划分更清晰,多窗口、多设备适配也更灵活,是鸿蒙开发必须掌握的基础。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐