UIAbility 生命周期与全局初始化

UIAbility 是 HarmonyOS 应用的基本运行单元,负责管理界面的生命周期与系统交互。理解 UIAbility 的生命周期流程,并在合适的时机执行初始化操作,是构建稳定应用的关键。本文以柚兔学伴项目的 EntryAbility.ets 为例,深入讲解 UIAbility 生命周期与全局初始化实践。
请添加图片描述

一、UIAbility 生命周期概览

UIAbility 提供了六个核心生命周期回调,按调用顺序如下:

onCreate → onWindowStageCreate → onForeground ⇄ onBackground → onDestroy
                                                        ↓
                                                onWindowStageDestroy
回调 触发时机 典型用途
onCreate Ability 创建时 全局初始化、参数解析
onWindowStageCreate 窗口舞台创建时 窗口配置、加载主页
onForeground 切到前台时 恢复动画、刷新数据
onBackground 切到后台时 暂停动画、释放临时资源
onWindowStageDestroy 窗口舞台销毁时 释放 UI 资源
onDestroy Ability 销毁时 释放全部资源
onNewWant 已存在的 Ability 收到新 Intent 处理新参数
请添加图片描述

二、onCreate:应用级初始化

onCreate 在 Ability 创建时调用,是执行全局初始化的最佳时机。柚兔学伴在此完成了参数检查、颜色模式设置、工具初始化和朗读引擎初始化:

// entry/src/main/ets/entryability/EntryAbility.ets
export default class EntryAbility extends UIAbility {
  async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
    // 1. 检查启动参数
    this.checkAndHandleParams(want);

    // 2. 读取并存储系统颜色模式到 AppStorage
    AppStorage.setOrCreate('systemColorMode', this.context.config.colorMode);
    // 设置为自动跟随系统模式
    this.context.getApplicationContext()
      .setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);

    // 3. 初始化全局工具
    AppUtil.init(this.context);
    PreferencesUtil.init('partner');

    // 4. 初始化朗读控件
    if (this.context) {
      const readerParams: TextReader.ReaderParam = {
        isVoiceBrandVisible: true,
        businessBrandInfo: {
          panelName: '小艺朗读',
          panelIcon: $r('app.media.startIcon')
        }
      };
      await TextReader.init(this.context, readerParams).then(() => {
        console.info(`TextReader succeeded in initializing.`);
      }).catch((e: BusinessError) => {
        console.error(`TextReader failed to initialize. Code: ${e.code}, message: ${e.message}`);
      });
    }
  }
}

2.1 启动参数检查

checkAndHandleParams(want: Want): void {
  Logger.info(TAG, `checkAndHandleParams`);
  try {
    if (want === null || want.parameters === null ||
        want === undefined || want.parameters === undefined) {
      return;
    }
  } catch (err) {
    Logger.error(TAG, `checkAndHandleParams failed: ${err}`);
  }
}

Want 对象携带了启动 Ability 时传入的参数,在 onCreateonNewWant 中都需要检查参数的有效性。

2.2 AppStorage 全局状态

AppStorage 是 HarmonyOS 的全局状态容器,在 UIAbility 中写入后,所有 UI 组件都可以通过 @StorageLink@StorageProp 读取:

// 存储系统颜色模式,供 UI 组件适配深色/浅色模式
AppStorage.setOrCreate('systemColorMode', this.context.config.colorMode);

2.3 TextReader 朗读引擎初始化

柚兔学伴集成了 @kit.SpeechKit 的 TextReader 朗读能力,在 onCreate 中完成初始化:

import { TextReader } from '@kit.SpeechKit';

const readerParams: TextReader.ReaderParam = {
  isVoiceBrandVisible: true,          // 显示语音品牌标识
  businessBrandInfo: {
    panelName: '小艺朗读',             // 朗读面板名称
    panelIcon: $r('app.media.startIcon') // 面板图标
  }
};
await TextReader.init(this.context, readerParams);
  • isVoiceBrandVisible:是否在朗读面板中显示语音品牌
  • businessBrandInfo:定制朗读面板的名称和图标,与产品品牌保持一致

三、onWindowStageCreate:窗口与页面配置

onWindowStageCreate 在主窗口创建后回调,是配置窗口属性和加载首页的关键时机:

