第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 实现提供了以下最佳实践:

  1. 窗口管理:全屏适配 + 安全区域避让
  2. 动态监听:避让区域变化的实时响应
  3. 状态持久化:深色模式等用户偏好的持久化
  4. 推送集成:通知权限申请与消息处理
  5. 外部跳转:深度链接导航处理
  6. 服务初始化:分享等全局服务的初始化

这些实践适用于大多数鸿蒙应用,是鸿蒙应用开发的基础模板。


关键源码文件:

  • products/entry/src/main/ets/entryability/EntryAbility.ets — 完整入口 Ability
  • products/entry/src/main/ets/util/WantUtils.ets — Want 处理工具
  • commons/commonLib/src/main/ets/utils/PreferencesUtil.ets — 首选项持久化
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