本文深入解析 ImportantDays 项目中的应用入口EntryAbility包括 UIAbility 的生命周期回调、初始化流程Preferences → Manager → 通知检查、窗口管理、前台提醒检查机制以及应用配置的关联关系。一、UIAbility 概述UIAbility是 HarmonyOS 应用的基本组成单元负责承载 UI 界面和处理生命周期。每个应用至少有一个 UIAbility 作为入口。应用启动 ↓ EntryAbility.onCreate() ↓ EntryAbility.onWindowStageCreate() ↓ 加载 MainEntry 页面 ↓ 用户交互 ↓ EntryAbility.onForeground() / onBackground() ↓ EntryAbility.onWindowStageDestroy() ↓ EntryAbility.onDestroy()二、EntryAbility 完整代码import{UIAbility,AbilityConstant,Want}fromkit.AbilityKit;import{window}fromkit.ArkUI;import{PreferenceUtil}from../utils/PreferenceUtil;import{NotificationUtil}from../utils/NotificationUtil;import{ImportantDayManager}from../viewmodel/ImportantDayManager;exportdefaultclassEntryAbilityextendsUIAbility{asynconCreate(want:Want,launchParam:AbilityConstant.LaunchParam):Promisevoid{console.info(EntryAbility onCreate);PreferenceUtil.init(this.context);ImportantDayManager.getInstance().init();consthasPermissionawaitNotificationUtil.checkPermission();if(hasPermission){awaitImportantDayManager.getInstance().checkAndSendReminders();}}onNewWant(want:Want,launchParam:AbilityConstant.LaunchParam):void{console.info(EntryAbility onNewWant);}onDestroy():void{console.info(EntryAbility onDestroy);}onWindowStageCreate(windowStage:window.WindowStage):void{console.info(EntryAbility onWindowStageCreate);windowStage.getMainWindow((err,win){if(err.code){console.error(Failed to get main window:,err);return;}// 沉浸式设置已注释});windowStage.loadContent(pages/MainEntry,(err){if(err.code){console.error(Failed to load content:,err);return;}console.info(Loaded MainEntry successfully);});}onWindowStageDestroy():void{console.info(EntryAbility onWindowStageDestroy);}onForeground():void{console.info(EntryAbility onForeground);ImportantDayManager.getInstance().checkAndSendReminders();}onBackground():void{console.info(EntryAbility onBackground);}}三、生命周期回调详解onCreateasynconCreate(want:Want,launchParam:AbilityConstant.LaunchParam):Promisevoid{console.info(EntryAbility onCreate);PreferenceUtil.init(this.context);ImportantDayManager.getInstance().init();consthasPermissionawaitNotificationUtil.checkPermission();if(hasPermission){awaitImportantDayManager.getInstance().checkAndSendReminders();}}调用时机Ability 实例首次创建时应用冷启动。执行流程1. PreferenceUtil.init(this.context) ↓ 初始化 Preferences 存储 2. ImportantDayManager.getInstance().init() ↓ 加载持久化数据 ↓ 构建 dayMap ↓ 检查并发送提醒 3. NotificationUtil.checkPermission() ↓ 检查通知权限 4. 如果有权限 → checkAndSendReminders() ↓ 发送到期提醒初始化顺序的重要性PreferenceUtil.init() ← 必须最先执行 ↓ ImportantDayManager.init() 依赖 PreferenceUtil ↓ Manager.init() 调用 PreferenceUtil.loadImportantDays()如果顺序反了PreferenceUtil.store为 null数据加载失败。onNewWantonNewWant(want:Want,launchParam:AbilityConstant.LaunchParam):void{console.info(EntryAbility onNewWant);}调用时机Ability 已存在实例通过 WantAgent 或其他方式再次启动时。场景用户点击通知打开应用但应用已在后台运行。当前实现仅打印日志未来可在此解析 Want 携带的参数实现精确跳转。onDestroyonDestroy():void{console.info(EntryAbility onDestroy);}调用时机Ability 实例被销毁时。当前实现仅打印日志数据已在每次操作时持久化无需额外处理。onWindowStageCreateonWindowStageCreate(windowStage:window.WindowStage):void{console.info(EntryAbility onWindowStageCreate);windowStage.getMainWindow((err,win){if(err.code){console.error(Failed to get main window:,err);return;}// win.setWindowLayoutFullScreen(true);// win.setWindowSystemBarProperties({ ... });});windowStage.loadContent(pages/MainEntry,(err){if(err.code){console.error(Failed to load content:,err);return;}console.info(Loaded MainEntry successfully);});}调用时机窗口舞台创建时onCreate 之后。执行流程获取主窗口windowStage.getMainWindow()当前沉浸式设置已注释预留功能加载主页面windowStage.loadContent(pages/MainEntry)加载MainEntry作为入口页面MainEntry使用 Tabs 组织三个 Tab 页面onWindowStageDestroyonWindowStageDestroy():void{console.info(EntryAbility onWindowStageDestroy);}调用时机窗口舞台销毁时应用被关闭。onForegroundonForeground():void{console.info(EntryAbility onForeground);ImportantDayManager.getInstance().checkAndSendReminders();}调用时机应用从后台回到前台时。核心功能每次回到前台都检查提醒确保用户不会错过在后台期间到期的提醒。onBackgroundonBackground():void{console.info(EntryAbility onBackground);}调用时机应用从前台进入后台时。当前实现仅打印日志。四、完整生命周期时序冷启动应用未运行 ↓ onCreate() ↓ 初始化数据 onWindowStageCreate() ↓ 加载页面 onForeground() ↓ 检查提醒 用户交互热启动从后台恢复应用在后台 ↓ 用户点击应用图标 / 通知 ↓ onForeground() ↓ 检查提醒 用户交互通知点击启动通知显示 ↓ 用户点击通知 ↓ WantAgent 触发 ↓ 应用已在运行 ├── 是 → onNewWant() → onForeground() └── 否 → onCreate() → onWindowStageCreate() → onForeground()退出应用用户退出 ↓ onBackground() ↓ onWindowStageDestroy() ↓ onDestroy()五、初始化流程详解第一步Preferences 初始化PreferenceUtil.init(this.context);this.contextAbility 的上下文用于确定存储路径PreferenceUtil.init使用getPreferencesSync同步创建 Preferences 实例必须在ImportantDayManager.init()之前执行第二步数据管理器初始化ImportantDayManager.getInstance().init();init()内部执行init():void{if(this.initialized)return;this.allDaysPreferenceUtil.loadImportantDays();// 依赖 Preferencesthis.rebuildDayMap();this.initializedtrue;this.checkAndSendReminders();// 初始化时也检查提醒}注意init()内部已经调用了checkAndSendReminders()但此时可能没有通知权限。第三步权限检查与提醒consthasPermissionawaitNotificationUtil.checkPermission();if(hasPermission){awaitImportantDayManager.getInstance().checkAndSendReminders();}由于init()中的checkAndSendReminders()可能在没有权限时执行这里再次检查权限并调用确保有权限时一定发送提醒。双重检查的设计考量// init() 内部的检查可能无权限this.checkAndSendReminders();// ↓ checkAndSendReminders 内部也检查权限// ↓ if (!hasPermission) return;// onCreate 中的显式检查consthasPermissionawaitNotificationUtil.checkPermission();if(hasPermission){awaitImportantDayManager.getInstance().checkAndSendReminders();}实际上checkAndSendReminders()内部已有权限检查onCreate中的显式检查是冗余的。但这种双重检查确保了可靠性——即使内部检查逻辑发生变化外部检查仍然保障。六、窗口管理获取主窗口windowStage.getMainWindow((err,win){if(err.code){console.error(Failed to get main window:,err);return;}// 沉浸式设置已注释});沉浸式状态栏预留/*win.setWindowLayoutFullScreen(true); win.setWindowSystemBarProperties({ statusBarContentColor: #333333, navigationBarContentColor: #333333 });*/这段代码被注释了但保留了沉浸式全屏的方案setWindowLayoutFullScreen(true)设置全屏布局setWindowSystemBarProperties设置状态栏和导航栏文字颜色加载主页面windowStage.loadContent(pages/MainEntry,(err){if(err.code){console.error(Failed to load content:,err);return;}console.info(Loaded MainEntry successfully);});pages/MainEntry对应MainEntry.ets文件中的Entry组件。七、与 module.json5 的关联{module:{mainElement:EntryAbility,abilities:[{name:EntryAbility,srcEntry:./ets/entryability/EntryAbility.ets,skills:[{entities:[entity.system.home],actions:[action.system.home]}]}]}}配置说明字段值说明mainElementEntryAbility应用入口 AbilitysrcEntry./ets/entryability/EntryAbility.ets源文件路径skillsentity.system.homeaction.system.home声明可从桌面启动WantAgent 与配置的对应// WantAgent 中的配置{bundleName:com.importantdays.app,abilityName:EntryAbility,action:action.system.home}必须与app.json5的bundleName和module.json5的abilities[0].name一致。八、前台提醒检查机制为什么每次回前台都检查场景 1. 用户早上 8 点打开应用设置了一个 3 天后提醒的重要日 2. 用户退出应用 3. 三天后重要日进入提醒范围 4. 用户下午 2 点打开应用 5. onForeground → checkAndSendReminders → 发送通知鸿蒙应用在后台时无法主动发送通知除非使用后台任务因此每次回到前台时检查是务实的解决方案。检查逻辑asynccheckAndSendReminders():Promisevoid{constneedReminderthis.getDaysNeedReminder();// needReminder 所有 shouldRemind() 返回 true 的重要日consthasPermissionawaitNotificationUtil.checkPermission();if(!hasPermission)return;for(constdayofneedReminder){consttitleday.isToday()?今天${day.title}:即将到来${day.title};constcontentday.getDisplayText();awaitNotificationUtil.publishBasic(title,content,this.getNotificationId(day.dayID));}}重复通知问题每次回前台都会发送通知可能导致重复通知。但由于使用稳定的通知 ID基于 dayID 哈希相同 ID 的通知会覆盖而非追加。九、总结EntryAbility的设计体现了以下原则初始化有序Preferences → Manager → 通知检查依赖关系清晰生命周期完整所有回调都有实现即使只是日志前台检查每次回前台检查提醒确保不遗漏错误处理窗口加载和内容加载都有错误检查配置一致与 app.json5 和 module.json5 保持对应EntryAbility是应用的入口点它的正确初始化是整个应用正常运行的基石。
企业数字化 ERP 产品动态
相关推荐
SolidWorks_钣金设计18_钣金工程图规范 钣金工程图规范:标注展开图、折弯线、折弯角度及下料尺寸的完整指南
摘要
钣金工程图是连接设计意图与制造工艺的核心技术文档。本文系统性地阐述了钣金工程图的规范标注方法,重点涵盖展开图的绘制与标注、折弯线的精确表达、折弯角度的标准标注以及下料… · 2026/9/23 15:54:05
SolidWorks_钣金设计17_钣金设计与装配 钣金设计与装配:在装配体中参考相邻零件设计配套的钣金支架
摘要
在机械产品开发过程中,钣金支架的设计往往需要与相邻零件紧密配合。传统的“孤立设计”方式容易导致装配干涉、孔位偏移等问题。本文将深入探讨如何在装配体环境中,利用参数化… · 2026/9/23 15:54:04
Flutter组件构建机制与build函数优化实践 1. 理解Flutter组件的核心机制在Flutter的世界里,组件(Widget)是构建用户界面的基本单元。每个Flutter应用都是由组件树构成的,而build函数则是这个体系中最关键的枢纽。作为开发者,我们需要深入理解build函数的工作原… · 2026/9/16 3:20:54
深度学习DOA估计入门:从数据生成到模型训练的避坑指南 简介:一份面向窄带信号波达方向(DOA)估计的 Python 深度学习入门代码包,供信号处理与机器学习初学者学习使用。DOA 估计旨在确定信号源相对接收阵列的方向,是雷达、通信与声学系统中的重要课题;窄带信号频率… · 2026/9/23 15:54:11
TM1640驱动详解:裸机GPIO模拟I²C时序与数码管控制 简介:本资源是一份面向嵌入式开发初学者与单片机爱好者的TM1640 LED数码管驱动程序实现,专为简化7段数码管显示控制而设计,适用于电子钟、计数器、简易仪表等常见应用场景。压缩包仅含2个核心文件(1个.h头文件与1个.c实现文件&… · 2026/9/23 15:54:11
DeepSeek+微表情分析:房地产精准获客与话术生成实战 简介:一份关于DeepSeek在房地产精准获客场景的技术方案文档,面向营销策划、NLP算法工程师及方案设计人员,提供从客户微表情识别到销售话术生成的完整思路。文档共一百三十七页,以PDF格式打包,大小约十一点零七兆字节&a… · 2026/9/23 15:54:05
夜间行人检测:5000张图三种格式标签与YOLO11跨平台训练 简介:面向夜间监控与低光行人检测需求,这套资源包含5000张真实场景夜间行人高质量图片,涉及夜间街景行人、道路行人、遮挡行人及严重遮挡行人等丰富场景,并采用LabelImg逐张标注,标注质量可靠,统一提供VOC(… · 2026/9/23 15:54:05
基于ffmpeg的Java音频处理SDK:从封装原理到实战避坑 简介:基于ffmpeg的Java音频处理SDK设计源码,面向需要处理音频格式转换与信息提取的Java开发者,旨在通过封装底层多媒体能力,降低音频处理功能的门槛。压缩包共27个文件,包含10个XML配置文件、7个Java源文件、2个Git忽略… · 2026/9/23 15:53:59
三万英尺等于多少米?开发者的单位换算速查手册 三万英尺等于多少米?开发者的单位换算速查手册 看了一堆教程还是不会写项目?别慌,很多时候卡住你的不是高深的架构,而是那些看似基础却极易出错的细节。今天咱们不聊虚的,直接拆解一个在面试和实际业务中经常“阴人”的小知识点: 三万英尺等于多少米… · 2026/9/23 15:53:59
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29