











本文档基于HarmonyOS NEXT API 12+官方标准,系统讲解Stage模型的核心概念、架构设计、开发流程与企业级最佳实践,帮助开发者快速掌握Stage模型下的应用开发能力,构建高性能、可扩展的企业级应用。
官方定位
Stage模型是HarmonyOS主推的应用模型,采用面向对象的设计思想,支持多窗口、多设备、分布式能力,是未来HarmonyOS应用开发的标准范式。FA模型已进入维护阶段,新应用建议全部采用Stage模型开发。
Stage模型采用"UIAbility-UI页面-组件"的三层架构:
应用 → UIAbility(1-N个) → AbilityStage → UI页面(1-N个) → 自定义组件 → 基础组件
每个UIAbility对应一个独立的业务模块,拥有独立的上下文和生命周期
|
组件 |
作用 |
说明 |
|
UIAbility |
应用组件入口 |
对应一个独立的业务模块,拥有独立的生命周期和窗口,支持单独启动 |
|
AbilityStage |
运行时容器 |
UIAbility的运行容器,同一工程中所有UIAbility共享同一个AbilityStage实例 |
|
WindowStage |
窗口管理器 |
管理UIAbility的窗口,包括窗口大小、位置、显示隐藏等 |
|
Context |
上下文环境 |
提供应用运行时环境,可获取资源、启动Ability、访问系统服务等 |
|
Router |
页面路由 |
管理UI页面之间的跳转、参数传递、回退等操作 |
|
特性 |
Stage模型 |
FA模型 |
|
架构设计 |
面向对象,组件化架构 |
面向页面,轻量架构 |
|
进程模型 |
支持多进程、多实例 |
单进程、单实例 |
|
窗口管理 |
多窗口支持,窗口独立管理 |
单窗口限制 |
|
分布式能力 |
原生支持分布式调度 |
分布式能力有限 |
|
生命周期 |
完善的生命周期管理 |
生命周期相对简单 |
|
代码复用 |
高,支持组件级、模块级复用 |
较低,页面级复用 |
|
适用场景 |
复杂应用、多模块应用、分布式应用 |
简单应用、单页面应用 |
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
import type AbilityConstant from '@ohos.app.ability.AbilityConstant';
import type Want from '@ohos.app.ability.Want';
export default class EntryAbility extends UIAbility {
/**
* Ability创建时调用,全局只调用一次
* @param want 启动参数
* @param launchParam 启动参数
*/
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
console.log('Ability onCreate');
// 全局初始化操作:初始化SDK、配置全局参数等
}
/**
* Ability变为可见时调用
*/
onWindowStageCreate(windowStage: window.WindowStage): void {
console.log('Ability onWindowStageCreate');
// 加载页面,设置UI
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
console.error('加载页面失败', JSON.stringify(err));
return;
}
// 获取窗口实例,设置窗口属性
windowStage.getMainWindow((err, window) => {
if (!err) {
window.setLayoutFullScreen(true); // 全屏显示
}
});
});
}
/**
* Ability进入前台时调用
*/
onForeground(): void {
console.log('Ability onForeground');
// 恢复暂停的操作:恢复动画、重新注册监听等
}
/**
* Ability进入后台时调用
*/
onBackground(): void {
console.log('Ability onBackground');
// 暂停不必要的操作:暂停动画、注销监听、释放资源等
}
/**
* Ability窗口销毁时调用
*/
onWindowStageDestroy(): void {
console.log('Ability onWindowStageDestroy');
// 释放窗口相关资源
}
/**
* Ability销毁时调用
*/
onDestroy(): void {
console.log('Ability onDestroy');
// 全局资源释放:关闭数据库、注销全局监听等
}
}
@Entry
@Component
struct IndexPage {
/**
* 页面创建时调用,每次进入页面都会调用
*/
aboutToAppear(): void {
console.log('页面 aboutToAppear');
// 页面初始化:加载数据、注册页面级监听
}
/**
* 页面布局完成后调用
*/
onPageShow(): void {
console.log('页面 onPageShow');
// 页面显示时的操作:恢复播放、更新数据等
}
/**
* 页面即将隐藏时调用
*/
onPageHide(): void {
console.log('页面 onPageHide');
// 页面隐藏时的操作:暂停播放、保存状态等
}
/**
* 页面销毁时调用
*/
aboutToDisappear(): void {
console.log('页面 aboutToDisappear');
// 页面资源释放:注销监听、取消请求等
}
build() {
Column() {
Text('首页')
.fontSize(30)
}
.width('100%')
.height('100%')
}
}
1. 应用冷启动:onCreate → onWindowStageCreate → onForeground → aboutToAppear → onPageShow
2. 应用切后台:onPageHide → onBackground
3. 应用切前台:onForeground → onPageShow
4. 页面跳转:新页面aboutToAppear → 旧页面onPageHide → 新页面onPageShow
5. 页面回退:旧页面onPageShow → 新页面aboutToDisappear
6. 应用退出:onPageHide → onBackground → onWindowStageDestroy → onDestroy
entry/src/main/
├── ets/ # 业务代码目录
│ ├── entryability/ # Ability入口
│ │ └── EntryAbility.ets
│ ├── pages/ # 页面文件
│ │ ├── Index.ets
│ │ ├── Login.ets
│ │ └── UserCenter.ets
│ ├── common/ # 公共资源
│ │ ├── components/ # 公共组件
│ │ ├── utils/ # 工具函数
│ │ ├── constants/ # 常量定义
│ │ └── api/ # 网络请求
│ ├── features/ # 业务特性模块
│ │ ├── home/ # 首页模块
│ │ ├── product/ # 商品模块
│ │ └── order/ # 订单模块
│ └── router/ # 路由配置
├── resources/ # 资源文件
│ ├── base/ # 基础资源
│ │ ├── element/ # 字符串、颜色、数值等
│ │ ├── media/ # 图片、音视频等
│ │ └── profile/ # 配置文件
│ ├── en_US/ # 英文资源
│ └── zh_CN/ # 中文资源
└── module.json5 # 模块配置文件
{
"module": {
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"deviceTypes": [
"phone",
"tablet"
],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:main_pages", // 页面路由配置
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:icon",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
]
}
]
}
}
{
"src": [
"pages/Index",
"pages/Login",
"pages/UserCenter",
"pages/product/ProductList",
"pages/product/ProductDetail",
"pages/order/OrderList",
"pages/order/OrderDetail"
]
}
import router from '@ohos.router';
// 基础跳转
router.pushUrl({
url: 'pages/Login'
});
// 带参数跳转
router.pushUrl({
url: 'pages/product/ProductDetail',
params: {
productId: '123456',
productName: '华为Mate 60 Pro'
}
});
// 替换当前页面
router.replaceUrl({
url: 'pages/Home'
});
// 返回上一页
router.back();
// 返回指定页面
router.back({
url: 'pages/Home'
});
// 清空页面栈并跳转
router.clear();
router.pushUrl({ url: 'pages/Login' });
import router from '@ohos.router';
@Entry
@Component
struct ProductDetailPage {
@State productId: string = '';
@State productName: string = '';
aboutToAppear() {
// 获取路由参数
const params = router.getParams() as Record; if (params) { this.productId = params.productId; this.productName = params.productName; } // 根据productId加载商品详情 this.loadProductDetail(this.productId); } loadProductDetail(productId: string) { // 加载商品详情逻辑 } build() { Column() { Text(`商品ID: ${this.productId}`) Text(`商品名称: ${this.productName}`) } .width('100%') .height('100%') } }
import common from '@ohos.app.ability.common';
import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
// 获取全局Context
const context = getContext(this) as common.UIAbilityContext;
// 1. 启动其他Ability
context.startAbility({
bundleName: 'com.example.myapp',
abilityName: 'SecondAbility'
});
// 2. 获取资源
const appName = context.resourceManager.getStringSync($r('app.string.app_name').id);
const icon = context.resourceManager.getMediaContentSync($r('app.media.icon').id);
// 3. 权限申请
let atManager = abilityAccessCtrl.createAtManager();
atManager.requestPermissionsFromUser(context, [
'ohos.permission.INTERNET',
'ohos.permission.LOCATION'
]).then((result) => {
console.log('权限申请结果', JSON.stringify(result));
});
// 4. 获取应用信息
const appInfo = context.applicationInfo;
console.log('应用包名', appInfo.bundleName);
console.log('应用版本', appInfo.versionName);
// 5. 获取目录路径
const cacheDir = context.cacheDir; // 缓存目录
const filesDir = context.filesDir; // 文件目录
const tempDir = context.tempDir; // 临时目录
// 在Ability的onCreate中初始化全局状态
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
// 初始化用户信息
AppStorage.setOrCreate('userInfo', null); // 初始化登录状态 AppStorage.setOrCreate('isLogin', false); // 初始化主题 AppStorage.setOrCreate('theme', 'light'); } // 在页面中使用全局状态 @Entry @Component struct UserCenterPage { @StorageLink('userInfo') userInfo: UserInfo = null; @StorageLink('isLogin') isLogin: boolean = false; build() { Column() { if (this.isLogin) { Text(`欢迎回来,${this.userInfo?.name}`) Button('退出登录') .onClick(() => { this.logout(); }) } else { Button('去登录') .onClick(() => { router.pushUrl({ url: 'pages/Login' }); }) } } } logout() { // 清除全局状态 AppStorage.set('userInfo', null); AppStorage.set('isLogin', false); // 跳转到登录页 router.clear(); router.pushUrl({ url: 'pages/Login' }); } }
在DevEco Studio中右键点击模块 → New → Ability,选择模板后自动生成Ability相关文件,自动更新module.json5配置。
// 在AbilityA中启动AbilityB并传递参数
const context = getContext(this) as common.UIAbilityContext;
context.startAbility({
bundleName: 'com.example.myapp',
abilityName: 'AbilityB',
parameters: {
userId: '123',
userName: '张三'
}
}, (err) => {
if (err) {
console.error('启动AbilityB失败', err);
}
});
// 在AbilityB的onCreate中接收参数
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
const userId = want.parameters?.userId as string;
const userName = want.parameters?.userName as string;
console.log('接收参数', userId, userName);
}
// AbilityB返回结果给AbilityA
// AbilityA中使用startAbilityForResult
context.startAbilityForResult({
bundleName: 'com.example.myapp',
abilityName: 'AbilityB'
}).then((result) => {
console.log('AbilityB返回结果', JSON.stringify(result));
const code = result.resultCode;
const data = result.want?.parameters;
});
// AbilityB中设置返回结果
const context = getContext(this) as common.UIAbilityContext;
context.terminateSelfWithResult({
resultCode: 0, // 0表示成功
want: {
parameters: {
result: '操作成功'
}
}
});
// 创建新窗口
import window from '@ohos.window';
const context = getContext(this) as common.UIAbilityContext;
window.createWindow(context, 'second_window', window.WindowType.TYPE_APPLICATION).then((win) => {
// 设置窗口大小和位置
win.resize(600, 800);
win.moveTo(100, 100);
// 加载页面
win.loadContent('pages/SecondWindow');
// 显示窗口
win.show();
});
// 获取所有窗口
window.getAllWindows().then((windows) => {
console.log('窗口数量', windows.length);
});
// 关闭指定窗口
window.findWindow('second_window').then((win) => {
win.destroy();
});
• 模块化拆分:按业务领域拆分为独立的Ability,每个Ability对应一个独立的业务模块
• 分层架构:采用UI层-业务逻辑层-数据层的三层架构,各层职责清晰
• 依赖注入:使用依赖注入框架管理对象依赖,降低耦合度
• 单一职责:每个Ability、页面、组件只负责单一功能
• 路由常量统一管理:所有页面路径定义为常量,避免硬编码
• 路由守卫:封装路由跳转方法,实现权限校验、登录拦截等功能
• 参数类型安全:定义路由参数接口,确保参数类型正确
• 页面栈管理:合理控制页面栈大小,避免页面层级过深
// 路由常量定义
export enum RouterPath {
HOME = 'pages/Index',
LOGIN = 'pages/Login',
USER_CENTER = 'pages/UserCenter',
PRODUCT_LIST = 'pages/product/ProductList',
PRODUCT_DETAIL = 'pages/product/ProductDetail'
}
// 路由参数类型定义
export interface ProductDetailParams {
productId: string;
productName?: string;
}
// 封装路由工具类
export class RouterUtil {
/**
* 跳转到商品详情页
* @param params 商品参数
*/
static goToProductDetail(params: ProductDetailParams): void {
// 登录校验
if (!AppStorage.get('isLogin')) { router.pushUrl({ url: RouterPath.LOGIN }); return; } // 跳转页面 router.pushUrl({ url: RouterPath.PRODUCT_DETAIL, params: params }); } }
• 懒加载:非首屏页面和组件使用懒加载,减少启动时间
• 资源优化:图片等资源按需加载,避免一次性加载过多资源
• 内存管理:在onBackground和onDestroy中及时释放大资源
• 启动优化:onCreate中只做必要的初始化,非必要操作延迟执行
• 异步操作:耗时操作全部异步执行,避免阻塞主线程
• 权限最小化:只申请必要的权限,避免过度申请
• 数据加密:敏感数据存储和传输时加密处理
• 输入校验:所有用户输入都要做合法性校验
• WebView安全:WebView启用安全配置,禁止执行不安全的JS代码
|
问题现象 |
解决方案 |
|
页面跳转时提示"路由不存在" |
检查页面路径是否正确,是否在main_pages.json中注册 |
|
获取Context时报错"context is undefined" |
确保在组件初始化完成后调用getContext,建议在aboutToAppear中获取 |
|
Ability启动缓慢 |
优化onCreate中的初始化逻辑,减少同步阻塞操作 |
|
页面跳转时参数丢失 |
避免传递大对象,参数类型支持JSON序列化 |
|
多窗口切换时状态丢失 |
使用AppStorage或持久化存储保存状态,避免依赖组件内部状态 |
|
后台运行时被系统杀死 |
关键状态及时持久化,Ability重启时恢复状态 |
|
权限申请被拒绝后功能异常 |
添加权限拒绝的友好提示和降级处理逻辑 |
1. ✅ 所有页面都在main_pages.json中正确注册
2. ✅ 路由跳转使用统一的常量路径,无硬编码
3. ✅ 生命周期方法中正确处理资源的申请与释放
4. ✅ 全局状态使用AppStorage等统一管理,避免跨组件传参混乱
5. ✅ 敏感权限申请有明确的使用说明和降级处理
6. ✅ 后台操作在应用切后台时正确暂停
7. ✅ 大对象、大资源在使用完后及时释放
8. ✅ 所有用户输入都做了合法性校验
9. ✅ 错误场景都有友好的用户提示
10. ✅ 页面跳转和返回逻辑符合用户操作习惯
学习建议
Stage模型是HarmonyOS开发的核心,建议开发者深入理解生命周期和Context机制,这是开发稳定可靠应用的基础。多动手实践,结合官方示例理解各种场景的处理方式。
文档版本:V1.0 | 适配版本:HarmonyOS NEXT API 12+ | 更新日期:2024年4月
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。