鸿蒙掌上驾考宝典应用开发4:鸿蒙 EntryAbility 生命周期管理最佳实践
·
第4篇:鸿蒙 EntryAbility 生命周期管理最佳实践

一、UIAbility 概述
在鸿蒙应用开发中,UIAbility 是系统调度的基本单元,类似于 Android 的 Activity。每个应用至少有一个 EntryAbility,它负责管理应用窗口、页面加载和系统交互。DriverLicenseExam 项目的 EntryAbility.ets 文件展示了完整的生命周期管理实践。
二、EntryAbility 完整源码分析
2.1 核心生命周期方法
// products/entry/src/main/ets/entryability/EntryAbility.ets
import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
import { AppStorageV2, window } from '@kit.ArkUI';
import { Logger, PreferencesUtil } from '@ohos_agcit/driver_license_exam_commonlib';
import { BusinessError } from '@kit.BasicServicesKit';
export default class EntryAbility extends UIAbility {
private shareServiceImpl: ShareService =
ShareService.create()
.initWX('wxc92d9d6570127a32')
.initQQ(102061317);
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
Logger.info(TAG, 'Ability onCreate');
WantUtils.handlePushCall(want);
this.shareServiceImpl.handleWant(want, this.context);
}
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
this.setLightOrDarkMode(this.context);
WantUtils.handlePushWant(want);
this.shareServiceImpl.handleWant(want, this.context);
}
}
onCreate 在 Ability 首次创建时调用,适合进行初始化操作:
- 处理推送消息(WantUtils.handlePushCall)
- 初始化分享服务
- 设置全局变量
onNewWant 在 Ability 已存在但收到新的启动请求时调用:
- 恢复深色模式状态
- 处理新的推送消息
- 处理外部跳转参数
2.2 onWindowStageCreate——窗口创建的核心方法
public onWindowStageCreate(windowStage: window.WindowStage): void {
Logger.info(TAG, 'Ability onWindowStageCreate');
try {
windowStage.loadContent('pages/MainEntry', (err) => {
if (err.code) {
Logger.error(TAG, 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
// 加载成功后的初始化
try {
AppStorage.setOrCreate('windowStage', windowStage);
// 获取应用主窗口
let windowClass: window.Window = windowStage.getMainWindowSync();
// 设置窗口全屏
let isLayoutFullScreen = true;
windowClass.setWindowLayoutFullScreen(isLayoutFullScreen);
// 获取底部导航指示器避让区域
let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR;
let avoidArea = windowClass.getWindowAvoidArea(type);
let bottomRectHeight = avoidArea.bottomRect.height;
AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);
// 获取顶部状态栏避让区域
type = window.AvoidAreaType.TYPE_SYSTEM;
avoidArea = windowClass.getWindowAvoidArea(type);
let topRectHeight = avoidArea.topRect.height;
AppStorage.setOrCreate('topRectHeight', topRectHeight);
// 请求通知权限
notificationManager.requestEnableNotification(this.context);
// 注册监听函数,动态获取避让区数据
windowClass.on('avoidAreaChange', (data) => {
if (data.type === window.AvoidAreaType.TYPE_SYSTEM) {
AppStorage.setOrCreate('topRectHeight', data.area.topRect.height);
} else if (data.type === window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) {
AppStorage.setOrCreate('bottomRectHeight', data.area.bottomRect.height);
}
});
this.setLightOrDarkMode(this.context);
} catch (e) {
Logger.error(TAG, 'loadContent post-success error: %{public}s', JSON.stringify(e) ?? '');
}
});
} catch (e) {
Logger.error(TAG, 'loadContent failed: %{public}s', JSON.stringify(e) ?? '');
}
}
三、窗口管理的关键实践
3.1 全屏适配
设置窗口全屏布局,隐藏系统状态栏:
let isLayoutFullScreen = true;
windowClass.setWindowLayoutFullScreen(isLayoutFullScreen);
3.2 安全区域避让
鸿蒙设备有导航指示器、状态栏等系统 UI 区域,应用需要避开这些区域。项目通过 getWindowAvoidArea 获取避让区域尺寸:
// 获取底部导航指示器高度
let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR;
let avoidArea = windowClass.getWindowAvoidArea(type);
let bottomRectHeight = avoidArea.bottomRect.height;
AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);
// 获取顶部状态栏高度
type = window.AvoidAreaType.TYPE_SYSTEM;
avoidArea = windowClass.getWindowAvoidArea(type);
let topRectHeight = avoidArea.topRect.height;
AppStorage.setOrCreate('topRectHeight', topRectHeight);
3.3 动态监听避让区域变化
当用户滑动切换手势导航或三键导航时,避让区域会变化。项目通过 avoidAreaChange 事件动态监听:
windowClass.on('avoidAreaChange', (data) => {
if (data.type === window.AvoidAreaType.TYPE_SYSTEM) {
AppStorage.setOrCreate('topRectHeight', data.area.topRect.height);
} else if (data.type === window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) {
AppStorage.setOrCreate('bottomRectHeight', data.area.bottomRect.height);
}
});
3.4 页面中使用避让区域
在页面中读取全局避让高度,应用到布局:
// HomeView 中使用顶部避让
.padding({
top: this.getUIContext().px2vp(AppStorage.get('topRectHeight') || 0) + 10,
left: 16,
right: 16
})
// MainEntry 中使用底部避让
.padding({
bottom: this.getUIContext().px2vp(this.bottomRectHeight)
})
四、深色模式管理
4.1 状态恢复
在 onCreate 和 onNewWant 中恢复深色模式设置:
private setLightOrDarkMode(context: Context) {
const preferencesUtil = PreferencesUtil.getInstance();
const preference = preferencesUtil.getPreferences(context);
const value = preferencesUtil.getPreferencesValue(preference, 'lightDarkMode') || 0;
AppStorage.setOrCreate('lightDarkMode', value);
if (value === 0) {
// 跟随系统
context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
} else if (value === 1) {
// 强制浅色
context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT);
} else if (value === 2) {
// 强制深色
context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_DARK);
}
}
五、推送通知管理
5.1 推送权限申请
在 Ability 初始化时申请通知权限:
notificationManager.requestEnableNotification(this.context).then(() => {
hilog.info(0x0000, 'testTag', '[ANS] requestEnableNotification success');
}).catch((err: BusinessError) => {
hilog.error(0x0000, 'testTag',
'[ANS] requestEnableNotification failed, code is ${err.code}, message is ${err.message}');
});
5.2 推送消息处理
通过 Want 参数传递推送消息,在 Ability 的 onCreate 和 onNewWant 中处理:
// onCreate 中处理冷启动推送
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
WantUtils.handlePushCall(want);
}
// onNewWant 中处理热启动推送
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
WantUtils.handlePushWant(want);
}
六、外部跳转深度链接
6.1 深度链接处理
应用支持从外部跳转到指定页面,例如从推送通知跳转到练习页面:
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
if (want.parameters && want.parameters.params) {
let param: ESObject = {};
try {
param = JSON.parse(want.parameters.params as string);
} catch (e) {}
if (param.message === 'practiceView') {
// 跳转到模拟考试
const examService = ExamService.instance(this.context as Context);
const par: ROUTE_PARAM = {
title: '模拟考试',
type: EXAM_MANAGER_TYPE.mock_exam,
examManager: examService.getMockExamManager('模拟考试')
};
CommonModel.instance.navStack.replacePathByName('practiceView', par);
} else if (param.message === 'orderPractice') {
// 跳转到顺序练习
const param: ROUTE_PARAM = {
title: '顺序练习',
type: EXAM_MANAGER_TYPE.sequence
};
CommonModel.instance.navStack.replacePathByName('practiceView', param);
}
}
}
七、分享服务初始化
分享服务在 Ability 级别初始化,确保全局可用:
private shareServiceImpl: ShareService =
ShareService.create()
.initWX('wxc92d9d6570127a32')
.initQQ(102061317);
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
this.shareServiceImpl.handleWant(want, this.context);
}
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
this.shareServiceImpl.handleWant(want, this.context);
}
八、EntryAbility 完整生命周期流程图
系统启动应用
│
▼
onCreate() ← 初始化推送、分享服务
│
▼
onWindowStageCreate() ← 加载页面、设置窗口、获取避让区域
│
▼
页面加载完成
│
▼
应用在前台运行
│
├── onNewWant() ← 处理外部跳转、推送点击
│
├── setLightOrDarkMode() ← 深色模式切换
│
└── avoidAreaChange() ← 避让区域变化
│
▼
应用退出 → onDestroy()
九、总结
DriverLicenseExam 项目的 EntryAbility 实现提供了以下最佳实践:
- 窗口管理:全屏适配 + 安全区域避让
- 动态监听:避让区域变化的实时响应
- 状态持久化:深色模式等用户偏好的持久化
- 推送集成:通知权限申请与消息处理
- 外部跳转:深度链接导航处理
- 服务初始化:分享等全局服务的初始化
这些实践适用于大多数鸿蒙应用,是鸿蒙应用开发的基础模板。
关键源码文件:
products/entry/src/main/ets/entryability/EntryAbility.ets— 完整入口 Abilityproducts/entry/src/main/ets/util/WantUtils.ets— Want 处理工具commons/commonLib/src/main/ets/utils/PreferencesUtil.ets— 首选项持久化
更多推荐




所有评论(0)