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

新手学鸿蒙——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(): Promisevoid { 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 } } }); }五、实战案例登录状态管理完整实现登录功能包含未登录跳转登录页登录成功返回主页登录信息全局共享详细代码已在本文提供请参考上文。六、常见问题 FAQQ1UIAbility 和 Page 有什么区别UIAbility 是应用级组件Page 是页面级组件。普通页面跳转使用 Page。Q2什么时候创建新 UIAbility需要独立启动入口或隔离生命周期时创建。Q3如何共享数据使用 AppStorage、Preferences 或数据库。七、总结本文要点✅ UIAbility 生命周期管理✅ 三种启动模式详解✅ Ability 间数据传递✅ 登录状态管理实战下一篇预告《新手学鸿蒙——应用进程与线程模型》