首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >[鸿蒙从零到一] Ability 基础与生命周期实战

[鸿蒙从零到一] Ability 基础与生命周期实战

原创
作者头像
hunter android
发布2026-07-13 11:09:37
发布2026-07-13 11:09:37
360
举报

HarmonyOS Ability 基础与生命周期实战

在 HarmonyOS 应用开发里,Ability 是承载所有可运行能力的最小单元。不管是启动一个页面、跑一段后台服务,还是接受外部拉起,几乎都会落在某个 Ability 上。理解 Ability 的定位、类型与生命周期,是把 Stage 模型玩转的基础。这篇文章会从概念到源码,由浅入深地把 Ability 讲透。

一、Ability 是什么

一句话:Ability 是 HarmonyOS 应用暴露给系统的“可被调度的能力入口”。

  • 系统视角:系统调度器根据用户操作或事件(点击图标、通知拉起、任务列表、语音助手、原子化服务等)挑一个 Ability 拉起来。
  • 应用视角:应用把自己拆成若干可独立启动、可被外部访问的 Ability,各自有独立的上下文、独立的生命周期。

Stage 模型(当前 HarmonyOS 推荐模型)下,Ability 有两大类:

类型

类名

定位

UIAbility

UIAbility

带界面的能力,承载页面栈,用户可见

ExtensionAbility

ServiceExtensionAbility、DataShareExtensionAbility 等

无界面的扩展能力,专注后台服务、数据共享、卡片、输入法等场景

初学阶段主要打交道的是 UIAbility;ExtensionAbility 用到再展开。

二、Ability、AbilityStage 和 Module 的关系

Stage 模型里,一个 HAP 模块里可以有多个 Ability,它们共享一个 AbilityStage

代码语言:javascript
复制
HAP Module
├── AbilityStage        // 模块级容器,模块首次加载时创建
│   ├── UIAbility A     // 独立进程/独立任务栈
│   ├── UIAbility B
│   └── ServiceExtensionAbility C
└── resources / pages / ets ...
  • AbilityStage 是模块运行时的容器,负责模块加载时的初始化,比如注入依赖、初始化路由、埋点 SDK。
  • 每个 UIAbility 有独立的任务(Task),可以在最近任务列表里独立出现。
  • 不同 Ability 之间通过 Want 通信,不能直接共享内存里的 UI 状态。

三、UIAbility 生命周期状态机

UIAbility 的生命周期比 Android Activity 更规整,主要有五个回调:

代码语言:javascript
复制
                       onCreate
                          │
                          ▼
                    onWindowStageCreate
                          │
                          ▼
                       onForeground
                          │
                     (可见 & 可交互)
                          │
                          ▼
                       onBackground
                          │
                     (切后台,仍存活)
                          │
                          ▼
                    onWindowStageDestroy
                          │
                          ▼
                       onDestroy

各回调职责:

  • onCreate(want, launchParam):Ability 首次创建时触发。做一次性初始化、读取启动参数。注意:此时 UI 还没有 WindowStage,不要在这里操作窗口。
  • onWindowStageCreate(windowStage):窗口舞台创建完成。加载首页、设置沉浸式、监听窗口事件,都在这里做。
  • onForeground():Ability 进入前台,用户可见可交互。启动定时刷新、恢复动画。
  • onBackground():Ability 切到后台,用户不可见但进程还在。暂停耗电任务、保存临时状态。
  • onWindowStageDestroy():窗口舞台销毁前的最后机会,释放和 WindowStage 绑定的资源。
  • onDestroy():Ability 生命周期终点,做最终清理。

关键点:onCreate ↔ onDestroy 是一对;onWindowStageCreate ↔ onWindowStageDestroy 是一对;onForeground ↔ onBackground 会反复来回。

四、一个最小可运行的 UIAbility

新建工程后,entry/src/main/ets/entryability/EntryAbility.ets 里的默认代码大概长这样,我们在里面加上完整的生命周期日志:

代码语言:javascript
复制
import UIAbility from '@ohos.app.ability.UIAbility';
import type Want from '@ohos.app.ability.Want';
import type AbilityConstant from '@ohos.app.ability.AbilityConstant';
import window from '@ohos.window';
import hilog from '@ohos.hilog';

const TAG = 'EntryAbility';

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    hilog.info(0x0000, TAG, 'onCreate, action=%{public}s', want.action ?? '');
    // 读取启动参数
    const from = want.parameters?.['from'] as string | undefined;
    hilog.info(0x0000, TAG, 'launched by: %{public}s', from ?? 'launcher');
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    hilog.info(0x0000, TAG, 'onWindowStageCreate');
    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        hilog.error(0x0000, TAG, 'loadContent failed: %{public}s', JSON.stringify(err));
        return;
      }
      hilog.info(0x0000, TAG, 'loadContent ok');
    });
  }

  onForeground(): void {
    hilog.info(0x0000, TAG, 'onForeground');
  }

  onBackground(): void {
    hilog.info(0x0000, TAG, 'onBackground');
  }

  onWindowStageDestroy(): void {
    hilog.info(0x0000, TAG, 'onWindowStageDestroy');
  }

  onDestroy(): void {
    hilog.info(0x0000, TAG, 'onDestroy');
  }
}

跑起来后,从桌面点击图标进入,日志顺序会是:

代码语言:javascript
复制
onCreate → onWindowStageCreate → onForeground

按 Home 返回桌面:

