当前位置:首页>鸿蒙APP>鸿蒙应用:ApplicationContext监听当前进程的前后台状态变化

鸿蒙应用:ApplicationContext监听当前进程的前后台状态变化

  • 2026-10-11 06:13:34
鸿蒙应用:ApplicationContext监听当前进程的前后台状态变化

监听当前进程的前后台状态变化,便于进程在前后台切换时执行某些操作。例如,统计进程前后台时长、或者当进程退到后台时清理内存缓存。

当应用部分功能退后台时,系统仅挂起无活跃窗口的进程,而保持前台进程(如音乐播放)正常运行,兼顾性能与用户体验。

一、 进程与应用

在鸿蒙系统中,进程的前后台状态与应用的前后台状态是两个相关但不同的概念。

  • 应用是基于鸿蒙分布式架构,以Ability为核心组件,可跨设备部署、调度、运行的软件程序。

  • 应用分为传统应用和元服务两类。

  • 一个应用可以包含一个或多个进程。

  • 进程是系统进行资源分配的基本单位,是操作系统结构的基础。

  • 进程分为基本进程类型和其他进程类型两类。

二、 区分进程的前后台状态与应用的前后台状态

2.1 进程的前后台状态

取决于当前进程中是否存在前台UIAbility/UIExtensionAbility或可见窗口

  • 前台进程:

进程中至少有一个 UIAbility 处于前台(例如用户正在操作的页面)或存在可见窗口。

  • 后台进程:

进程中所有 UIAbility 均退至后台且无可见窗口。

2.2 应用的前后台状态

取决于应用内所有进程的整体状态:

  • 前台应用:应用下至少有一个进程处于前台状态。

  • 后台应用:应用下所有进程均处于后台状态。

2.3 假设一个应用包含两个进程(如主进程和音乐播放进程):

  • 场景 1:用户返回桌面(主进程退后台),但音乐仍在播放(播放进程处前台)

应用状态:前台(因播放进程在前台)

主进程状态:后台

  • 场景 2:用户暂停音乐后返回桌面(所有进程退后台)

应用状态:后台

所有进程状态:后台

三、 监听当前进程的前后状态:ApplicationStateChangeCallback

该模块仅支持监听当前进程的前后台状态变化。

