新手学鸿蒙——02-UIAbility组件深度解析

📅 2026/7/14 9:35:59 👁️ 阅读次数 📝 编程学习
新手学鸿蒙——02-UIAbility组件深度解析

新手学鸿蒙——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 间数据传递
  • ✅ 登录状态管理实战

下一篇预告:《新手学鸿蒙——应用进程与线程模型》