代码语言:javascript
复制
onBackground

再次点击图标切回:

代码语言:javascript
复制
onForeground

系统真正回收进程时(比如从最近任务列表滑掉、内存紧张被杀):

代码语言:javascript
复制
onBackground → onWindowStageDestroy → onDestroy

五、Ability 之间的启动与参数传递

UIAbility 之间不共享内存,跳转靠 WantWant 就是一份跨 Ability 的启动意图描述。

5.1 启动另一个 UIAbility

代码语言:javascript
复制
import common from '@ohos.app.ability.common';
import type Want from '@ohos.app.ability.Want';

@Entry
@Component
struct Index {
  build() {
    Column() {
      Button('打开详情页 Ability')
        .onClick(() => {
          const ctx = getContext(this) as common.UIAbilityContext;
          const want: Want = {
            bundleName: 'com.example.harmonydemo',
            abilityName: 'DetailAbility',
            parameters: {
              itemId: 1024,
              from: 'index',
            },
          };
          ctx.startAbility(want).catch((err: Error) => {
            console.error(`startAbility failed: ${err.message}`);
          });
        })
    }
    .width('100%').height('100%')
  }
}

对面的 DetailAbility.onCreate 就能拿到 want.parameters.itemId

5.2 带返回值的启动

需要拿到结果时,改用 startAbilityForResult

代码语言:javascript
复制
const result = await ctx.startAbilityForResult({
  bundleName: 'com.example.harmonydemo',
  abilityName: 'PickerAbility',
});
// result.resultCode / result.want.parameters
if (result.resultCode === 0) {
  const picked = result.want?.parameters?.['picked'] as string | undefined;
  console.info(`picked=${picked}`);
}

被启动的 Ability 在结束前调用:

代码语言:javascript
复制
this.context.terminateSelfWithResult({
  resultCode: 0,
  want: {
    parameters: { picked: 'apple' },
  },
});

5.3 启动模式

module.json5 里通过 launchType 控制:

launchType

语义

singleton

全局单实例,再次启动复用

multiton

每次启动都新建实例

specified

由 onAcceptWant 决定实例的 key,自定义复用逻辑

大多数首页/主入口用 singleton;文档编辑器这种“每个文档一个 Ability 实例”的场景用 specified

六、AbilityStage:模块级初始化的正确位置

同一个 HAP 里若干 Ability 共用一个 AbilityStage,非常适合放模块级初始化:

代码语言:javascript
复制
import AbilityStage from '@ohos.app.ability.AbilityStage';
import hilog from '@ohos.hilog';

export default class EntryAbilityStage extends AbilityStage {
  onCreate(): void {
    hilog.info(0x0000, 'AbilityStage', 'module loaded');
    // 初始化:埋点 SDK、Crash 上报、全局路由表、依赖注入容器等
  }

  onAcceptWant(want): string {
    // launchType=specified 时决定实例 key
    return want.parameters?.['instanceKey'] as string ?? 'default';
  }
}

module.json5 中注册:

代码语言:javascript
复制
{
  "module": {
    "srcEntry": "./ets/entryability/EntryAbilityStage.ets",
    "abilities": [ /* ... */ ]
  }
}

不要把这些初始化塞进每个 UIAbility 的 onCreate,否则多入口场景会重复执行。

七、常见坑与调试建议

1. onCreate 里操作 UI:此时 WindowStage 还没准备好,操作窗口会 crash。UI 相关放 onWindowStageCreate

2. 在 onBackground 做重活:切后台后系统随时可能回收进程,长任务应该走后台任务能力,而不是在这里 await 一个大同步操作。

3. Ability 间共享数据:不要靠单例静态变量,跨进程时不可靠。优先用 Want.parameters 传参、PreferencesrelationalStore 持久化、EventHub/CommonEvent 广播。

4. 窗口大小监听:折叠屏、平板需要监听 windowStage.on('windowStageEvent', ...)window.on('windowSizeChange', ...),在 onWindowStageCreate 注册、onWindowStageDestroy 反注册。

5. 调试生命周期hdc shell aa dump -a 可以看到当前进程里所有 Ability 状态;hdc shell aa start -a AbilityName -b BundleName 可以在命令行直接拉起,方便复现。

八、小结

Ability 是 HarmonyOS 应用的运行时骨架,掌握它需要抓住三件事:

  • 分层清晰:AbilityStage 管模块级别,UIAbility 管一个可见入口,ExtensionAbility 管无界面能力。
  • 生命周期节奏:onCreate → onWindowStageCreate → onForeground 是启动主线;onBackground / onForeground 会反复;onWindowStageDestroy → onDestroy 是终点。
  • 通信统一走 Want:跨 Ability、跨应用、带结果回调,全都是 Want 描述 + startAbility* 系列 API。

打好这层地基,后面做页面路由、多入口、原子化服务、卡片能力时才不会脚下打滑。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • HarmonyOS Ability 基础与生命周期实战
    • 一、Ability 是什么
    • 二、Ability、AbilityStage 和 Module 的关系
    • 三、UIAbility 生命周期状态机
    • 四、一个最小可运行的 UIAbility
    • 五、Ability 之间的启动与参数传递
      • 5.1 启动另一个 UIAbility
      • 5.2 带返回值的启动
      • 5.3 启动模式
    • 六、AbilityStage:模块级初始化的正确位置
    • 七、常见坑与调试建议
    • 八、小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档