HarmonyOS 鸿蒙Next中通过navigation跳转到到二级页面怎么监听前后台事件
HarmonyOS 鸿蒙Next中通过navigation跳转到到二级页面怎么监听前后台事件 【问题描述】:通过navigation跳转到到二级页面怎么监听前后台事件
【问题现象】:有个二级页面在播放视频时,切换到后台,能暂停播放,但是切换回前台不能恢复播放
【修改建议】 为了实现前后台切换能够继续播放的效果,结合UIAbility组件生命周期和@Watch和自定义组件更新,考虑在前后台切换时,对APP全局变量的值进行修改,然后通过监听APP全局变量值,以及对其进行判断,来控制视频的停止和播放。
(1)在前后台切换时,对APP里的全局变量isForeGround进行赋值或者修改。
代码示例如下:
// EntryAbility.ets
export default class EntryAbility extends UIAbility {
...
onForeground():void {
// 切到前台,设置isForeGround值为true
console.info('onForeground-切换到前台了');
AppStorage.setOrCreate('isForeGround', true);
}
onBackground():void {
// 切到后台,设置isForeGround值为false
console.info('onBackground-切换到后台了');
AppStorage.setOrCreate('isForeGround', false)
}
}
(2)在当前组件用watch来监听APP全局变量。
代码示例如下:
// video.ets
@Entry
@Component
struct videoDemo {
private controller: VideoController = new VideoController();
[@Watch](/user/Watch)('network') @StorageLink('isForeGround') isForeGround: boolean = false;
network() {
if (this.isForeGround) {
// 切换到前台了,视频继续播放
this.controller.start();
} else {
// 切换到后台了,视频暂停播放
this.controller.pause();
}
}
build() {
Column(){
Video({
src: $rawfile('video.mp4'), // 示例视频
controller:this.controller
}).height('40%')
.loop(true) // 开启循环播放
}.margin({top:100})
.width('100%')
.height('100%')
}
}
【背景知识】
- UIAbility组件生命周期:当用户打开、切换和返回到对应应用时,应用中的UIAbility实例会在其生命周期的不同状态之间转换。
- Foreground和Background状态:Foreground和Background状态分别在UIAbility实例切换至前台和切换至后台时触发,对应于onForeground()回调和onBackground()回调。
- Watch和自定义组件更新:@Watch用于监听状态变量的变化,当状态变量变化时,@Watch的回调方法将被调用。
【问题定位】 视频播放功能需要通过VideoController的start()方法启动。因此可以排查应用在前后台切换时,aboutToAppear和onPageShow方法是否会被触发,从而确定controller.start()方法是否被调用。
【分析结论】 播放视频必须调用controller.start(),如下代码。虽然首次进入页面时,可以通过aboutToAppear或者onPageShow调用controller.start(),但是前后台切换的时候,这两个方法不会被触发,因此controller.start()不会被调用,所以会出现视频无法继续播放的情况。
controller: VideoController = new VideoController()
this.controller.start();
更多关于HarmonyOS 鸿蒙Next中通过navigation跳转到到二级页面怎么监听前后台事件的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
好的,感谢,
方案一:使用 WindowStage 监听窗口生命周期事件
如何判断应用当前在前台/后台-程序框架(Ability)-程序框架-应用框架开发-开发 - 华为HarmonyOS开发者
[Interface (WindowStage)-@ohos.window (窗口)-窗口管理-ArkTS API-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-window-windowstage#onwindowstageevent9)
import { UIAbility } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage) {
try {
windowStage.on('windowStageEvent', (data) => {
console.info('Window stage event: ' + JSON.stringify(data));
if (data === window.WindowStageEventType.SHOWN) {
console.info('应用进入前台');
// 在这里恢复视频播放
this.resumeVideoPlayback();
} else if (data === window.WindowStageEventType.HIDDEN) {
console.info('应用进入后台');
// 在这里暂停视频播放
this.pauseVideoPlayback();
} else if (data === window.WindowStageEventType.ACTIVE) {
console.info('窗口获焦');
} else if (data === window.WindowStageEventType.INACTIVE) {
console.info('窗口失焦');
}
});
} catch (exception) {
console.error('Failed to enable window stage event listener: ' + JSON.stringify(exception));
}
}
private pauseVideoPlayback() {
// 实现暂停视频播放的逻辑
}
private resumeVideoPlayback() {
// 实现恢复视频播放的逻辑
}
}
方案二:使用 ApplicationStateChangeCallback 监听应用前后台状态
[@ohos.app.ability.ApplicationStateChangeCallback (应用进程状态变化监听器)-Stage模型能力的接口-ArkTS API-Ability Kit(程序框架服务)-应用框架 - 华为HarmonyOS开发者](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-app-ability-applicationstatechangecallback)
import { UIAbility, ApplicationStateChangeCallback } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
export default class MyAbility extends UIAbility {
onCreate() {
console.log('MyAbility onCreate');
let applicationStateChangeCallback: ApplicationStateChangeCallback = {
onApplicationForeground() {
console.info('applicationStateChangeCallback onApplicationForeground');
// 应用切换到前台,恢复视频播放
this.resumeVideoPlayback();
},
onApplicationBackground() {
console.info('applicationStateChangeCallback onApplicationBackground');
// 应用切换到后台,暂停视频播放
this.pauseVideoPlayback();
}
}
// 1.获取applicationContext
let applicationContext = this.context.getApplicationContext();
try {
// 2.通过applicationContext注册应用前后台状态监听
applicationContext.on('applicationStateChange', applicationStateChangeCallback);
} catch (paramError) {
console.error(`error: ${(paramError as BusinessError).code}, ${(paramError as BusinessError).message}`);
}
console.log('Register applicationStateChangeCallback');
}
onDestroy() {
// 在销毁时取消监听
let applicationContext = this.context.getApplicationContext();
try {
applicationContext.off('applicationStateChange');
} catch (paramError) {
console.error(`error: ${(paramError as BusinessError).code}, ${(paramError as BusinessError).message}`);
}
}
private pauseVideoPlayback() {
// 实现视频暂停逻辑
console.info('Video playback paused due to background state');
}
private resumeVideoPlayback() {
// 实现视频恢复播放逻辑
console.info('Video playback resumed due to foreground state');
}
}
在鸿蒙 ArkUI 中,通过Navigation跳转的二级页面监听前后台事件(如应用切后台 / 前台),需结合应用生命周期和页面生命周期、组件级生命周期实现。针对 “切换后台能暂停、切换前台不能恢复” 的问题,核心是要在正确的时机触发 “恢复播放” 逻辑,以下是具体解决方案:
一、核心思路
二级页面的前后台状态变化,可通过两种生命周期机制监听:
- 应用级生命周期:通过
Ability的onForeground(切前台)和onBackground(切后台)感知整个应用的前后台切换。 - 页面级生命周期:通过页面组件的
onPageShow(页面显示)和onPageHide(页面隐藏)感知当前页面的显示 / 隐藏状态(包括应用前后台切换导致的显示变化)。 - 组件级生命周期:通过页面组件的
onShown(组件显示)和onHidden(组件隐藏)感知当前组件的显示 / 隐藏状态(包括应用前后台切换导致的显示变化)。
// 页面显示时触发(包括从后台切回前台)
onShown() {
console.log("二级页面显示/切回前台");
// 恢复播放
this.videoController.start();
}
// 页面隐藏时触发(包括切到后台或跳走)
onHidden() {
console.log("二级页面隐藏/切到后台");
// 暂停播放
this.videoController.pause();
}
希望HarmonyOS能继续加强在安全性方面的研发,保护用户的隐私和数据安全。
也可以使用onNewWant去获取前后台状态切换,设置一个动态参数,在前后台切换时改变该参数,onNewWant监听到回到前台时继续播放
export default class EntryAbility extends UIAbility {
onCreate(want: Want, _launchParam: AbilityConstant.LaunchParam): void {
......
}
onNewWant(want: Want, _launchParam: AbilityConstant.LaunchParam): void {
// 可以监听到返回前台事件
改变参数,同时改变播放状态
....
}
}
找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17
【解决方案】
监听Navigation首页和子页面互相跳转的过程中两个页面的显示和隐藏(前台与后台),Navigation组件通常被用作Page页面的根容器,它内部默认包含标题栏、内容区域和工具栏。
在内容区域中,默认情况下,首页会展示导航内容(即Navigation的子组件),而子页面则展示NavDestination的子组件。当从首页跳转至子页面时,实际打开的是NavDestination组件,而不是一个完整的应用页面,因此不会触发应用页面特有的onPageShow和onPageHide生命周期方法。
有两种途径可以监听页面的显示和隐藏:
- 途径1:监听NavDestination组件的显示和隐藏。
可以使用onShown事件和onHidden事件来监听NavDestination组件的显示和隐藏。示例代码如下:
NavDestination() {
}
.onShown(()=>{
console.info('MyPageTwo onShown')
//log('播放')
})
.onHidden(()=>{
console.info('MyPageTwo onHidden')
//log('暂停')
})
- 途径2:监听Navigation首页的显示和隐藏。
在Navigation不使用hideNavBar隐藏导航栏的场景下,有以下三个方案来监听Navigation主页面的显示和隐藏。
方案一:在首页的aboutToAppear函数中使用无感监听uiObserver.on(‘navDestinationSwitch’)监听页面切换。在回调函数中,如果切换的目的页面是navBar,表明切换到Navigation首页。示例代码如下:
aboutToAppear(): void {
uiObserver.on('navDestinationSwitch', this.getUIContext(), (switchInfo) => {
// 判断切换的目的页面是否为Navigation首页
if (switchInfo.to === 'navBar') {
console.info('----NavigationPage again show')
}
})
}
方案二:监听Navigation的onNavBarStateChange事件。在回调函数中,如果变量isVisible为true,表明首页正在显示。示例代码如下:
build() {
Navigation(this.pageInfos) {
}
.title('NavigationPage')
.onNavBarStateChange((isVisible: boolean) => {
console.info('----isVisible:' + isVisible)
})
}
方案三:使用@Watch装饰器监听NavPathStack路由栈对象。如果路由栈为空,则表明Navigation首页正在显示。示例代码如下:
@Provide('pageInfos') [@Watch](/user/Watch)('pathInfoChange') pageInfos: NavPathStack = new NavPathStack()
pathInfoChange() {
console.info('----pageInfosChange:' + this.pageInfos.size())
}
【背景知识】
- 应用的UI页面由一个入口组件+多个非入口组件(为可选)组成,其中入口组件同时具备页面和自定义组件的生命周期。
- Navigation是路由导航的根视图容器,一般作为页面(@Entry)的根容器,NavDestination是Navigation子页面的根容器。
您在页面播放视频时使用的是video组件还是avplayer呢?
用的video,
好的,另外提供了关于video组件切换前后台播放中断的解决方案,您看看是否能解决问题,
在鸿蒙Next中监听页面前后台事件,可在二级页面使用onPageShow和onPageHide生命周期回调。示例代码:
@Entry
@Component
struct SecondPage {
onPageShow() {
// 处理前台事件
}
onPageHide() {
// 处理后台事件
}
}
通过navigation跳转时,这些生命周期方法会自动触发。页面进入前台执行onPageShow,进入后台执行onPageHide。
在HarmonyOS Next中,可通过onPageShow和onPageHide生命周期方法监听页面前后台切换。在二级页面的UI组件中实现:
onPageShow() {
// 切回前台时恢复视频播放
this.videoController.start();
}
onPageHide() {
// 切换到后台时暂停播放
this.videoController.pause();
}
确保在aboutToAppear中初始化视频控制器,在aboutToDisappear中释放资源。这种方法适用于通过navigation跳转的页面栈管理。

