总结的如有问题,欢迎大家指正!
以下是基于鸿蒙(HarmonyOS)开发的 页面生命周期 和 组件生命周期 的总结。
一、UIAbility 生命周期
UIAbility 是应用的基本交互单元,其生命周期由系统管理,分为以下核心阶段:
onCreate()
- UIAbility 实例创建时触发,用于初始化非界面相关资源(如数据读取、变量定义)。
onWindowStageCreate(windowStage)
- 窗口阶段创建时触发,需在此加载页面内容(如
windowStage.loadContent('pages/Index')
)并订阅窗口事件(如获焦/失焦)。
- 窗口阶段创建时触发,需在此加载页面内容(如
onForeground()
- UIAbility 切换至前台时触发(如应用从后台恢复),用于重新申请资源(如定位功能)。
onBackground()
- UIAbility 切换至后台时触发,释放非必要资源(如停止定位)或保存临时数据。
onWindowStageDestroy()
- 窗口阶段销毁时触发,释放 UI 资源(如注销事件监听)。
onDestroy()
- UIAbility 销毁时触发,执行最终资源清理和数据持久化。
二、页面生命周期(@Entry 组件)
页面由 @Entry
装饰的组件作为根节点,其生命周期仅对入口组件生效:
onPageShow()
- 触发场景:页面显示(首次进入、从后台返回、路由跳转后返回)。
- 用途:恢复数据(如刷新列表)或重新申请资源。
onPageHide()
- 触发场景:页面隐藏(跳转至其他页面、应用进入后台)。
- 用途:保存临时状态或释放页面独占资源。
onBackPress()
- 触发场景:用户点击物理/导航返回键。
- 返回值 :返回
true
可拦截默认返回行为(如弹窗确认)。
三、组件生命周期(@Component 组件)
自定义组件的生命周期由 ArkUI 框架管理,核心方法如下:
aboutToAppear()
- 触发时机 :组件实例创建后,
build()
执行前。 - 允许操作 :初始化数据、订阅事件,可修改状态变量(如
@State
)。
- 触发时机 :组件实例创建后,
aboutToDisappear()
- 触发时机 :组件销毁前(如
if
条件不满足、ForEach
数组变化)。 - 禁止操作 :修改状态变量(尤其是
@Link
),避免应用行为异常。
- 触发时机 :组件销毁前(如
onDidBuild()
- 触发时机 :
build()
执行完成后。 - 限制:不建议在此修改状态变量或触发动画,可能导致 UI 不稳定。
- 触发时机 :
组件生命周期的执行顺序
- 创建时 :父组件
aboutToAppear
→ 子组件aboutToAppear
→ 父组件build
→ 子组件build
。 - 销毁时 :子组件
aboutToDisappear
→ 父组件aboutToDisappear
。
四、关键场景下的生命周期协同
- 页面跳转(
router.pushUrl
)- 原页面触发
onPageHide
,新页面触发onPageShow
,原页面未被销毁,组件不触发aboutToDisappear
。
- 原页面触发
- 页面替换(
router.replaceUrl
)- 原页面触发
onPageHide
→ 组件依次触发aboutToDisappear
→ 新页面初始化。
- 原页面触发
- 应用后台切换
- 仅触发页面级
onPageHide
/onPageShow
,不触发组件销毁。
- 仅触发页面级
- 组件条件渲染
- 若
if
条件从true
变为false
,子组件触发aboutToDisappear
;条件恢复时重新创建实例,触发aboutToAppear
。
- 若
五、高级生命周期(Navigation 组件)
若使用 Navigation 作为路由容器,其 NavDestination 组件扩展了以下特有生命周期:
onWillAppear
:组件挂载到组件树前,修改状态变量会立即生效。onShown
:页面布局完成后触发,适用于获取元素尺寸。onWillDisappear
:组件销毁前(含转场动画),可执行动画预处理。
六、最佳实践与注意事项
- 资源管理
- 在
aboutToDisappear
或onPageHide
中释放资源(如关闭定时器、取消网络请求)。
- 在
- 状态变量
- 避免在
aboutToDisappear
中修改@Link
变量,可能引发同步源异常。
- 避免在
- 异步操作
- 不在生命周期回调中使用
async/await
,防止组件因闭包引用延迟回收。
- 不在生命周期回调中使用
附:生命周期时序示例
- 冷启动应用
graph LR
A[MyComponent.aboutToAppear] --> B[MyComponent.build] --> C[Child.aboutToAppear] --> D[Child.build] --> E[onPageShow]
- 跳转至新页面
graph LR
A[Index.onPageHide] --> B[Page2.aboutToAppear] --> C[Page2.build] --> D[Page2.onPageShow]
- 返回原页面
graph LR
A[Page2.onBackPress] --> B[Page2.onPageHide] --> C[Index.onPageShow]
额外说明:若页面未被销毁,不触发 aboutToAppear