当前位置: 首页 > news >正文

HarmonyOS应用开发实战:猫猫大作战-如何管理启动参数、初始化全局状态和预加载配置

前言

在 HarmonyOS 应用开发中,每个应用都有一个或多个Ability作为入口。其中UIAbility是包含 UI 界面的应用组件,负责管理应用窗口、生命周期和页面路由——它是整个应用的“大门“。

本文以「猫猫大作战」的EntryAbility.ets源码为主线,拆解 UIAbility 的完整生命周期、在module.json5中的注册方式,以及onWindowStageCreateloadContent的首屏加载链路,带你吃透 HarmonyOS 应用入口的核心机制。

提示:本系列不讲 ArkTS 基础语法与环境搭建,假设你已跟完第 1–70 篇。本篇是阶段三第 71 篇。

一、项目中的 EntryAbility

1.1 源码定位

打开「猫猫大作战」项目entry/src/main/ets/entryability/EntryAbility.ets,可以看到最精简的入口实现:

import { UIAbility, Want, AbilityConstant } from '@kit.AbilityKit'; import { window } from '@kit.ArkUI'; import { hilog } from '@kit.PerformanceAnalysisKit'; const TAG: string = 'EntryAbility'; const DOMAIN: number = 0xFF00; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { hilog.info(DOMAIN, TAG, '%{public}s', 'Ability onCreate'); } onDestroy() { hilog.info(DOMAIN, TAG, '%{public}s', 'Ability onDestroy'); } onWindowStageCreate(windowStage: window.WindowStage) { hilog.info(DOMAIN, TAG, '%{public}s', 'Ability onWindowStageCreate'); windowStage.loadContent('pages/Index', (err) => { if (err.code) { hilog.error(DOMAIN, TAG, 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } hilog.info(DOMAIN, TAG, '%{public}s', 'Succeeded in loading the content.'); }); } onWindowStageDestroy() { hilog.info(DOMAIN, TAG, '%{public}s', 'Ability onWindowStageDestroy'); } onForeground() { hilog.info(DOMAIN, TAG, '%{public}s', 'Ability onForeground'); } onBackground() { hilog.info(DOMAIN, TAG, '%{public}s', 'Ability onBackground'); } }

1.2 结构解析

元素说明来源
UIAbility基类,提供生命周期回调@kit.AbilityKit
Want启动参数,携带目标、数据@kit.AbilityKit
AbilityConstant启动原因常量@kit.AbilityKit
WindowStage窗口阶段,承载 UI 加载@kit.ArkUI
hilog系统日志工具@kit.PerformanceAnalysisKit

二、UIAbility 生命周期全景

2.1 六个核心回调

UIAbility 的生命周期包含6 个回调,调用顺序如下:

冷启动:onCreate → onWindowStageCreate → onForeground ↓ loadContent('pages/Index') ↓ Index 页面渲染(aboutToAppear → build → onDidBuild) ↓ 切后台:onBackground 切前台:onNewWant → onForeground ↓ 窗口销毁:onWindowStageWillDestroy → onWindowStageDestroy 应用退出:onDestroy

2.2 各回调用途速查

回调触发时机项目用途
onCreate首次创建 Ability 实例初始化全局配置、日志
onWindowStageCreateWindowStage 创建完成后加载首屏页面、订阅窗口事件
onForegroundAbility 进入前台恢复游戏/定位等资源
onBackgroundAbility 完全不可见暂停游戏、释放资源
onWindowStageDestroyWindowStage 销毁后释放 WindowStage 资源
onDestroyAbility 实例销毁前保存数据、释放全局资源

2.3 各回调生命周期表

