HarmonyOS NEXT 应用开发实战(五、页面的生命周期及使用介绍)

news2024/11/25 4:59:26

HarmonyOS NEXT是华为推出的最新操作系统,arkUI是其提供的用户界面框架。arkUI的页面生命周期管理对于开发者来说非常重要,因为它涉及到页面的创建、显示、隐藏、销毁等各个阶段。以下是arkUI页面生命周期的介绍及使用举例。

页面的生命周期的作用

页面的生命周期管理在应用开发中具有重要作用,主要体现在以下几个方面:

  1. 资源管理:在不同的生命周期阶段,开发者可以合理分配和释放资源,例如在页面创建时分配内存,在页面销毁时释放内存,从而避免内存泄漏。

  2. 状态保存:通过生命周期方法,可以在页面隐藏时保存当前状态,以便在重新显示时恢复。这样可以提升用户体验,用户返回页面时能够继续之前的操作。

  3. 数据加载和更新:在页面显示时加载数据,确保用户能够看到最新信息。在页面展示前,可以进行必要的数据预处理,提高界面的响应速度和流畅度。

  4. 用户交互处理:根据页面在生命周期中不同的状态,适时处理用户交互,比如在页面隐藏时暂停动画或停止网络请求,减少不必要的操作。

  5. 事件管理:能够更好地管理用户事件,在合适的时机绑定/解绑事件监听器,避免多次绑定导致的性能问题。

  6. 调试和日志记录:通过生命周期方法,可以在各个阶段记录日志,帮助开发者调试应用,了解应用的状态变化和用户行为。

arkUI的自定义组件和页面的关系

  • 自定义组件:@Component装饰的UI单元,可以组合多个系统组件实现UI的复用,可以调用组件的生命周期。
  • 页面:即应用的UI页面。可以由一个或者多个自定义组件组成,@Entry装饰的自定义组件为页面的入口组件,即页面的根节点,一个页面有且仅能有一个@Entry。只有被@Entry装饰的组件才可以调用页面的生命周期。

页面生命周期,即被@Entry装饰的组件生命周期,提供以下生命周期接口:

  • onPageShow:页面每次显示时触发一次,包括路由过程、应用进入前台等场景。
  • onPageHide:页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景。
  • onBackPress:当用户点击返回按钮时触发。

组件生命周期,即一般用@Component装饰的自定义组件的生命周期,提供以下生命周期接口:

  • aboutToAppear:组件即将出现时回调该接口,具体时机为在创建自定义组件的新实例后,在执行其build()函数之前执行。
  • aboutToDisappear:在自定义组件析构销毁之前执行。不允许在aboutToDisappear函数中改变状态变量,特别是@Link变量的修改可能会导致应用程序行为不稳定。

生命周期流程如下图所示,下图展示的是被@Entry装饰的组件(页面)生命周期

// Index.ets
import router from '@ohos.router';

// Page
@Entry
@Component
struct MyComponent {
  @State showChild: boolean = true;

  // 只有被@Entry装饰的组件才可以调用页面的生命周期
  onPageShow() {
    console.info('Index onPageShow');
  }
  // 只有被@Entry装饰的组件才可以调用页面的生命周期
  onPageHide() {
    console.info('Index onPageHide');
  }

  // 只有被@Entry装饰的组件才可以调用页面的生命周期
  onBackPress() {
    console.info('Index onBackPress');
  }

  // 组件生命周期
  aboutToAppear() {
    console.info('MyComponent aboutToAppear');
  }

  // 组件生命周期
  aboutToDisappear() {
    console.info('MyComponent aboutToDisappear');
  }

  build() {
    Column() {
      // this.showChild为true,创建Child子组件,执行Child aboutToAppear
      if (this.showChild) {
        Child()
      }
      // this.showChild为false,删除Child子组件,执行Child aboutToDisappear
      Button('create or delete Child').onClick(() => {
        this.showChild = false;
      })
      // push到Page2页面,执行onPageHide
      Button('push to next page')
        .onClick(() => {
          router.pushUrl({ url: 'pages/Page2' });
        })
    }

  }
}

// 组件
@Component
struct Child {
  @State title: string = 'Hello World';
  // 组件生命周期
  aboutToDisappear() {
    console.info('[lifeCycle] Child aboutToDisappear')
  }
  // 组件生命周期
  aboutToAppear() {
    console.info('[lifeCycle] Child aboutToAppear')
  }