onWindowStageCreate(windowStage: window.WindowStage): void {
  // 1. 保存 UIAbilityContext 到全局单例
  GlobalUIAbilityContext.setContext(this.context);

  // 2. 注册断点系统监听
  WindowUtil.registerBreakPoint(windowStage);

  // 3. 请求全屏沉浸式布局
  WindowUtil.requestFullScreen(windowStage, this.context);

  // 4. 创建 PageContext 并存入 AppStorage
  AppStorage.setOrCreate('pageContext', new PageContext());

  // 5. 加载首页内容
  windowStage.loadContent('pages/HomePage', (err) => {
    if (err.code) {
      hilog.error(DOMAIN, 'testTag',
        'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
      return;
    }
    // 6. 隐藏标题栏
    WindowUtil.hideTitleBar(windowStage);
    hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
  });
}

3.1 GlobalUIAbilityContext 全局上下文

HSP/HAR 模块无法直接获取 UIAbilityContext,柚兔学伴通过单例模式解决这一问题:

// common/src/main/ets/util/ContextConfig.ts
import type { common } from '@kit.AbilityKit';

declare namespace globalThis {
  let _brushEngineContext: common.UIAbilityContext;
}

export class GlobalUIAbilityContext {
  public static getContext(): common.UIAbilityContext {
    return globalThis._brushEngineContext;
  }

  public static setContext(context: common.UIAbilityContext): void {
    globalThis._brushEngineContext = context;
  }
}

onWindowStageCreate 中调用 setContext 保存上下文后,任意模块都可以通过 GlobalUIAbilityContext.getContext() 获取:

// 在 feature 模块中使用
import { GlobalUIAbilityContext } from 'common';

const context: common.UIAbilityContext = GlobalUIAbilityContext.getContext();
const cacheDir = context.cacheDir;  // 获取缓存目录

3.2 PageContext 路由管理

PageContext 封装了 NavPathStack,作为全局导航控制器:

AppStorage.setOrCreate('pageContext', new PageContext());

在 UI 组件中通过 AppStorage 获取:

// entry/src/main/ets/pages/HomePage.ets
private pageContext: PageContext = AppStorage.get('pageContext') as PageContext;
private appPathInfo: NavPathStack = this.pageContext.navPathStack;

build() {
  Navigation(this.appPathInfo) {
    // 页面内容
  }
  .mode(NavigationMode.Stack)
}

3.3 窗口初始化顺序

onWindowStageCreate 中的操作顺序至关重要:

  1. 先保存 Context → 确保后续操作能获取到上下文
  2. 注册断点监听 → 获取设备尺寸和避让区域信息
  3. 请求全屏 → 设置沉浸式窗口
  4. 创建 PageContext → 导航栈准备就绪
  5. 加载内容 → 最后才加载 UI 页面
  6. 隐藏标题栏 → 页面加载完成后再处理 UI 细节

四、onNewWant:处理新 Intent

当 Ability 已存在且 launchTypesingleton 时,再次启动会触发 onNewWant 而非 onCreate

onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  Logger.info(TAG, `onNewWant`);
  this.checkAndHandleParams(want);
}

典型场景:用户通过通知栏点击、快捷方式或 Deep Link 再次打开应用时,可以在 onNewWant 中解析新的 Want 参数,实现跳转到指定页面等逻辑。

五、onForeground 与 onBackground

onForeground(): void {
  // Ability 切到前台,可恢复动画、刷新数据
  hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
}

onBackground(): void {
  // Ability 切到后台,可暂停动画、释放临时资源
  hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
}

实际开发建议:

  • onForeground:恢复视频播放、刷新聊天消息、重新请求定位
  • onBackground:暂停视频播放、停止轮询请求、释放相机资源

六、onDestroy:资源清理

onDestroy(): void {
  hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
}

onDestroy 中应释放所有全局资源,包括关闭数据库连接、注销事件监听、停止后台任务等。

七、生命周期与初始化全景图

应用启动
  │
  ▼
onCreate
  ├── checkAndHandleParams()        ← 参数解析
  ├── AppStorage.setOrCreate()      ← 全局状态初始化
  ├── AppUtil.init()                ← 工具初始化
  ├── PreferencesUtil.init()        ← 偏好初始化
  └── TextReader.init()             ← 朗读引擎初始化
  │
  ▼
onWindowStageCreate
  ├── GlobalUIAbilityContext.setContext()  ← 全局上下文
  ├── WindowUtil.registerBreakPoint()      ← 断点系统
  ├── WindowUtil.requestFullScreen()       ← 沉浸式窗口
  ├── AppStorage.setOrCreate('pageContext') ← 导航控制器
  ├── windowStage.loadContent('HomePage')  ← 加载首页
  └── WindowUtil.hideTitleBar()            ← 隐藏标题栏
  │
  ▼
onForeground ⇄ onBackground             ← 前后台切换
  │
  ▼
onDestroy                               ← 资源清理

小结

UIAbility 的生命周期为应用提供了清晰的初始化与资源管理时机。柚兔学伴在 onCreate 中完成全局工具和朗读引擎的初始化,在 onWindowStageCreate 中配置窗口属性并加载首页,通过 GlobalUIAbilityContext 单例解决跨模块上下文访问问题,通过 AppStorage 实现全局状态共享。遵循生命周期规范执行初始化,是保障应用稳定运行的基础。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