import { UIAbility, Want, AbilityConstant } from '@kit.AbilityKit'; import { window } from '@kit.ArkUI'; import { hilog } from '@kit.PerformanceAnalysisKit'; const TAG = 'EntryAbility'; const DOMAIN = 0xFF00; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { // 冷启动时初始化一次:读取配置、初始化日志 hilog.info(DOMAIN, TAG, 'onCreate called'); // 此处可初始化全局数据,如 AppStorage 预置默认值 AppStorage.setOrCreate('highScore', 0); } onWindowStageCreate(windowStage: window.WindowStage): void { // WindowStage 创建后加载首屏 hilog.info(DOMAIN, TAG, 'onWindowStageCreate called'); // 订阅 WindowStage 事件(获焦/失焦) windowStage.on('windowStageEvent', (data) => { const eventType: window.WindowStageEventType = data; switch (eventType) { case window.WindowStageEventType.ACTIVE: hilog.info(DOMAIN, TAG, '窗口获焦'); break; case window.WindowStageEventType.INACTIVE: hilog.info(DOMAIN, TAG, '窗口失焦'); break; case window.WindowStageEventType.HIDDEN: hilog.info(DOMAIN, TAG, '窗口隐藏'); break; default: break; } }); // 加载首屏页面 windowStage.loadContent('pages/Index', (err) => { if (err.code) { hilog.error(DOMAIN, TAG, '加载页面失败: %{public}s', JSON.stringify(err)); return; } hilog.info(DOMAIN, TAG, '页面加载成功'); }); } onForeground(): void { hilog.info(DOMAIN, TAG, 'onForeground called'); // 回到前台:可恢复游戏引擎 } onBackground(): void { hilog.info(DOMAIN, TAG, 'onBackground called'); // 切到后台:可暂停游戏 } onWindowStageDestroy(): void { hilog.info(DOMAIN, TAG, 'onWindowStageDestroy called'); } onDestroy(): void { hilog.info(DOMAIN, TAG, 'onDestroy called'); // 保存高分到持久化存储 } }

三、module.json5 中的注册

3.1 配置结构

UIAbility 必须在module.json5中注册才能被系统识别。猫猫大作战的entry/src/main/module.json5

{ "module": { "name": "entry", "type": "entry", "deviceTypes": ["tablet", "phone", "wearable"], "deliveryWithInstall": true, "installationFree": false, "pages": "$profile:main_pages", "abilities": [ { "name": "EntryAbility", "srcEntry": "./ets/entryability/EntryAbility.ets", "description": "$string:EntryAbility_desc", "icon": "$media:app_icon", "label": "$string:EntryAbility_label", "startWindowIcon": "$media:app_icon", "startWindowBackground": "$color:start_window_background", "exported": true, "skills": [ { "actions": ["action.system.home"] } ] } ] } }

3.2 关键字段说明

字段含义
nameEntryAbilityAbility 名称,唯一标识
srcEntry./ets/entryability/EntryAbility.ets源码路径
exportedtrue允许其他应用通过 Want 启动
skills[0].actionsaction.system.home桌面图标入口
startWindowIcon$media:app_icon启动窗口图标
startWindowBackground$color:start_window_background启动窗口背景色

注意srcEntry路径相对于entry/src/main/目录。exportedtrue时,其他应用可通过startAbility启动你的 Ability。

四、启动流程时序

4.1 冷启动时序

用户点击桌面图标 ↓ Launcher 构造 Want → action.system.home ↓ AAFWK(Ability Manager Service)创建 UIAbility 实例 ↓ onCreate(want, launchParam) ← ① 第一次初始化 ↓ onWindowStageCreate(windowStage) ← ② 窗口创建 ↓ windowStage.loadContent('pages/Index') ← ③ 加载页面 ↓ Index.ets aboutToAppear → build → onDidBuild ← ④ 页面渲染 ↓ onForeground() ← ⑤ 进入前台 ↓ 用户可见、可交互

4.2 热启动(从后台回到前台)

用户从最近任务/桌面重新打开 ↓ onNewWant(want, launchParam) ← ① 携带新参数 ↓ onForeground() ← ② 进入前台 ↓ onPageShow() ← ③ Index 页面级回调

五、Want 与启动参数

5.1 Want 结构

onCreate中接收的Want参数包含了启动的完整信息:

// Want 的核心字段 interface Want { deviceId?: string; // 目标设备 ID(跨设备时使用) bundleName?: string; // 目标应用 Bundle 名称 abilityName?: string; // 目标 Ability 名称 uri?: string; // 通用资源标识符 type?: string; // MIME 类型 parameters?: Record<string, Object>; // 自定义参数 flags?: number; // 启动标记 }

5.2 在 EntryAbility 中解析启动参数

onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { // 解析启动原因 switch (launchParam.launchReason) { case AbilityConstant.LaunchReason.START_ABILITY: hilog.info(DOMAIN, TAG, '通过 startAbility 启动'); break; case AbilityConstant.LaunchReason.CALL: hilog.info(DOMAIN, TAG, '通过 call 启动'); break; case AbilityConstant.LaunchReason.CONTINUATION: hilog.info(DOMAIN, TAG, '通过跨端迁移启动'); break; case AbilityConstant.LaunchReason.APP_RECOVERY: hilog.info(DOMAIN, TAG, '通过应用恢复启动'); break; default: break; } // 解析自定义参数(比如通过 DeepLink 启动) const targetPage = want.parameters?.['targetPage'] as string; if (targetPage) { AppStorage.setOrCreate('targetPage', targetPage); } }

六、常见踩坑

6.1 坑一:loadContent 路径错误

// 🚫 错误:路径多了 src/ windowStage.loadContent('src/main/ets/pages/Index', ...); // ✅ 正确:路径相对于 entry/src/main/ets/ windowStage.loadContent('pages/Index', (err) => { if (err.code) { hilog.error(DOMAIN, TAG, '加载失败: %{public}s', JSON.stringify(err)); } });

6.2 坑二:忘记在 module.json5 注册

// 🚫 错误:只写了文件,没在 abilities 数组中注册 { "module": { "abilities": [] // ❌ 空的,系统找不到 EntryAbility } }

表现:应用启动直接闪退,报Cannot find ability

6.3 坑三:onBackground 中做耗时操作

// 🚫 错误:onBackground 中执行数据库写入等耗时操作 onBackground(): void { this.saveGameData(); // ❌ 可能耗时超过系统限制 } // ✅ 正确:在 onPageHide 或异步任务中处理 onBackground(): void { // 仅标记状态,不做耗时操作 AppStorage.set('isBackground', true); }

onBackground()执行时间极短,不适合做数据库事务、网络请求等操作。

七、HiLog 日志验证

7.1 日志输出

在 DevEco Studio 中运行应用并过滤EntryAbility,可以看到完整的生命周期调用链:

09:15:23.101 [INFO] EntryAbility: Ability onCreate 09:15:23.156 [INFO] EntryAbility: Ability onWindowStageCreate 09:15:23.201 [INFO] EntryAbility: Succeeded in loading the content. 09:15:23.225 [INFO] Index: Index aboutToAppear called 09:15:23.289 [INFO] Index: Index onDidBuild called 09:15:23.302 [INFO] EntryAbility: Ability onForeground

7.2 使用 hilog 替代 console

EntryAbility.ets中,官方推荐使用hilog而非console.log

方面consolehilog
性能未优化异步写入,不阻塞主线程
分级DEBUG/INFO/WARN/ERROR/FATAL
过滤按字符串按 DOMAIN + TAG
线上采集不支持支持 HiAppEvent 采集
// 推荐:在 EntryAbility 中使用 hilog import { hilog } from '@kit.PerformanceAnalysisKit'; hilog.info(0xFF00, 'EntryAbility', '应用启动完成');

八、总结

EntryAbility是 HarmonyOS 应用的起点,承载了冷启动初始化、窗口创建、首屏加载和前后台切换等核心职责。本文从「猫猫大作战」的实际源码出发,覆盖了 UIAbility 的六大生命周期回调、module.json5 注册规范、Want 参数解析和常见踩坑。

核心要点

  • UIAbility 生命周期:onCreateonWindowStageCreateonForeground/onBackgroundonDestroy
  • loadContent('pages/Index')负责加载首屏页面
  • module.json5中必须注册 Ability 才能被系统识别
  • onBackground不允许做耗时操作
  • hilog替代console.log进行日志输出

下一篇预告:第 72 篇将深入onCreate冷启动初始化,讲解如何管理启动参数、初始化全局状态和预加载配置。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

  • UIAbility 组件生命周期官方文档
  • UIAbility 概述
  • UIAbility 使用指导
  • module.json5 配置参考
  • Want 与启动参数文档
  • 开源鸿蒙跨平台社区
  • 第 72 篇:onCreate 冷启动初始化
  • 第 73 篇:loadContent 首屏绑定
http://www.jsqmd.com/news/1277843/

相关文章:

  • (2026最新)安康本地漏水检测维修公司靠谱推荐:正规防水补漏上门维修-墙面/屋顶/外墙/暗管漏水检测精准定位 - 即刻修防水
  • (2026最新)宜昌本地人必选的靠谱漏水检测维修推荐:正规防水补漏防水-卫生间/厨房/屋顶/阳台/外墙渗漏水精准测漏,本地人的信赖之选 - 安佳防水
  • 2024年最值得关注的Top-AI-Tools:从艺术创作到生产力工具全解析
  • Three.js代码生成工具实战:从环境配置到可维护项目落地
  • 自考论文写作工具:智能选题与结构化写作指南
  • 深度解析CamLaserCalibraTool相机模型:Pinhole与鱼眼相机参数设置全攻略
  • 5分钟掌握Winlator:在Android手机畅玩PC游戏的终极指南
  • 如何用Frappe框架在3天内构建企业级Web应用:终极低代码开发指南
  • 2026制造业:丙烯酸防锈底漆生产厂家采购指南 - 卓企推荐
  • 技术传播新范式:从黄仁勋现象看开发者影响力构建
  • ImageJ宏语言零基础教程:从录制到编写自动化脚本的完整指南
  • 如何免费提升视频画质:终极AI视频增强工具使用指南
  • 2026年财务报表分析软件推荐:功能与安全解析 - 科技焦点
  • 民宿怎么订才划算?超实用攻略教程,新手也能轻松订到低价好房 - 工具软件使用方法推荐
  • 开发者必看:Invio架构设计与核心代码实现原理详解
  • TileLang:用Python编写高性能GPU内核,实现CUDA级计算性能
  • EasyX跑酷游戏开发:重力系统与菜单实现
  • Android平台OPC UA服务器开发:Eclipse Milo实现与工业自动化应用
  • PasteMD终极指南:如何一键将AI内容完美粘贴到Office
  • 2026 年程序员找工作,为什么 AI 写出的代码反而成了简历的“硬伤”?
  • (2026最新)宜宾本地漏水检测维修公司靠谱推荐:正规防水补漏上门维修-墙面/屋顶/外墙/暗管漏水检测精准定位 - 即刻修防水
  • 2026年贵阳上门保洁如何选?可靠小程序深度解析 - 装修教育财税推荐2026
  • (2026最新)娄底本地人必选的靠谱漏水检测维修推荐:正规防水补漏防水-卫生间/厨房/屋顶/阳台/外墙渗漏水精准测漏,本地人的信赖之选 - 安佳防水
  • 民宿怎么订最便宜?亲测有效的省钱技巧,看完每次都能省一半! - 工具软件使用方法推荐
  • eSpeak NG技术深度解析:多语言语音合成引擎的架构设计与应用实践
  • C++实现协同过滤算法:构建超市外卖推荐系统毕业设计全解析
  • Open Dreamer:基于JAX/Flax的世界模型工程化实践指南
  • AI智能体研发 | 什么是OpenAI API协议
  • 黄仁勋X账号2天30万粉:技术内容传播的平台策略分析
  • 摄像头sc233hgs驱动 v4l2驱动层设置参数方法