第6篇 | 战旗小游戏 HarmonyOS UIAbility——应用生命周期与工程配置

一、UIAbility 是什么?

在 HarmonyOS 应用开发中,**UIAbility** 是承载 UI 界面的核心组件,相当于 Android 的 `Activity`。一个应用可以有多个 UIAbility,每个 UIAbility 独立管理自己的 UI 生命周期和窗口。

该战旗项目只有一个 UIAbility:`EntryAbility`,它是整个应用的启动入口。

二、EntryAbility 完整代码解析

```

import UIAbility from '@ohos.app.ability.UIAbility';

import window from '@ohos.window';

export default class EntryAbility extends UIAbility {

// 窗口创建时调用

onWindowStageCreate(windowStage: window.WindowStage) {

// 设置窗口布局(非全屏)

windowStage.getMainWindow().then((win) => {

win.setWindowLayoutFullScreen(false);

});

// 加载首页

windowStage.loadContent('pages/Index', (err, data) => {

if (err.code) {

console.error('Failed to load the content. Cause: ' + JSON.stringify(err));

return;

}

});

}

onWindowStageDestroy() {

// 窗口销毁时释放 UI 相关资源

}

onForeground() {

// 应用进入前台(用户切换回来)

}

onBackground() {

// 应用进入后台(用户按 Home 键)

}

}

```

三、UIAbility 生命周期状态机

```

应用启动

onCreate(初始化)

onWindowStageCreate(创建窗口)

onForeground(前台运行) ←─────────┐

↓ │

用户按 Home 键 │

↓ │

onBackground(后台) │

↓ │

用户切回应用 ────────────────────────┘

onWindowStageDestroy(销毁窗口)

onDestroy(销毁)

```

各生命周期回调的职责

| 回调 | 触发时机 | 建议操作 |

|------|---------|---------|

| `onCreate` | Ability 创建(代码未展示)| 初始化全局数据 |

| `onWindowStageCreate` | 窗口创建好,可以加载页面 | 加载首页,配置窗口 |

| `onForeground` | 应用从后台切换到前台 | 恢复游戏计时器、刷新数据 |

| `onBackground` | 应用进入后台 | 保存游戏进度、暂停动画 |

| `onWindowStageDestroy` | 窗口即将销毁 | 释放 Canvas、停止计时器 |

| `onDestroy` | Ability 销毁 | 释放所有资源 |

四、加载首页:loadContent

```

windowStage.loadContent('pages/Index', (err, data) => {

if (err.code) {

console.error('Failed to load the content. Cause: ' + JSON.stringify(err));

return;

}

});

```

`loadContent` 加载的路径 `'pages/Index'` 对应 `entry/src/main/ets/pages/Index.ets`,框架自动解析路径和文件扩展名。

错误处理模式:

这里使用了 HarmonyOS API 的标准错误处理模式------回调函数的第一个参数 `err` 包含错误信息。如果 `err.code !== 0`,说明加载失败。

```

// 更健壮的写法:区分错误码

if (err.code) {

console.error(`Error code: {err.code}, message: {err.message}`);

return;

}

// 加载成功后的操作

```

五、窗口全屏配置

```

windowStage.getMainWindow().then((win) => {

win.setWindowLayoutFullScreen(false); // false = 非全屏(保留状态栏)

});

```

setWindowLayoutFullScreen参数:

  • `true`:全屏布局,UI 延伸到状态栏区域(沉浸式)

  • `false`:普通布局,状态栏不被遮挡

对于游戏应用,通常使用 `true` 实现沉浸式体验,本游戏选择了 `false` 保留顶部状态栏(方便看时间、信号等)。

Promise 链式调用:

```

windowStage.getMainWindow() // 返回 Promise<Window>

.then((win) => { // 获取窗口对象

win.setWindowLayoutFullScreen(false); // 配置窗口

});

```

`.then()` 是 Promise 的链式处理,`getMainWindow()` 是异步操作,需要等待获取到窗口对象后再配置。

六、module.json5 工程配置深度解析

```

{

"module": {

"name": "entry", // 模块名称(HAP 包名)

"type": "entry", // 模块类型:entry = 入口模块

"description": "Ancient Empire War Flag Game",

"mainElement": "EntryAbility", // 默认启动的 Ability

"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:icon", // 启动屏图标

"startWindowBackground": "$color:start_window_background", // 启动屏背景色

"visible": true,

"orientation": "unspecified" // 屏幕方向:不限制

}

]

}

}

```

关键字段说明

deviceTypes

```

"deviceTypes": "phone", "tablet"

```

声明本应用支持手机和平板,HarmonyOS 会根据设备类型调整部分行为(如界面适配)。

orientation

```json5

"orientation": "unspecified" // 跟随系统设置

```

也可以设为:

  • `"portrait"` --- 强制竖屏

  • `"landscape"` --- 强制横屏

战棋游戏通常横屏更好(更宽的地图视野),可以考虑改为 `"landscape"`。

资源引用语法

| 语法 | 说明 | 资源文件 |

|------|------|---------|

| `$string:name` | 字符串资源 | `element/string.json` |

| `$color:name` | 颜色资源 | `element/color.json` |

| `$media:name` | 媒体资源 | `resources/media/` |

| `$profile:name` | 配置文件 | `resources/profile/` |

七、页面路由配置

```

// resources/base/profile/main_pages.json

{

"src": [

"pages/Index.ets",

"pages/GamePage.ets"

]

}

```

**所有页面都必须在这里注册**,否则 `router.pushUrl({ url: 'pages/GamePage' })` 会报错找不到页面。

页面路径规则:

  • 相对于 `entry/src/main/ets/` 目录

  • 不需要写 `.ets` 扩展名(写了也不报错)

八、资源文件管理

string.json --- 字符串资源

```

{

"string": [

{ "name": "EntryAbility_label", "value": "远古帝国战旗" },

{ "name": "EntryAbility_desc", "value": "Ancient Empire War Flag Game" }

]

}

```

`EntryAbility_label` 是应用在桌面显示的名称,`EntryAbility_desc` 是应用描述。

color.json --- 颜色资源

```

{

"color": [

{ "name": "start_window_background", "value": "#F5DEB3" }

]

}

```

`start_window_background` 是启动屏的背景色(小麦色 `#F5DEB3`),与游戏主题色一致,减少启动时的视觉跳跃。

九、HarmonyOS 应用分层模型

```

应用(App)

└── HAP 包(module)

└── UIAbility(应用窗口)

└── WindowStage(窗口舞台)

└── Page(ArkUI 页面)

└── Component(ArkUI 组件)

```

从上到下依次:

  • **App**:应用标识,对应 AppScope

  • **HAP 包**:可独立安装的模块,`entry` 是入口 HAP

  • **UIAbility**:UI 容器,管理页面栈

  • **Page**:带 `@Entry` 的组件,一个页面一个文件

  • **Component**:不带 `@Entry` 的组件,可复用的 UI 片段

十、小结

`EntryAbility` 虽然代码简短,却是整个 HarmonyOS 应用的基石,负责窗口创建、页面加载和生命周期管理。理解 UIAbility 的生命周期对于处理游戏暂停/恢复、资源管理至关重要。

在实际游戏项目中,应该在 `onBackground` 中保存游戏进度,在 `onForeground` 中恢复,给玩家提供完整的后台恢复体验。