  build() {
    Text(this.title).fontSize(50).onClick(() => {
      this.title = 'Hello ArkUI';
    })
  }
}

以上示例,Index页面包含两个自定义组件,一个是被@Entry装饰的MyComponent,也是页面的入口组件,即页面的根节点;一个是Child,是MyComponent的子组件。只有@Entry装饰的节点才可以使页面级别的生命周期方法生效,所以MyComponent中声明了当前Index页面的页面生命周期函数。MyComponent和其子组件Child也同时也声明了组件的生命周期函数。

以上示例需要注意的是,区分组件的生命周期和页面的声明周期。只有被@Entry装饰的组件才可以调用页面的生命周期。

// 只有被@Entry装饰的组件才可以调用页面的生命周期
  onPageShow() {
    console.info('Index onPageShow');
  }
  // 只有被@Entry装饰的组件才可以调用页面的生命周期
  onPageHide() {
    console.info('Index onPageHide');
  }

  // 只有被@Entry装饰的组件才可以调用页面的生命周期
  onBackPress() {
    console.info('Index onBackPress');
  }
  • 应用冷启动的初始化流程为:MyComponent aboutToAppear --> MyComponent build --> Child aboutToAppear --> Child build --> Child build执行完毕 --> MyComponent build执行完毕 --> Index onPageShow。
  • 点击“delete Child”,if绑定的this.showChild变成false,删除Child组件,会执行Child aboutToDisappear方法。
  • 点击“push to next page”,调用router.pushUrl接口,跳转到另外一个页面,当前Index页面隐藏,执行页面生命周期Index onPageHide。此处调用的是router.pushUrl接口,Index页面被隐藏,并没有销毁,所以只调用onPageHide。跳转到新页面后,执行初始化新页面的生命周期的流程。
  • 如果调用的是router.replaceUrl,则当前Index页面被销毁,执行的生命周期流程将变为:Index onPageHide --> MyComponent aboutToDisappear --> Child aboutToDisappear。上文已经提到,组件的销毁是从组件树上直接摘下子树,所以先调用父组件的aboutToDisappear,再调用子组件的aboutToDisappear,然后执行初始化新页面的生命周期流程。
  • 点击返回按钮,触发页面生命周期Index onBackPress,且触发返回一个页面后会导致当前Index页面被销毁。
  • 最小化应用或者应用进入后台,触发Index onPageHide。当前Index页面没有被销毁,所以并不会执行组件的aboutToDisappear。应用回到前台,执行Index onPageShow。
  • 退出应用,执行Index onPageHide --> MyComponent aboutToDisappear --> Child aboutToDisappear。

页面周期使用举例

比如以下场景,就需要用到页面周期,从一个页面跳转到另一个页面,跳转后的页面需要拿到第一个页面传递过来的参数信息。就需要在第二个页面的生命周期里获取,举例如下:

// Page1.ets
import router from '@ohos.router';

@Entry
@Component
struct Page1 {
  // 页面生命周期方法
  onPageShow() {
    console.info('Page1 onPageShow');
  }

  // 跳转到Page2并传递数据
  navigateToPage2() {
    const data = { message: 'Hello from Page1' };
    router.pushUrl({ url: 'pages/Page2', params: data });
  }

  build() {
    Column() {
      Text('This is Page 1').fontSize(30);
      Button('Go to Page 2').onClick(() => this.navigateToPage2());
    }
  }
}

// Page2.ets
import router from '@ohos.router';

@Entry
@Component
struct Page2 {
  // 变量用于接收从Page1传来的数据
  @State message: string = '';

  // 页面生命周期方法
  onPageShow() {
    console.info('Page2 onPageShow');
    const params = router.getParams(); // 获取传递的参数
    this.message = params.message; // 赋值给本地状态
  }

  // 返回上一页
  goBack() {
    router.back(); // 返回上一页面
  }

  build() {
    Column() {
      Text(this.message).fontSize(30); // 显示接收到的消息
      Button('Go Back').onClick(() => this.goBack());
    }
  }
}

上述示例中,页面路由仍使用了旧的router,仅作为示例。 看官方文档router 已经被标记为「不推荐」了,同时官方推荐使用 Navigation。Navigation 提供了简单易用的分栏模式,如果你有平板/折叠屏适配需求,那么强烈建议你使用 Navigation。关于Navigation路由的介绍,这是后话,后续单独整理一份文档,这里先略过。关于router切换Navigation介绍,可参见官方文档:文档中心-Router切换Navigation

