【HarmonyOS】HMRouter使用详解(三)生命周期
生命周期(Lifecycle)
使用HMRouter的页面跳转时,想实现和Navigation一样的生命周期时,需要通过新建生命周期类来实现对页面对某一个生命周期的监控。
新建Lifecycle类
通过继承IHMLifecycle接口实现生命周期接口的方法重写。
通过添加@HMLifecycle装饰器,来定义生命周期类的名称,然后在页面中使用
IHMLifecycle
export interface IHMLifecycle {onPrepare?(ctx: HMLifecycleContext): void;onAppear?(ctx: HMLifecycleContext): void;onDisAppear?(ctx: HMLifecycleContext): void;onShown?(ctx: HMLifecycleContext): void;onHidden?(ctx: HMLifecycleContext): void;onWillAppear?(ctx: HMLifecycleContext): void;onWillDisappear?(ctx: HMLifecycleContext): void;onWillShow?(ctx: HMLifecycleContext): void;onWillHide?(ctx: HMLifecycleContext): void;onReady?(ctx: HMLifecycleContext): void;onBackPressed?(ctx: HMLifecycleContext): boolean;
}
- onPrepare:在拦截器执行后,路由栈真正push前触发。
- onWillAppear:在路由组件创建后,挂载到组件树之前执行。
- onAppear:通用生命周期事件,路由组件挂载到组件树时执行。
- onWillShow:路由组件布局显示之前执行,此时页面不可见(应用切换到前台不会触发)。
- onShown:路由组件布局显示之后执行,此时页面已完成布局。
- onWillHide:路由组件触发隐藏之前执行(应用切换到后台不会触发)。
- onHidden:路由组件触发隐藏后执行(非栈顶页面push进栈,栈顶页面pop出栈或应用切换到后台)。
- onWillDisappear:路由组件即将销毁之前执行,如果有转场动画,会在动画前触发(栈顶页面pop出栈)。
- onDisappear:通用生命周期事件,路由组件从组件树上卸载销毁时执行。
- onReady:在即将构件子组件时触发此回调。
- onBackPressed:在路由组件绑定的页面栈中存在内容时,此回调生效。当点击返回键时,触发该回调。返回值为true时,表示重写返回键逻辑,false时,表示回退到上一个页面。
下面插入Navigation的生命周期流程图,HMRouter的生命周期流程类似,在此基础上增加了额外的生命周期流程。