export default class ApplicationStateChangeCallback {// 当前进程从后台切换到前台时触发回调。    onApplicationForeground(): void;// 当前进程从前台切换到后台时触发回调。    onApplicationBackground(): void;}

调用ApplicationContext.on('applicationStateChange')方法传入自定义ApplicationStateChangeCallback来监听当前进程的前后台状态变化,从而根据进程前后台状态变化来执行某些操作。

3.1 onApplicationForeground(): void

当前进程从后台切换到前台时触发回调。

当该回调触发时,并不表示进程已完全处于前台状态,而是即将进入前台状态,此时无法执行需要依赖前台状态的操作(例如启动其他UIAbility)。

从API version 11开始,该接口支持在元服务中使用。

3.2 onApplicationBackground(): void

当前进程从前台切换到后台时触发回调。

当该回调触发时,表示进程已完全处于后台状态,可以执行适合在后台状态下完成的操作(例如清理内存缓存)。

从API version 11开始,该接口支持在元服务中使用。

3.3 实现 ApplicationStateChangeCallback

import { ApplicationStateChangeCallback, common } from '@kit.AbilityKit';import { hilog } from '@kit.PerformanceAnalysisKit';const DOMAIN = 0x0001;const TAG = "AppStatusCbOnOff";const PREFIX = "AppStsCb";export class ApplicationStatusCallbackImpl extends ApplicationStateChangeCallback {  private applicationContext: common.ApplicationContext | null = null;  public onApplicationStatus(applicationContext: common.ApplicationContext) {    let format = '%{public}s on applicationStateChangeCallback run, appContext:%{public}s';    let isNotUndefined = applicationContext != undefined;    hilog.info(DOMAIN, TAG, format, PREFIX, isNotUndefined);    if (applicationContext != undefined) {      this.applicationContext = applicationContext;      try {        // 1.通过applicationContext注册当前进程状态监听        this.applicationContext.on('applicationStateChange', this);        let format = '%{public}s on applicationStateChange!';        hilog.info(DOMAIN, TAG, format, PREFIX);      } catch (paramError) {        let error = paramError as BusinessError        let format = '%{public}s on applicationStateChange error, code:%{public}d, message:%{public}s'        hilog.info(DOMAIN, TAG, format, PREFIX, error.code, error.message);      }    }  }  public offApplicationStatus() {    let format = '%{public}s off applicationStateChangeCallback run. appContext:%{public}s';    hilog.info(DOMAIN, TAG, format, PREFIX, this.applicationContext != undefined);    if (this.applicationContext != undefined) {      try {        // 2.通过applicationContext注册当前进程状态监听        this.applicationContext.off('applicationStateChange', this);        let format = '%{public}s off applicationStateChange!';        hilog.info(DOMAIN, TAG, format, PREFIX);      } catch (paramError) {        let error = paramError as BusinessError        let format = '%{public}s off applicationStateChange error, code:%{public}d, message:%{public}s'        hilog.info(DOMAIN, TAG, format, PREFIX, error.code, error.message);      }    }  }  override onApplicationForeground(): void {    let format = '%{public}s on onApplicationForeground.';    hilog.info(DOMAIN, TAG, format, PREFIX);  }  override onApplicationBackground(): void {    let format = '%{public}s on onApplicationBackground.';    hilog.info(DOMAIN, TAG, format, PREFIX);  }}

3.4 注册/解注册监听ApplicationStateChangeCallback

import { AbilityStage } from '@kit.AbilityKit';import { ApplicationStatusCallbackImpl } from 'commonlib';export default class MyAbilityStage extends AbilityStage {  private appStatusCallbackImpl: ApplicationStatusCallbackImpl = new ApplicationStatusCallbackImpl();  onCreate(): void {    let applicationContext = this.context.getApplicationContext();    this.appStatusCallbackImpl.onApplicationStatus(applicationContext);  }  override onDestroy(): void {    super.onDestroy();    this.appStatusCallbackImpl.offApplicationStatus();  }}

自定义的MyAbilityStage类需要在的module.json5配置文件中,通过配置 srcEntry 参数来指定对应的代码路径,以作为HAP加载的入口。

详情见:AbilityStageContext是模块级别的上下文

B族维生素,公众号:众擎易举独力难支鸿蒙应用获取AbilityStageContext、UIAbilityContext及其他模块的Context

3.5 日志如下

         I     AppStsCb on applicationStateChangeCallback run, appContext:true         I     AppStsCb on applicationStateChange!         I     AppStsCb on onApplicationForeground.         I     Ability onCreaterecipes  I     Ability onWindowStageCreaterecipes  I     Ability onForegroundrecipes  I     Succeeded in loading the content.recipes  I     Ability onBackgroundrecipes  I     AppStsCb on onApplicationBackground.recipes  I     Ability onWindowStageDestroyrecipes  I     Ability onDestroyrecipes  I     AppStsCb off applicationStateChangeCallback run. appContext:truerecipes  I     AppStsCb off applicationStateChange!

第3行:进入前台,第9行进入后台

四、 典型场景

5.1 资源释放与状态保存

应用进程退到后台时需释放内存、网络资源或暂停高耗能任务(如动画、数据传输)。

5.2 后台持续任务(如音乐播放)

应用进程需在后台持续运行(如音乐播放),需申请长时任务并监听状态变化。

5.3 网络连接管理

应用进程切后台后网络资源被冻结(约12秒释放),需重新连接或释放 Socket。

5.4 状态同步与 UI 更新

应用进程回到前台需刷新数据(如消息列表、定位信息)。

5.5 播控中心交互(AVSession)

音乐类应用需在后台同步播放状态到系统播控中心。

六、约束限制

ApplicationStateChangeCallback仅支持监听当前进程的前后台状态变化。

如果需要监听整个应用的前后台状态变化,需要使用ApplicationStateObserver,但ApplicationStateObserver不对普通应用授权,下面仅做简单介绍。

  • ApplicationStateObserver:监听整个应用前后台状态

ApplicationStateObserver作为入参传入appManager.on('applicationState')方法,监听应用的生命周期变化。

  • 导入模块:import { appManager } from '@kit.AbilityKit';

  • 需要权限:ohos.permission.RUNNING_STATE_OBSERVER

ohos.permission.RUNNING_STATE_OBSERVER为系统级别权限,需要系统授权。

从API 14开始,开放范围从系统应用变更为企业普通应用

  • 对于非系统应用和非企业类应用

声明:ohos.permission.RUNNING_STATE_OBSERVER权限时,将导致应用安装失败

Install Failed: error: failed to install bundle.code:9568289error: install failed due to grant request permissions failed.PermissionName: ohos.permission.RUNNING_STATE_OBSERVER
  • 企业类应用的特性:

包括:企业普通应用和MDM(Mobile Device Management)设备管理应用。

  • 仅在企业定制设备上运行,不会在普通消费者设备上运行。

  • 不会上架华为应用市场。

  • 代码示例:

import { appManager } from '@kit.AbilityKit';let applicationStateObserver: appManager.ApplicationStateObserver = {  onForegroundApplicationChanged(appStateData) {    console.log(`[appManager] onForegroundApplicationChanged: ${JSON.stringify(appStateData)}`);  },  onAbilityStateChanged(abilityStateData) {    console.log(`[appManager] onAbilityStateChanged: ${JSON.stringify(abilityStateData)}`);  },  onProcessCreated(processData) {    console.log(`[appManager] onProcessCreated: ${JSON.stringify(processData)}`);  },  onProcessDied(processData) {    console.log(`[appManager] onProcessDied: ${JSON.stringify(processData)}`);  },  onProcessStateChanged(processData) {    console.log(`[appManager] onProcessStateChanged: ${JSON.stringify(processData)}`);  },  onAppStarted(appStateData) {    console.log(`[appManager] onAppStarted: ${JSON.stringify(appStateData)}`);  },  onAppStopped(appStateData) {    console.log(`[appManager] onAppStopped: ${JSON.stringify(appStateData)}`);  }};let observerId: number = -1;try {  observerId = appManager.on('applicationState', applicationStateObserver);  console.info(`[appManager] observerCode: ${observerId}`);} catch (paramError) {  let code = (paramError as BusinessError).code;  let message = (paramError as BusinessError).message;  console.error(`[appManager] error: ${code}, ${message}`);}function offCallback(err: BusinessError) {  if (err) {    console.error(`appmanager.off failed, code: ${err.code}, msg: ${err.message}`);  } else {    console.info(`appmanager.off success.`);  }}try {  appManager.off('applicationState', observerId, offCallback);  console.info(`[appManager] observerCode: ${observerId}`);} catch (paramError) {  let code = (paramError as BusinessError).code;  let message = (paramError as BusinessError).message;  console.error(`[appManager] error: ${code}, ${message}`);}

七、注意事项:资源冻结策略

在鸿蒙系统中,应用或进程切换到后台2秒后,应用的网络资源会被冻结,并且在12秒后进行释放(未申请短时任务或长时任务会导致网络资源被冻结和释放)。此时,再继续使用网络资源,就会出现网络不可用的情况。

- END -

欢迎关注公众号

长按上图识别二维码或扫一扫

最新文章

随机文章