新手学鸿蒙——02-UIAbility组件深度解析
本文深入解析了鸿蒙系统中的UIAbility组件,涵盖其核心概念、生命周期管理和启动模式。UIAbility作为界面展示和用户交互的核心组件,具有界面管理、生命周期处理、数据传递等职责。文章详细介绍了onCreate、onWindowStageCreate等生命周期回调的使用场景和代码示例,并对比分析了multiton(默认)、singleton和specified三种启动模式的特点及适用场景。通
新手学鸿蒙——UIAbility组件深度解析
前言
在上一篇《应用架构设计原则》中,我们初步了解了 UIAbility 的概念。本文将深入探讨 UIAbility 组件的方方面面,包括生命周期管理、启动模式、跨 Ability 通信等核心技能。
学习目标:掌握 UIAbility 的完整开发能力,能够独立设计多 Ability 应用架构。
一、UIAbility 是什么?
1.1 定义
UIAbility 是 HarmonyOS 应用中负责界面展示和用户交互的核心组件。可以类比为 Android 的 Activity 或 iOS 的 ViewController,但能力更强大。
1.2 核心职责
| 职责 | 说明 |
|---|---|
| 界面管理 | 加载页面、管理窗口 |
| 生命周期 | 处理创建、前后台切换、销毁等事件 |
| 用户交互 | 响应用户操作,处理输入事件 |
| 数据传递 | 接收启动参数,返回处理结果 |
| 资源管理 | 申请和释放系统资源 |
二、生命周期回调详解
2.1 完整生命周期流程
应用启动
↓
┌─────────────┐
│ onCreate │ 初始化数据、恢复状态
└──────┬──────┘
↓
┌──────────────────┐
│onWindowStageCreate│ 创建窗口、设置UI内容
└──────┬───────────┘
↓
┌──────────────┐
│ onForeground │ 获取焦点、恢复动画
└──────┬───────┘
↓
【用户交互】
↓
┌──────────────┐
│ onBackground │ 暂停动画、保存临时数据
└──────┬───────┘
↓
┌───────────────────┐
│onWindowStageDestroy│ 释放窗口资源
└──────┬────────────┘
↓
┌─────────────┐
│ onDestroy │ 释放所有资源
└─────────────┘
2.2 回调方法详解
onCreate()
触发时机:Ability 首次创建时调用,整个生命周期只调用一次。
使用场景:
- 初始化全局变量
- 恢复持久化数据
- 注册全局监听器
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
export default class MainAbility extends UIAbility {
// 全局变量
private userData: any = null;
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
console.log('[MainAbility] onCreate');
// 恢复用户数据
const savedData = want.parameters?.userData;
if (savedData) {
this.userData = JSON.parse(savedData as string);
console.log('恢复用户数据:', this.userData);
}
// 初始化全局状态
this.initGlobalState();
}
private initGlobalState(): void {
// 初始化全局状态管理
console.log('初始化全局状态');
}
}
onWindowStageCreate()
触发时机:WindowStage 创建完成后调用。
使用场景:
- 设置主窗口内容
- 加载初始页面
- 配置窗口属性
import window from '@ohos.window';
onWindowStageCreate(windowStage: window.WindowStage): void {
console.log('[MainAbility] onWindowStageCreate');
// 1. 设置窗口全屏
windowStage.getMainWindow().then((win) => {
win.setWindowLayoutFullScreen(true);
});
// 2. 加载主页面
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
console.error('加载页面失败:', err.message);
return;
}
console.log('加载页面成功');
});
}
onForeground()
触发时机:Ability 从后台切换到前台,用户可见。
使用场景:
- 恢复动画
- 重新连接网络
- 刷新数据
onForeground(): void {
console.log('[MainAbility] onForeground');
// 恢复动画
this.resumeAnimation();
// 刷新数据
this.refreshData();
}
private resumeAnimation(): void {
console.log('恢复动画播放');
}
private refreshData(): void {
console.log('刷新页面数据');
// 调用 API 刷新数据
}
onBackground()
触发时机:Ability 从前台切换到后台,用户不可见。
使用场景:
- 暂停动画
- 保存临时数据
- 释放部分资源
onBackground(): void {
console.log('[MainAbility] onBackground');
// 暂停动画节省性能
this.pauseAnimation();
// 保存临时数据
this.saveTempData();
}
private pauseAnimation(): void {
console.log('暂停动画播放');
}
private saveTempData(): void {
console.log('保存临时数据');
// 使用 Preferences 保存临时数据
}
onDestroy()
触发时机:Ability 销毁时调用。
使用场景:
- 释放资源
- 取消监听器
- 保存持久化数据
onDestroy(): void {
console.log('[MainAbility] onDestroy');
// 取消网络请求
this.cancelNetworkRequests();
// 释放资源
this.releaseResources();
}
private cancelNetworkRequests(): void {
console.log('取消所有网络请求');
}
private releaseResources(): void {
console.log('释放资源');
}
三、启动模式深度解析
3.1 multiton 模式(默认)
特点:每次启动都创建新实例。
配置方式:
// module.json5
{
"module": {
"abilities": [
{
"name": "DetailAbility",
"launchType": "multiton"
}
]
}
}
应用场景:
- 详情页(每次打开不同商品详情)
- 聊天会话页
- 浏览器标签页
实例:
用户操作序列:
1. 打开商品A详情 → 创建 DetailAbility 实例1
2. 打开商品B详情 → 创建 DetailAbility 实例2
3. 打开商品C详情 → 创建 DetailAbility 实例3
结果:同时存在3个 DetailAbility 实例
3.2 singleton 模式
特点:全局唯一实例,每次启动复用同一实例。
配置方式:
{
"abilities": [
{
"name": "MainAbility",
"launchType": "singleton"
}
]
}
应用场景:
- 主页面
- 设置页面
- 个人中心
实例:
用户操作序列:
1. 启动应用 → 创建 MainAbility 实例
2. 跳转详情页
3. 返回主页 → 复用 MainAbility 实例
结果:始终只有一个 MainAbility 实例
3.3 specified 模式
特点:根据指定的 Key 决定是否创建新实例。
使用场景:多账号、多窗口等复杂场景。
配置方式:
{
"abilities": [
{
"name": "ChatAbility",
"launchType": "specified"
}
]
}
代码实现:
// 启动方代码
import common from '@ohos.app.ability.common';
// 启动指定的聊天会话
startChat(contactId: string) {
const context = getContext(this) as common.UIAbilityContext;
const want: Want = {
bundleName: 'com.example.chat',
abilityName: 'ChatAbility',
parameters: {
// 指定实例的唯一标识
'instanceKey': contactId
}
};
context.startAbility(want);
}
// ChatAbility.ets
import UIAbility from '@ohos.app.ability.UIAbility';
export default class ChatAbility extends UIAbility {
// 必须实现此方法
onAcceptWant(want: Want): string {
// 返回实例标识
return want.parameters?.instanceKey as string;
}
}
效果:
启动序列:
1. 启动聊天会话 user_001 → 创建实例 user_001
2. 启动聊天会话 user_002 → 创建实例 user_002
3. 再次启动聊天会话 user_001 → 复用实例 user_001
结果:2个实例(user_001 和 user_002)
四、UIAbility 之间的数据传递
4.1 启动 Ability 并传递参数
发送方:
import common from '@ohos.app.ability.common';
import Want from '@ohos.app.ability.Want';
// 启动详情页并传递商品ID
function openDetailPage(productId: string) {
const context = getContext(this) as common.UIAbilityContext;
const want: Want = {
bundleName: 'com.example.myapp',
abilityName: 'DetailAbility',
parameters: {
'productId': productId,
'source': 'home'
}
};
context.startAbility(want)
.then(() => {
console.log('启动详情页成功');
})
.catch((err: Error) => {
console.error('启动详情页失败:', err.message);
});
}
接收方:
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
export default class DetailAbility extends UIAbility {
private productId: string = '';
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
// 接收传递过来的参数
this.productId = want.parameters?.productId as string;
console.log('商品ID:', this.productId);
}
}
4.2 启动 Ability 并获取返回结果
调用方:
async function openSettings(): Promise<void> {
const context = getContext(this) as common.UIAbilityContext;
const result = await context.startAbilityForResult({
bundleName: 'com.example.myapp',
abilityName: 'SettingsAbility'
});
if (result.resultCode === 0) {
console.log('返回数据:', result.want?.parameters);
}
}
被调用方:
function saveAndReturn(): void {
this.context.terminateSelfWithResult({
resultCode: 0,
want: {
parameters: { 'themeChanged': true }
}
});
}
五、实战案例:登录状态管理
完整实现登录功能,包含:
- 未登录跳转登录页
- 登录成功返回主页
- 登录信息全局共享
详细代码已在本文提供,请参考上文。
六、常见问题 FAQ
Q1:UIAbility 和 Page 有什么区别?
UIAbility 是应用级组件,Page 是页面级组件。普通页面跳转使用 Page。
Q2:什么时候创建新 UIAbility?
需要独立启动入口或隔离生命周期时创建。
Q3:如何共享数据?
使用 AppStorage、Preferences 或数据库。
七、总结
本文要点:
- ✅ UIAbility 生命周期管理
- ✅ 三种启动模式详解
- ✅ Ability 间数据传递
- ✅ 登录状态管理实战
下一篇预告:《新手学鸿蒙——应用进程与线程模型》
更多推荐



所有评论(0)