HarmonyOS Next IM实战:双Navigation生命周期引起的事件被取消功能异常问题

背景介绍

IM应用聊天页中有用户反馈点击图片无法查看大图,查看代码发现点击查看大图使用了ohos.events.emitter事件机制处理大图点击,进一步定位发现事件已发出,但是消费处没有被调用。增加日志发现事件已被成功注册,当时收不到事件。

问题定位

进一步分析,发现该问题的场景是从通知点击冷启动应用是会必现,从push点击热启动没有问题。公司两个应用都接入了HarmonyOS 提供的PushKit,达到在应用推到后台或者被关闭后可以正常收到通知的目的,但是其中一款应用正常,另一款出现该问题。

继续分析日志发现,从通知栏点击应用冷启动打开应用进入聊天页时,聊天页的aboutToAppear执行了一次,aboutToDisappear主动执行了一次。进一步区分发现聊天页被打开两次生命周期依次为聊天页1 aboutToAppear -> 聊天页2 aboutToAppear -> 聊天页2 aboutToDisappear

最初怀疑和pushkit有关系,但是定位到另一个应用没有问题后思路暂时断了。通知栏点击后在onNewWant 通过Navigation跳转到聊天页。在跟专家沟通后提供思路可能是因为应用中有多个Navigation引起的。

查看代码后梳理代码逻辑发现,在应用冷启动后onNewWant中没有立即跳转到聊天页,等待首页加载出来后在首页aboutToAppear中跳转聊天页。应用在onWindowStageCreate中先load闪屏页,在闪屏页aboutToAppear中跳转到首页,再在首页aboutToAppear中跳转到聊天页。闪屏页和首页是两个Navigation,它们共享一个NavPathStack。

进一步了解Navigation生命周期,Navigation作为路由容器,其生命周期承载在NavDestination组件上,以组件事件的形式开放。其生命周期大致可分为三类,自定义组件生命周期、通用组件生命周期和自有生命周期。其中,aboutToAppear和aboutToDisappear是自定义组件的生命周期(NavDestination外层包含的自定义组件),OnAppear和OnDisappear是组件的通用生命周期。剩下的生命周期为NavDestination独有。

生命周期时序如下图所示:
在这里插入图片描述

  • aboutToAppear:在创建自定义组件后,执行其build()函数之前执行(NavDestination创建之前),允许在该方法中改变状态变量,更改将在后续执行build()函数中生效。
  • onWillAppear:NavDestination创建后,挂载到组件树之前执行,在该方法中更改状态变量会在当前帧显示生效。
  • onAppear:通用生命周期事件,NavDestination组件挂载到组件树时执行。
  • onWillShow:NavDestination组件布局显示之前执行,此时页面不可见(应用切换到前台不会触发)。
  • onShown:NavDestination组件布局显示之后执行,此时页面已完成布局。
  • onActive:NavDestination处于激活态(处于栈顶可操作,且上层无特殊组件遮挡)触发。
  • onWillHide:NavDestination组件触发隐藏之前执行(应用切换到后台不会触发)。
  • onInactive:NavDestination组件处于非激活态(处于非栈顶不可操作,或处于栈顶时上层有特殊组件遮挡)触发。
  • onHidden:NavDestination组件触发隐藏后执行(非栈顶页面push进栈,栈顶页面pop出栈或应用切换到后台)。
  • onWillDisappear:NavDestination组件即将销毁之前执行,如果有转场动画,会在动画前触发(栈顶页面pop出栈)。
  • onDisappear:通用生命周期事件,NavDestination组件从组件树上卸载销毁时执行。
  • aboutToDisappear:自定义组件析构销毁之前执行,不允许在该方法中改变状态变量。

页面A跳转页面B的页面生命周期为:A aboutToAppear -> B aboutToAppear -> A aboutToDisappear

终于找到了出现问题的根因,在首页aboutToAppear中跳转聊天页时,由于aboutToAppear还没有执行完,闪屏页的aboutToDisappear也没有执行,这样在跳转聊天页时两个Navigation都存在,这样导致聊天页被执行了两次aboutToAppear生命周期,在闪屏页执行aboutToDisappear后,聊天页第二次aboutToAppear对应的页面也被自动aboutDisappear掉。

解决方案

定位到问题后接下来进行修复,直接在跳转聊天页的地方增加20毫秒延迟,问题被正确修复。
更优雅的方式是在闪屏页aboutDisappear后再跳转聊天页,或者修改闪屏页的结构为非Navigation。

总结

通过对问题的逐步排查,最终确定根本原因是由于应用在冷启动时存在两个共享NavPathStackNavigation组件(闪屏页和首页),导致在首页aboutToAppear中跳转聊天页时,闪屏页尚未完成aboutToDisappear生命周期,从而引发聊天页被重复创建和销毁。这一现象直接导致事件订阅机制失效(因第二次创建的页面未正确注册事件消费逻辑)。解决方案包括增加延迟跳转、调整页面跳转时机至闪屏页销毁后,或重构闪屏页为非Navigation结构以消除多Navigation共存问题。此案例凸显了HarmonyOS中Navigation生命周期管理的复杂性,尤其在多页面跳转场景下需严格遵循组件挂载/卸载顺序,避免因生命周期交叉引发的功能异常。

参考:组件导航 (Navigation)(推荐):https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-navigation-navigation#%E9%A1%B5%E9%9D%A2%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F

评论 40
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

轻口味

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值