写在最后

最后,推荐下笔者的业余开源app影视项目“爱影家”,推荐分享给与我一样喜欢免费观影的朋友。【注:该项目仅限于学习研究使用!请勿用于其他用途!】

开源地址:爱影家app开源项目介绍及源码

https://gitee.com/yyz116/imovie

其他资源

HarmonyOS NEXT应用开发(一、打造最好用的网络通信模块组件)-CSDN博客

OpenHarmony三方库中心仓

UIAbility组件生命周期

页面和自定义组件生命周期

鸿蒙开发ArkTS 页面和自定义组件的生命周期 - 亲爱的老王哥 - 博客园

一、鸿蒙ArkTS/ArkUI实战-页面和自定义组件生命周期 - 简书

官方 Router切换Navigation 指导

【HarmonyOS】听说你还在用 router 做页面路由?我们知道鸿蒙上使用 router 模块进行页面跳转,转眼几 - 掘金

「HarmonyNextOS」页面路由跳转Router更换为Navigation_harmonyos next 页面跳转-CSDN博客

文档中心-设置组件导航和页面路由

【OpenHarmony】ArkTS 语法基础 ③ ( @Component 自定义组件生命周期回调函数 | @Entry 页面生命周期回调函数 )_wx5c66153045676的技术博客_51CTO博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2211630.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

7-I2C与AHT20温湿度传感器

I2C与AHT20温湿度传感器 嵌入式领域另一种常见的通信IIC通信,并用其与AHT20传感器进行交互,获取房间的温度与湿度。 I2C有一条用于传递数据的数据线称为SDA(Serial Data),另一条是用于提供同步时钟脉冲的时钟线SCL&am…

看图识微分与导数概念。

可建立如草图所示的局部坐标系。增量Δydy余项是草图中曲线的方程,微分dyydx(是关于dx的一次函数)是草图中切线的方程。草图形象直观地显示曲线Δy不切线dy。

安全可靠测评结果公告(2024年第1号)

大家可以选择对应的数据库,中央处理器,供参考;尤其是 水资源安可系统 智慧农业安可系统 智慧水利安可系统、智慧水务安可系统,企业安可系统 等参考使用

# 在执行 rpm 卸载软件使用 nodeps 参数时,报错 error: package nodeps is not installed 分析

在执行 rpm 卸载软件使用 nodeps 参数时,报错 error: package nodeps is not installed 分析 一、问题描述: 在执行 rpm 卸载软件使用 nodeps 参数时,报错 error: package nodeps is not installed 如下图: 二、报错分析&…

Java项目分层思路

Java项目分层思路 一、前言二、了解常见的术语1. 应用开发中使用的术语2. 建模和架构设计层面术语总结 三、如何划分1. 单个module2. 多个module 一、前言 每个人、每个开发团队的规范习惯都不太一样,没有固定标准,合适的才是最好的。 二、了解常见的术…

Python Django 查询集的延迟加载特性

