Administrator
发布于 2026-09-02 / 1,131 阅读
0
0

Stage 模型 vs FA 模型:应用架构演进与迁移指南

系列文章《鸿蒙开发从入门到专家》第 42 篇 · 中级

上一篇聊 Web 组件时提到 UIAbility.onCreate,有读者问:UIAbility 和之前听过的 PageAbility 是什么关系?这个问题值得专门写一篇。

鸿蒙的应用模型经历了从 FA 模型到 Stage 模型的演进。如果你从 HarmonyOS 早期版本入门,可能习惯了 FA 模型的 Ability + AbilitySlice 结构。如果你从 API 9 之后开始学,DevEco Studio 默认创建的就是 Stage 模型。

这篇把两种模型的差异讲清楚,并给出迁移判断依据。

一、两种模型是什么

1.1 FA 模型(Feature Ability)

FA 模型是鸿蒙早期的应用架构,从 API 7 开始支持。它的核心设计是"每个组件独享一个 ArkTS 引擎实例"。

FA 模型有三种组件类型:

组件

作用

有无 UI

PageAbility

界面展示

有

ServiceAbility

后台服务

无

DataAbility

数据共享

无

开发方式是导出匿名对象、固定入口文件,开发者无法派生。简单说就是"填空式"开发——你在一个固定结构的文件里实现约定的方法,系统来调用。

1.2 Stage 模型

Stage 模型从 API 9 开始引入,是目前主推且长期演进的模型。核心设计变化是"多个组件共享同一个 ArkTS 引擎实例"。

组件体系重新设计:

组件

作用

UIAbility

承载 UI,与用户交互

ExtensionAbility

场景化扩展能力(卡片、输入法等)

开发方式改为面向对象,应用组件以类接口形式开放,可以派生和扩展。

1.3 最本质的区别

一句话:FA 模型每个组件独立进程 + 独立引擎,Stage 模型多组件共享引擎 + 分离渲染进程。

这个差异的影响是深远的:

  • FA 模型下,两个 PageAbility 之间传数据要走 IPC,序列化开销大。

  • Stage 模型下,UIAbility 之间可以直接共享对象和状态,不需要序列化。

  • Stage 模型内存占用更低,因为不需要为每个组件启动独立的引擎实例。

二、架构差异详解

2.1 进程模型对比

维度

FA 模型

Stage 模型

进程类型

主进程、渲染进程

主进程、ExtensionAbility 进程、渲染进程

引擎实例

每组件独享

多组件共享

状态共享

需要 IPC

直接共享对象

内存占用

较高

较低

2.2 配置文件差异

FA 模型使用 config.json,Stage 模型使用 module.json5。这个变化不只是换了个格式,而是配置粒度更细了。

FA 模型的 config.json:

{
  "app": {
    "bundleName": "com.example.app",
    "version": { "code": 1, "name": "1.0.0" }
  },
  "module": {
    "name": "entry",
    "type": "entry",
    "abilities": [
      {
        "name": "MainAbility",
        "type": "page",
        "visible": true
      }
    ]
  }
}

Stage 模型的 module.json5:

{
  "module": {
    "name": "entry",
    "type": "entry",
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ets",
        "startWindowIcon": "$media:startIcon",
        "startWindowBackground": "$color:start_window_background"
      }
    ],
    "extensionAbilities": [
      {
        "name": "FormAbility",
        "srcEntry": "./ets/formability/FormAbility.ets",
        "type": "form"
      }
    ]
  }
}

注意 srcEntry 字段——Stage 模型把组件入口指向了具体的 .ets 文件,组件的类定义就在那里。FA 模型没有这个,因为它是约定式入口。

2.3 生命周期对比

FA 模型有双生命周期——Ability 和 AbilitySlice 各自一套回调,加起来二十多个,容易混乱。

Stage 模型简化为 UIAbility 的四个核心回调:

export default class EntryAbility extends UIAbility {
  onCreate(want: Want): void {
    // 组件创建
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    // 窗口舞台创建,加载页面
    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        console.error('Failed to load content.');
      }
    });
  }

  onWindowStageDestroy(): void {
    // 窗口舞台销毁
  }

  onForeground(): void {
    // 进入前台
  }

  onBackground(): void {
    // 进入后台
  }
}

对比 FA 模型 PageAbility 的生命周期:onStart → onActive → onInactive → onBackground → onForeground → onStop,还有 AbilitySlice 自己的 onStart、onActive 等。两套回调嵌在一起,哪个先触发哪个后触发,文档得翻半天。

