鸿蒙原生开发手记:徒步迹 - Stage 模型与UIAbility详解

深入理解鸿蒙 Stage 应用模型,掌握 UIAbility 生命周期


一、前言

HarmonyOS 的应用模型经历了从 FA(Feature Ability)模型到 Stage 模型的演进。Stage 模型是鸿蒙 NEXT 时代的主推架构,它提供了更清晰的生命周期管理、更好的模块化支持和更灵活的多实例管理能力。

本文将详细讲解 Stage 模型的核心概念,并结合"徒步迹"App 的 EntryAbility 实现进行实战分析。


二、Stage 模型 vs FA 模型

对比项 FA 模型 Stage 模型
架构复杂度 简单 中等
多实例支持 有限 原生支持
模块化 较弱 通过 HAP/HSP/HAR 灵活组织
生命周期 基础 更完善
推荐场景 简单应用 复杂应用(推荐)
兼容性 不再更新 当前主推

结论:新开发的应用统一使用 Stage 模型。


三、Stage 模型架构

Stage 模型的核心层级:

应用层(App)
  └── 模块层(Module: HAP/HSP/HAR)
       └── Ability 层(UIAbility / ExtensionAbility)
            └── 页面层(Page)
                 └── 组件层(Component)

3.1 关键概念

Ability:应用的功能单元,分为:

  • UIAbility:有 UI 界面的 Ability(如主界面)
  • ExtensionAbility:无 UI 的后台服务 Ability(如后台定位)

Module:功能模块,有三种类型:

  • HAP (Harmony Ability Package):可独立部署的应用包
  • HSP (Harmony Shared Package):共享库包
  • HAR (Harmony Archive):静态归档库

四、UIAbility 详解

UIAbility 是 Stage 模型中最核心的类,继承自 UIAbility 基类。

4.1 生命周期

import { UIAbility, AbilityConstant, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  // 1. Ability 创建时调用
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    console.info('[徒步迹] onCreate');
    // 初始化全局数据、数据库连接等
    AppStorage.setOrCreate('isLogged', false);
  }

  // 2. Ability 销毁时调用
  onDestroy(): void {
    console.info('[徒步迹] onDestroy');
    // 释放资源、保存状态
  }

  // 3. WindowStage 创建(**关键**:加载主页面)
  onWindowStageCreate(windowStage: window.WindowStage): void {
    console.info('[徒步迹] onWindowStageCreate');

    // 加载首页(启动页)
    windowStage.loadContent('pages/SplashPage', (err) => {
      if (err) {
        console.error(`加载失败: ${JSON.stringify(err)}`);
        return;
      }
    });
  }

  // 4. WindowStage 销毁
  onWindowStageDestroy(): void {
    console.info('[徒步迹] onWindowStageDestroy');
  }

  // 5. 切换到前台
  onForeground(): void {
    console.info('[徒步迹] onForeground');
  }

  // 6. 切换到后台
  onBackground(): void {
    console.info('[徒步迹] onBackground');
    // 保存应用状态,释放资源
  }
}

4.2 生命周期流程图

用户启动App
    ↓
onCreate()          ← 创建 Ability
    ↓
onWindowStageCreate()  ← 创建窗口,加载页面
    ↓
onForeground()      ← 进入前台(用户可见)
    ↓
  [应用正常运行]
    ↓
onBackground()      ← 进入后台(按Home键/切到其他App)
    ↓
  [系统可能回收]
    ↓
onForeground()      ← 重新回到前台
    ↓
onWindowStageDestroy()  ← 窗口销毁
    ↓
onDestroy()         ← Ability 销毁

五、Ability 启动模式

Stage 模型支持 3 种启动模式:

// module.json5 中配置 launchType
{
  "abilities": [
    {
      "name": "EntryAbility",
      "launchType": "singleton",  // 启动模式
    }
  ]
}
模式 说明 适用场景
singleton 单实例(默认) 主界面,只有一个实例
standard 多实例 需要独立多个实例时
multiton 多实例复用 类似浏览器多标签页

徒步迹 App 使用默认的 singleton 模式即可。


六、Want 与跨 Ability 通信

Want 是 Ability 间通信的载体,用于启动或传递数据:

// 启动另一个 UIAbility
function startAnotherAbility(context: Context): void {
  let want: Want = {
    bundleName: 'com.hiking.tuji',
    abilityName: 'AnotherAbility',
    parameters: {
      routeId: 123,
      fromPage: 'HomePage',
    },
  };

  context.startAbility(want, (err) => {
    if (err) {
      console.error(`启动失败: ${err.code}`);
    }
  });
}

// 接收参数(在目标 Ability 的 onCreate 中)
onCreate(want: Want): void {
  if (want?.parameters) {
    let routeId = want.parameters.routeId as number;
    console.log(`接收到 routeId: ${routeId}`);
  }
}

七、Context 能力

Context 是 Ability 运行时的上下文对象,提供了丰富的系统能力:

// 获取上下文
let context: Context = this.context;

// 获取应用信息
let bundleName: string = context.bundleName;
let versionCode: number = context.applicationInfo.versionCode;

// 获取文件路径
let cacheDir: string = context.cacheDir;
let tempDir: string = context.tempDir;
let filesDir: string = context.filesDir;

// 获取资源管理器
let resourceManager = context.resourceManager;

// 读取资源文件
let resMgr = resourceManager;
let stringValue = resMgr.getStringSync($r('app.string.app_name'));

八、实战:徒步迹的 EntryAbility

以下是"徒步迹"的 EntryAbility 完整实现:

// entryability/EntryAbility.ets
import { UIAbility, AbilityConstant, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    console.info('[徒步迹] EntryAbility onCreate');

    // 初始化全局应用存储
    AppStorage.setOrCreate<number>('stepCount', 0);
    AppStorage.setOrCreate<number>('todayDistance', 0);
    AppStorage.setOrCreate<number>('todayCalories', 0);
  }

  onDestroy(): void {
    console.info('[徒步迹] EntryAbility onDestroy');
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    console.info('[徒步迹] EntryAbility onWindowStageCreate');

    // 设置窗口属性
    windowStage.getMainWindow((err, mainWindow) => {
      if (!err) {
        // 设置全屏、状态栏等
        mainWindow.setWindowLayoutFullScreen(true);
        mainWindow.setWindowSystemBarEnable(['status', 'navigation']);
      }
    });

    // 加载启动页
    windowStage.loadContent('pages/SplashPage', (err) => {
      if (err) {
        console.error(`加载启动页失败: ${JSON.stringify(err)}`);
        return;
      }
      console.info('启动页加载成功');
    });
  }

  onWindowStageDestroy(): void {
    console.info('[徒步迹] EntryAbility onWindowStageDestroy');
  }

  onForeground(): void {
    console.info('[徒步迹] EntryAbility onForeground');
  }

  onBackground(): void {
    console.info('[徒步迹] EntryAbility onBackground');
  }
}

这是我们在项目中已经实现的 EntryAbility 代码,完整的文件路径为:
entry/src/main/ets/entryability/EntryAbility.ets


九、Application 与 AbilityStage

除了 UIAbility,Stage 模型还提供了应用级生命周期回调:

// 创建 AbilityStage(在 module.json5 中配置)
export default class MyAbilityStage extends AbilityStage {
  onCreate(): void {
    console.info('[徒步迹] AbilityStage onCreate');
    // 应用级初始化:日志系统、崩溃收集等
  }

  onAcceptWant(want: Want): string {
    // 多实例模式下返回实例标识
    return `instance_${Date.now()}`;
  }
}

在 module.json5 中配置:

{
  "module": {
    "name": "entry",
    "srcEntry": "./ets/myabilitystage/MyAbilityStage.ets",
    // ...
  }
}

十、总结

Stage 模型是鸿蒙 NEXT 应用开发的基石,理解 UIAbility 的生命周期对于构建稳定、高效的 App 至关重要。本文从模型对比、生命周期详解到实战代码,全面覆盖了 Stage 模型的核心知识。

下一篇文章我们将学习 Navigation 路由系统,实现页面间的无缝导航。


下一篇预告:鸿蒙原生开发手记:徒步迹 - 页面路由与Navigation导航

欢迎留言交流,一起探索鸿蒙开发。

Logo

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

更多推荐