Django 查询集的延迟加载特性 一、引言 在 Django 的开发过程中,查询集(QuerySet)是我们与数据库进行交互的重要工具。查询集提供了一种高效的方式来检索和操作数据库中的数据,且能够进行懒加载(Lazy Loading&#x…

Gin框架教程02:AsciiJSON

什么是 AsciiJSON? AsciiJSON 是 Gin 框架中的一个方法,用于生成仅包含 ASCII 字符的 JSON。对于非 ASCII 字符(例如汉字、特殊符号),AsciiJSON 会将其转义为 Unicode 表示(如 \uXXXX)&#xff…

使用CSS+SVG实现加载动画

使用CSSSVG实现加载动画 效果展示 CSS知识点 SVG元素使用SVG相关CSS属性运用 整体页面布局 <section><div class"box"><div class"loader"><svg><circle cx"40" cy"40" r"40"></circl…

vue从0开始的项目搭建(含环境配置)

一、环境准备 下载node.js 检查node.js版本 替换npm下载源 1.下载node.js: Node.js — 在任何地方运行 JavaScript (nodejs.org) 2.查看版本: windowsr输入cmd进入输入node -v命令查看版本号是否出现确认是否安装 2.替换npm下载源: npm config set registry https://reg…

深入Semantic Kernel:插件开发与实践应用(进阶篇)

文章目录 一、引言二、开发Semantic Kernel插件三、实战3.1 时间信息插件3.2 小部件工厂插件3.3 初始化Semantic Kernel实例3.4 四个实战示例3.4.1 模型幻觉3.4.2 给模型提供时间信息3.4.3 AI自动调用函数3.4.4 AI自动调用和使用枚举 四、结论 一、引言 在上一篇入门文章《探索…

vue3.x系列之v-model的使用技巧及面试高频问题

在前面的一篇文章中&#xff0c;我们分析了v-model在v2版中的用法。这次我们分析下在v3中的使用技巧。学习之前&#xff0c;请忘记之前的v2语法&#xff0c;现在的更加简洁易用。 组件上面的v-model 在v3.4版之前的写法如下 子组件Child.vue <!-- Child.vue --> <…

MobileViews: A Large-Scale Mobile GUI Dataset论文学习

这一片论文的工作主要集中在探索app上。 “ 设计#1&#xff1a;LLM增强型自动应用爬虫。为了提高应用程序遍历效率&#xff0c;我们引入了MobileViews Crawler&#xff0c;它使用固定的交互规则来处理繁琐的应用程序操作&#xff0c;LLM增强了其处理复杂UI状态的能力。在这个…

[C++ 核心编程]笔记 4.1.2 struct和class的区别

4.1.2 struct和class的区别 在C中 struct和class唯一的区别就在于 默认的访问权限不同 区别: struct 默认权限为公共class 默认权限为私有 #include<iostream> using namespace std;class C1 {int m_A;//默认私有 }; struct C2 {int m_A;//默认共有 };int main() {//s…

Android -- [SelfView] 多动画效果图片播放器

Android – [SelfView] 多动画效果图片播放器 效果&#xff08;录制的有点卡&#xff09; 1. 引用&#xff1a; <com.nepalese.virgolib.widget.image.BaseImageViewandroid:id"id/base_image"android:layout_width"match_parent"android:layout_heigh…

2024让我爱不释手的Mac清理神器CleanMyMac X4.15.8免费版

大家好&#xff0c;今天我要和大家分享一款让我爱不释手的Mac清理神器——CleanMyMac X。作为一个长期使用Mac的用户&#xff0c;我深知电脑在长时间使用后容易出现卡顿、存储空间不足等问题。而自从我遇到了CleanMyMac X&#xff0c;这些问题都迎刃而解啦&#xff01; #### 一…

实现一个进度条对话框

效果如下&#xff1a; 点击按钮后开启1个线程模拟加载什么东西&#xff0c;同时弹出1个进度条对话框&#xff0c;进度条达到最大值后&#xff0c;进度条对话框慢慢变透明然后消失 关键点是我们要在进度条类中添加1个槽函数&#xff0c;在这个槽函数中设置进度条的值 代码如下…

高校学科竞赛平台:SpringBoot实现的高效开发流程

3系统分析 3.1可行性分析 通过对本高校学科竞赛平台实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本高校学科竞赛平台采用SSM框架&#xff0c;JAVA作为开发语…

【Java】集合中单列集合详解(一):Collection与List

目录 引言 一、Collection接口 1.1 主要方法 1.1.1 添加元素 1.1.2 删除元素 1.1.3 清空元素 1.1.4 判断元素是否存在 1.1.5 判断是否为空 1.1.6 求取元素个数 1.2 遍历方法 1.2.1 迭代器遍历 1.2.2 增强for遍历 1.2.3 Lambda表达式遍历 1.2.4 应用场景 二、…

Autosar Dcm配置-App到Boot的跳转及1002回复配置及实现-基于ETAS软件

文章目录 前言App软复位的实现Dcm配置BswM配置BswMModeRequestPortBswMModeConditionBswMLogicalExpressionBswMActionListApp回复1002的实现Dcm配置代码实现App回NRC78的实现Dcm配置代码实现总结前言 在软件刷写流程中,上位机(诊断仪)发送1002后,APP检查允许跳转boot后,在…

python脚本处理--批量压缩解压文件(zip、rar) / 读取txt文件并在txt每行文件后面增加内容

一、批量压缩、解压文件 os库是为了监测生成的文件夹是否已存在。主要的库是zipfile&#xff0c;它提供了有关windows下的文件/文件夹的压缩、解压的函数。 压缩、解压函数及整体代码如下&#xff1a; import os import zipfiledef Compress_path_zip(path_all):path_all_list…