Stage 模型把"窗口管理"从"组件生命周期"中剥离出来。onWindowStageCreate / onWindowStageDestroy 管窗口,onForeground / onBackground 管前后台,各管各的。这个设计更清晰。

三、迁移判断:该不该迁

先说结论:HarmonyOS NEXT(纯血鸿蒙)已不支持 FA 模型。新项目必须用 Stage 模型。存量 FA 项目如果要在 NEXT 上跑,必须迁。

如果你维护的是 OpenHarmony 兼容版本(API 9 以下),可以暂时不迁,但建议尽早规划。

3.1 迁移的三个主要工作量

第一,组件类型映射。

FA 模型的组件到 Stage 模型的映射关系:

FA 模型组件

Stage 模型对应

PageAbility

UIAbility

ServiceAbility

没有直接对应,用 BackgroundTask 或 ExtensionAbility

DataAbility

DataShareExtensionAbility

ServiceAbility 的迁移最复杂。Stage 模型不再有独立的"后台服务"组件,后台任务由 WorkScheduler 或 BackgroundMode 管理。如果你的 ServiceAbility 里有大量后台逻辑,需要重新设计任务调度方式。

第二,导航方式重构。

FA 模型用 present 在 Ability 之间跳转:

// FA 模型导航
present({
  bundleName: 'com.example.app',
  abilityName: 'DetailAbility',
  parameters: { id: 123 }
});

Stage 模型用 Router 或 Navigation:

// Stage 模型导航
import { router } from '@kit.ArkUI';

router.pushUrl({
  url: 'pages/DetailPage',
  params: { id: 123 }
});

如果你的应用有大量 Ability 间跳转,导航重构是最大的工作量。建议趁迁移把页面级跳转统一到 Router,把 Ability 级跳转控制在少数几个入口。

第三,上下文获取方式。

FA 模型通过 featureAbility.getContext() 获取上下文。Stage 模型通过 this.context 获取:

// FA 模型
import featureAbility from '@ohos.ability.featureAbility';
const context = featureAbility.getContext();

// Stage 模型
// 在 UIAbility 中
const filesDir = this.context.filesDir;

// 在组件中
const context = getContext(this) as common.UIAbilityContext;

3.2 迁移策略

不建议一次性全量迁移。推荐增量迁移:

  1. 先把新功能模块用 Stage 模型开发。

  2. 把 FA 模型的导航入口逐步替换为 Router。

  3. 最后把旧 Ability 整体重写为 UIAbility。

DevEco Studio 没有提供自动迁移工具。迁移本质是重写组件入口和导航,自动转换的可靠性不够,手工迁移更可控。

四、一个容易被忽略的差异:窗口管理

FA 模型中,Ability 和窗口是绑定的。一个 PageAbility 对应一个窗口,生命周期和窗口强耦合。

Stage 模型引入了 WindowStage 概念。一个 UIAbility 可以管理多个窗口,窗口的创建和销毁独立于 UIAbility 的生命周期。

这个变化在以下场景有实际影响:

  • 多窗口应用:比如平板上的分栏布局,一个 UIAbility 可以创建多个窗口,每个窗口加载不同页面。

  • 悬浮窗:Stage 模型原生支持应用级悬浮窗,不需要像 FA 模型那样绕路。

  • 自由窗口:在 PC 或大屏上,Stage 模型支持自由调节窗口大小,窗口内容响应式适配。

// Stage 模型多窗口示例
onWindowStageCreate(windowStage: window.WindowStage): void {
  // 主窗口
  windowStage.loadContent('pages/Index');

  // 需要时创建子窗口
  const subWindow = windowStage.createSubWindow('subWindow');
  subWindow.loadContent('pages/SubPage', (err) => {
    if (!err.code) {
      subWindow.showWindow();
    }
  });
}

小结

决策点

结论

新项目

直接用 Stage 模型,没有悬念

存量 FA 项目

如果要在 HarmonyOS NEXT 上运行,必须迁

迁移工作量

导航重构 > 组件映射 > 上下文获取

迁移策略

增量迁移,先新后旧,先导航后组件

FA 模型不会获得任何新特性,它进入了维护期。Stage 模型是鸿蒙应用架构的未来,也是上一篇 Web 组件中 UIAbility 的来源。

下一篇我们进入 NAPI,聊聊 ArkTS 和 C++ 的混合编程。当 ArkTS 性能不够时,NAPI 是唯一的出路。


评论