目录

如何监听并响应应用切换前后台事件

问题现象

如何监听并响应应用切换前后台事件并作出相应的处理?

背景知识

解决方案

  1. 监听应用切换前后台事件。
    • 方案一:在EntryAbility中onForeground和onBackground方法中处理应用切换前后台事件。代码示例:
      onForeground(): void {
        // Ability has brought to foreground
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
      }
      
      onBackground(): void {
        // Ability has back to background
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
      }
    • 方案二:通过窗口的on('windowStageEvent')接口,开启WindowStage生命周期变化的监听,处理应用切换前后台事件。代码示例:
      onWindowStageCreate(windowStage: window.WindowStage): void {
        // Main window is created, set main page for this ability
        hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
        // 设置WindowStage的事件订阅(切到前台/切到后台)
        try {
          windowStage.on('windowStageEvent', (data) => {
            let stageEventType: window.WindowStageEventType = data;
            switch (stageEventType) {
              // 切到前台
              case window.WindowStageEventType.SHOWN:
                console.log(`windowStage foreground.`);
                // ...
                break;
              // 切到后台
              case window.WindowStageEventType.HIDDEN:
                console.log(`windowStage background.`);
                // ...
                break;
              default:
                break;
            }
          });
        } catch (exception) {
          console.log(`Failed to enable the listener for window stage event changes. Cause: ${JSON.stringify(exception)}`);
        }
        windowStage.loadContent('pages/Index', (err) => {
          if (err.code) {
            hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
            return;
          }
          hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
        });
      }
    • 方案三:通过ApplicationContext的getRunningProcessInformation()方法获取进程信息,其中包含当前进程运行状态,可以判断是否处于前台。代码示例:
      build() {
        RelativeContainer() {
          Button('获取信息').onClick(() => {
            let applicationContext = this.getUIContext().getHostContext()?.getApplicationContext();
            applicationContext?.getRunningProcessInformation().then((data) => {
              console.log(`The process running information is: ${JSON.stringify(data)}`);
            });
          })
        }
        .height('100%')
        .width('100%')
      }
  2. 如果需要实现在页面、组件、线程等场景下响应前后台切换事件,可结合事件通知能力来实现。在切换前后台时,发送合适的事件通知,并在相应的场景下进行接收处理。

    使用EventHub发送通知this.context.eventHub.emit('onForeground');。

    使用EventHub接收通知。示例代码:
    eventFunc() {
      // 响应进入前台方法
      // ...
    }
    
    aboutToAppear(): void {
      // 以eventHub为例,订阅事件
      this.getUIContext().getHostContext()?.eventHub.on('onForeground', this.eventFunc);
    }
    
    aboutToDisappear(): void {
      this.getUIContext().getHostContext()?.eventHub.off('onForeground', this.eventFunc);
    }

常见FAQ

Q:如何在依赖的Har模块包中监听前后台切换事件?

A:在Hap包的EntryAbility.ets文件的onWindowStageCreate生命周期中,通过调用Har暴露的接口,将WindowStage传递给Har包。在Har包中对传递的window.WindowStage进行监听,判断应用是否退到后台。