@HMLifecycle装饰器
export declare function HMLifecycle(param: HMLifecycleParam): ObjectConstructor;
export interface HMLifecycleParam {lifecycleName: string;priority?: number;global?: boolean;
}
标记在实现了IHMLifecycle的对象上,声明此对象为一个自定义生命周期处理器。
- lifecycleName:自定义生命周期处理器名称,必填。
- priority:生命周期优先等级。按照优先等级顺序触发,不区分自定义或者全局生命周期,优先级相同时先执行@HMRouter中定义的自定义生命周期。
- global:是否为全局生命周期,true时,所有页面生命周期事件为当前设定的生命周期处理器,默认为false。
实现代码
在之前文章的基础上进行修改。
添加一个Lifecycles文件夹,并新建一个TwoPageLifecycle,来实现TwoPage页面的生命周期。
TwoPageLifecycle
import { HMLifecycle, HMLifecycleContext, IHMLifecycle } from "@hadss/hmrouter";@HMLifecycle({ lifecycleName: 'TwoPageLifecycle' })
export class TwoPageLifecycle implements IHMLifecycle {/*** 在拦截器执行后,路由栈真正push前触发* @param ctx*/onPrepare(ctx: HMLifecycleContext): void {console.debug("router", 'onPrepare');}onWillAppear(ctx: HMLifecycleContext): void {console.debug("router", 'onWillAppear');}onAppear(ctx: HMLifecycleContext): void {console.debug("router", 'onAppear');}onWillShow(ctx: HMLifecycleContext): void {console.debug("router", 'onWillShow');}onShown(ctx: HMLifecycleContext): void {console.debug("router", 'onShown');}onWillHide(ctx: HMLifecycleContext): void {console.debug("router", 'onWillHide');}onHidden(ctx: HMLifecycleContext): void {console.debug("router", 'onHidden');}onWillDisappear(ctx: HMLifecycleContext): void {console.debug("router", 'onWillDisappear');}onDisAppear(ctx: HMLifecycleContext): void {console.debug("router", 'onDisAppear');}onReady(ctx: HMLifecycleContext): void {console.debug("router", 'onReady');}onBackPressed(ctx: HMLifecycleContext): boolean {console.debug("router", 'onBackPressed');return true;}
}
TwoPage
import { HMPopInfo, HMRouter, HMRouterMgr } from '@hadss/hmrouter'
import { PageModel } from '../../Models/PageModel'@HMRouter({ pageUrl: "TwoPage", lifecycle: "TwoPageLifecycle" })
@Component
export struct TwoPage {aboutToAppear(): void {let currentParam: PageModel = HMRouterMgr.getCurrentParam() as PageModel;if (currentParam == undefined) {return;}console.debug("router", 'name:' + currentParam.Name);console.debug("router", 'age:' + currentParam.Age);}build() {Column({ space: 20 }) {Button("ThreePage").width("80%").onClick(() => {HMRouterMgr.push({navigationId: "mainNavigation",pageUrl: "ThreePage"}, {onResult: (popInfo: HMPopInfo) => {let popResult: PageModel = popInfo.result as PageModel;if (popResult == null || popResult == undefined) {return;}console.debug("router", 'name:' + popResult.Name);console.debug("router", 'age:' + popResult.Age);}})})Button("ThreeReplacePage").width("80%").onClick(() => {HMRouterMgr.replace({navigationId: "mainNavigation",pageUrl: "ThreePage"}, {onResult: (popInfo: HMPopInfo) => {let popResult: PageModel = popInfo.result as PageModel;if (popResult == null || popResult == undefined) {return;}console.debug("router", 'name:' + popResult.Name);console.debug("router", 'age:' + popResult.Age);}})})Button("HomePage").width("80%").onClick(() => {HMRouterMgr.pop({navigationId: "mainNavigation"})})}.height("100%").width("100%")}
}
实现效果
在生命周期方法中实现内容打印,截图如下:


可以看到生命周期的调用顺序
相关文章:
【HarmonyOS】HMRouter使用详解(三)生命周期
生命周期(Lifecycle) 使用HMRouter的页面跳转时,想实现和Navigation一样的生命周期时,需要通过新建生命周期类来实现对页面对某一个生命周期的监控。 新建Lifecycle类 通过继承IHMLifecycle接口实现生命周期接口的方法重写。 通过…...
Docker 教程三 (Ubuntu Docker安装)
Ubuntu Docker 安装 Docker Engine-Community 支持以下的 Ubuntu 版本: Xenial 16.04 (LTS)Bionic 18.04 (LTS)Cosmic 18.10Disco 19.04 其他更新的版本…… Docker Engine - Community 支持上 x86_64(或 amd64)armhf,arm64&am…...
Redis:持久化
Redis:持久化 持久化RDBdump.rdb优缺点 AOF文件同步重写机制 混合持久化 持久化 虽然Redis是一个内存级别的数据库,但是Redis也是有持久化的能力的。当系统崩溃时,Redis就会被强制退出,此时内存中的数据就会丢失。为了能够在下次…...
精准监控,高效运营 —— 商品信息实时分析为商家带来新机遇
在现代商业环境中,精准监控和高效运营是商家成功的关键。通过实时分析商品信息,商家可以洞察市场趋势、优化库存管理、提升销售策略,从而抓住新的商业机遇。本文将介绍如何利用Python和一些流行的数据分析工具来实现商品信息的实时分析&#…...
Nginx应用配置实战
Nginx通用部署 Nginx常见参数介绍 Nginx 配置文件中的指令和参数决定了它的行为。下面详细介绍一些常见的 Nginx 参数,以帮助你更好地理解和配置 Nginx。 1. worker_processes worker_processes auto;作用:设置 Nginx 处理请求的工作进程数量。auto …...
html实现倒计时
参考网址 <!DOCTYPE html> <html> <head><title>倒计时示例</title> </head> <body><h1 id"titleCountDown"></h1><div id"countdown"></div><script>// 目标日期var targetDat…...
HTMLCSS练习
1) 效果如下 2) 代码如下 2.1) HTML <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" conte…...
LeetCode讲解篇之377. 组合总和 Ⅳ
文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 总和为target的元素组合个数 可以由 总和为target - nums[j]的元素组合个数 转换而来,其中j为nums所有元素的下标 而总和target - nums[j]的元素组合个数 可以由 总和为target - nums[j] - nums[k]的…...
Midjourney中文版:创意无限,艺术之旅由此启程
Midjourney中文版——一个将你的文字想象转化为视觉艺术的神奇平台。无需繁琐的绘画技巧,只需简单的文字描述,你就能开启一场前所未有的艺术之旅。 Midjourney AI超强绘画 (原生态系统)用户端:Ai Loadinghttps://www.mjdiscord.c…...
安装R和RStudio:开始你的数据分析之旅
数据分析是当今世界中一个非常热门的领域,而R语言是进行数据分析的强大工具之一。R是一种编程语言和软件环境,用于统计计算和图形表示。RStudio是一个集成开发环境(IDE),它为R语言提供了一个更加友好和高效的工作环境。…...
如何使用python连接数据库?
数据分析离不开数据库,如何使用python连接数据库呢?听我娓娓道来哈 该笔记参考了PyMySQL官方文档和《python数据采集》关于数据存储的部分,欢迎大家去阅读原著,相信会理解的更加透彻。 补充:文末增加Oracle数据库的连…...
停车位识别数据集 图片数量12416张YOLO,xml和txt标签都有; 2类类别:space-empty,space-occupied;
YOLO停车位识别 图片数量12416张,xml和txt标签都有; 2类类别:space-empty,space-occupied; 用于yolo,Python,目标检测,机器学习,人工智能,深度学习࿰…...
MySQL 创建子账号
1. 使用 root 账号登录 MySQL 使用 root 账号登录 MySQL,登录成功如图所示: 新建一个 MySQL 子账号,新建子账号命令如下: 命令 : CREATE USER testlocalhost IDENTIFIED BY 123456;若出现如下图所示,则表示新建 MySQL…...
代码随想录 106. 岛屿的周长
106. 岛屿的周长 #include<bits/stdc.h> using namespace std;int main(){int n, m;cin >> n >> m;vector<vector<int>> mp(n, vector<int>(m, 0));for (int i 0; i < n; i){for (int j 0; j < m; j){cin >> mp[i][j];}}in…...
阿里云融合认证中的App端一键登录能力
在如今的移动互联网环境中,App端的一键登录功能逐渐成为提升用户体验的关键。用户不再需要繁琐的注册流程或输入短信验证码,一键即可通过手机号码完成登录。而阿里云融合认证中,一键登录能力为移动应用提供了一个简单、便捷且安全的用户身份验…...
基于YOLO11/v10/v8/v5深度学习的安检X光危险品检测与识别系统设计与实现【python源码+Pyqt5界面+数据集+训练代码】
《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…...
vue-插槽作用域实用场景
vue-插槽作用域实用场景 1.插槽1.1 自定义列表渲染1.2 数据表格组件1.3 树形组件1.4 表单验证组件1.5 无限滚动组件 1.插槽 插槽感觉知道有这个东西,但是挺少用过的,每次看到基本都会再去看一遍用法和概念。但是在项目里,自己还是没有用到过…...
Prometheus+Grafana 监控 K8S Ingress-Ningx Controller
文章目录 一、prometheus中添加ingress-nginx的服务发现配置二、ingress-nginx controller的service添加端口暴露监控指标三、grafana添加ingress-nginx controller的监控模版 ingress-nginx默认是没有开启监控指标的,需要我们在ingress-nginx controller的svc里面开…...
如何在Visual Studio 2019中创建.Net Core WPF工程
如何在Visual Studio 2019中创建.Net Core WPF工程 打开Visual Studio 2019,选择Create a new project 选择WPF App(.Net Core) 输入项目名称和位置,单击Create 这样我们就创建好了一个WPF工程 工程文件说明 Dependencies 当前项目所使用的依赖库&…...
自然语言处理(NLP)论文数量的十年趋势:2014-2024
引言 近年来,自然语言处理(NLP)已成为人工智能(AI)和数据科学领域中的关键技术之一。随着数据规模的不断扩大和计算能力的提升,NLP技术从学术研究走向了广泛的实际应用。通过观察过去十年(2014…...
TranslucentTB 架构深度解析:Windows 任务栏透明化技术实现与工程化实践
TranslucentTB 架构深度解析:Windows 任务栏透明化技术实现与工程化实践 【免费下载链接】TranslucentTB A lightweight utility that makes the Windows taskbar translucent/transparent. 项目地址: https://gitcode.com/gh_mirrors/tr/TranslucentTB Tran…...
Qwen3-VL-2B实战:快速搭建一个能“看懂”图片的智能聊天机器人
Qwen3-VL-2B实战:快速搭建一个能"看懂"图片的智能聊天机器人 1. 项目介绍与核心能力 1.1 什么是视觉语言模型 视觉语言模型(Vision-Language Model)是一种能够同时理解图像和文本的AI技术。不同于传统聊天机器人只能处理文字&am…...
HDMI接口没声音?手把手教你用InfoFrame调试音频流(附Audio InfoFrame解析)
HDMI音频调试实战:用Audio InfoFrame精准定位无声问题 当4K显示器亮起而音响沉默时,工程师的调试噩梦就开始了。上周在调试一块定制开发板时,HDMI视频输出完美,但音频系统始终沉默——这不是简单的"线材接触不良"能解释…...
Ubuntu下USRP X300 FPGA固件降级实录:从‘need 38 but got 39’报错到完美兼容GNURadio
Ubuntu下USRP X300 FPGA固件降级实战:从版本冲突到完美兼容GNURadio的完整指南 当USRP X300的FPGA固件版本与GNURadio所需的版本不匹配时,终端里那个刺眼的"need 38 but got 39"报错足以让任何软件无线电开发者抓狂。这种版本冲突问题在Ubuntu…...
React Overdrive与Next.js集成:构建流畅页面过渡
React Overdrive与Next.js集成:构建流畅页面过渡 【免费下载链接】react-overdrive Super easy magic-move transitions for React apps 项目地址: https://gitcode.com/gh_mirrors/re/react-overdrive React Overdrive是一款为React应用提供超简单魔法移动过…...
Qwen3.5-4B-Claude-Opus一文详解:GGUF量化模型在低延迟推理场景下的优势
Qwen3.5-4B-Claude-Opus一文详解:GGUF量化模型在低延迟推理场景下的优势 1. 模型概述 Qwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled-GGUF是基于Qwen3.5-4B架构的推理蒸馏模型,特别强化了结构化分析、分步骤回答以及代码与逻辑类问题的处理能力。该…...
PyTorch Subset类实战:自定义数据子集与高效训练技巧
1. PyTorch Subset类基础与应用场景 当你面对一个庞大的数据集时,直接加载全部数据进行训练往往会遇到内存不足、训练速度慢等问题。这时候PyTorch的torch.utils.data.Subset类就能派上大用场。这个类就像是一个智能的数据筛选器,可以让你轻松地从原始数…...
新手福音:通过快马平台零代码基础理解qun329群聊应用开发
作为一个刚接触编程的新手,想要理解群聊应用开发确实容易一头雾水。最近我在尝试用InsCode(快马)平台搭建类似qun329的简单群聊网页时,发现整个过程比想象中简单很多。下面分享我的学习过程,希望能帮到同样零基础的朋友。 项目结构规划 首先明…...
个人 AI 助理——打造你的第二大脑
个人 AI 助理——打造你的第二大脑摘要:信息过载时代,个人 AI 助理不再是奢侈品,而是必需品。本文教你如何搭建专属 AI 助理,实现信息管理、知识沉淀、决策辅助的智能化,让 AI 成为你的"第二大脑"。一、为什…...
数组运算18题:从递归求和解到Kadane算法
1. 数组运算进阶指南:18道经典题目深度解析数组作为最基本的数据结构,在编程面试和实际开发中无处不在。掌握数组的各种运算技巧不仅能帮助你在面试中脱颖而出,更能提升日常编码的效率和质量。本文将深入解析18个经典的数组运算题目ÿ…...
