鸿蒙应用的生命周期与页面跳转:从入门到实战

前言:理解生命周期是开发的基础

很多新手刚学鸿蒙,上来就写UI和业务逻辑,结果遇到各种莫名其妙的bug:

  • 页面跳转后数据丢失了
  • 退出页面后音乐还在播放
  • 切回应用后状态不对
  • 应用在后台运行时耗电严重

这些问题90%都是因为没有正确理解和使用生命周期导致的。

生命周期就像是应用和页面的"人生轨迹",从创建到销毁,每个阶段都会触发对应的回调方法。只有掌握了这些回调的调用时机和作用,你才能写出健壮、高效的鸿蒙应用。

这篇文章我会用最直白的语言,带你搞懂鸿蒙的应用生命周期和页面生命周期,然后教你如何进行页面跳转和数据传递,最后通过一个完整的实战,把这些知识点融会贯通。

一、应用生命周期

应用生命周期指的是整个应用从启动到退出的整个过程。HarmonyOS NEXT中,应用的生命周期由AbilityStage类管理。

1.1 应用的四个生命周期阶段

阶段 回调方法 调用时机 主要作用
创建 onCreate() 应用首次启动时调用,整个应用生命周期只调用一次 初始化全局资源、配置全局变量、注册全局事件
前台 onForeground() 应用从后台切换到前台时调用 恢复应用状态、重新获取焦点、继续播放音乐
后台 onBackground() 应用从前台切换到后台时调用 保存应用状态、暂停不必要的操作、释放部分资源
销毁 onDestroy() 应用完全退出时调用 释放所有全局资源、取消所有网络请求、保存最终数据

1.2 代码示例

entry/src/main/ets/entryability/EntryAbility.ets文件中,你可以重写这些生命周期方法:

typescript 复制代码
import AbilityStage from '@ohos.app.ability.AbilityStage';
import hilog from '@ohos.hilog';

const TAG: string = 'MyApplication';
const DOMAIN: number = 0x0000;

export default class EntryAbility extends AbilityStage {
  // 应用创建时调用
  onCreate() {
    hilog.info(DOMAIN, TAG, '应用创建了');
    // 初始化全局配置
    // 初始化数据库
    // 注册全局事件监听
  }

  // 应用进入前台时调用
  onForeground() {
    hilog.info(DOMAIN, TAG, '应用进入前台了');
    // 恢复应用状态
    // 继续播放音乐
  }

  // 应用进入后台时调用
  onBackground() {
    hilog.info(DOMAIN, TAG, '应用进入后台了');
    // 保存应用状态
    // 暂停音乐播放
    // 停止定位等耗电操作
  }

  // 应用销毁时调用
  onDestroy() {
    hilog.info(DOMAIN, TAG, '应用销毁了');
    // 释放所有全局资源
    // 取消所有网络请求
    // 注销全局事件监听
  }
}

重要提醒:

  • onCreate()只在应用首次启动时调用一次,应用在后台被杀死后重新启动也会再次调用
  • 不要在onBackground()中做耗时操作,系统会限制应用在后台的运行时间
  • 一定要在onDestroy()中释放所有资源,否则会导致内存泄漏

二、页面生命周期

页面生命周期指的是单个页面从创建到销毁的整个过程。这是我们平时开发中接触最多的部分。

2.1 页面的四个核心生命周期回调

回调方法 调用时机 主要作用
aboutToAppear() 页面即将显示时调用,在build()方法之前 加载页面数据、初始化页面状态、注册页面事件
onPageShow() 页面完全显示时调用 开始动画、开始播放视频、获取焦点
onPageHide() 页面被隐藏时调用(比如跳转到新页面或应用进入后台) 暂停动画、暂停视频播放、保存页面临时状态
aboutToDisappear() 页面即将销毁时调用 释放页面资源、取消网络请求、注销页面事件

2.2 生命周期调用顺序演示

我们写一个简单的页面,在所有生命周期方法中添加日志,看看它们的调用顺序:

typescript 复制代码
@Entry
@Component
struct LifeCycleDemo {
  build() {
    Column() {
      Text("生命周期演示页面")
        .fontSize(24)
        .margin(20);
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center);
  }

  // 页面即将显示
  aboutToAppear() {
    console.log("页面即将显示:aboutToAppear");
  }

  // 页面完全显示
  onPageShow() {
    console.log("页面完全显示:onPageShow");
  }

  // 页面被隐藏
  onPageHide() {
    console.log("页面被隐藏:onPageHide");
  }

  // 页面即将销毁
  aboutToDisappear() {
    console.log("页面即将销毁:aboutToDisappear");
  }
}

运行结果:

  1. 打开页面:aboutToAppearbuild()onPageShow
  2. 跳转到新页面:onPageHide
  3. 返回到该页面:onPageShow
  4. 退出页面:onPageHideaboutToDisappear

常见使用场景:

  • aboutToAppear()中请求网络数据
  • onPageShow()中开始播放视频
  • onPageHide()中暂停视频播放
  • aboutToDisappear()中取消网络请求

三、路由导航基础

鸿蒙应用中,页面之间的跳转是通过router模块实现的。路由就像是应用内部的导航系统,帮你在不同页面之间切换。

3.1 配置路由表

在进行页面跳转之前,你需要先在main_pages.json文件中配置路由表。

打开entry/src/main/resources/base/profile/main_pages.json

json 复制代码
{
  "src": [
    "pages/Index",
    "pages/Login",
    "pages/Home"
  ]
}

每添加一个新页面,都要在这里注册对应的路由路径,否则无法跳转。

3.2 常用路由跳转方式

1. push跳转(最常用)

添加一个新页面到路由栈顶部,当前页面会被保留在栈中。点击返回按钮可以回到上一个页面。

typescript 复制代码
import router from '@ohos.router';

// 跳转到首页
router.pushUrl({
  url: 'pages/Home'
});
2. replace跳转

替换当前页面,当前页面会被销毁。点击返回按钮不会回到这个页面。

typescript 复制代码
// 用首页替换当前登录页
router.replaceUrl({
  url: 'pages/Home'
});

使用场景: 登录成功后跳转到首页,这时候用户不应该能返回到登录页。

3. 返回上一页
typescript 复制代码
// 返回上一个页面
router.back();
4. 返回指定页面
typescript 复制代码
// 返回到首页
router.back({
  url: 'pages/Home'
});

四、页面间数据传递

页面跳转时,经常需要把数据从一个页面传递到另一个页面。鸿蒙提供了几种简单高效的数据传递方式。

4.1 通过路由参数传递(最常用)

这是最简单也是最常用的数据传递方式,适合传递少量数据。

发送方(登录页):

typescript 复制代码
import router from '@ohos.router';

// 跳转到首页,并传递用户名
router.pushUrl({
  url: 'pages/Home',
  params: {
    username: '张三',
    userId: 123456
  }
});

接收方(首页):

typescript 复制代码
import router from '@ohos.router';

@Entry
@Component
struct Home {
  // 接收传递过来的参数
  private params: Record<string, Object> = router.getParams() as Record<string, Object>;
  private username: string = this.params.username as string;
  private userId: number = this.params.userId as number;

  build() {
    Column() {
      Text(`欢迎你,${this.username}`)
        .fontSize(24);
      
      Text(`你的用户ID是:${this.userId}`)
        .fontSize(18)
        .margin({ top: 10 });
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center);
  }
}

4.2 传递复杂对象

你也可以传递复杂的对象:

typescript 复制代码
// 定义用户对象
interface User {
  username: string;
  age: number;
  gender: string;
}

// 发送方
const user: User = {
  username: '李四',
  age: 25,
  gender: '男'
};

router.pushUrl({
  url: 'pages/Home',
  params: {
    user: user
  }
});

// 接收方
private params: Record<string, Object> = router.getParams() as Record<string, Object>;
private user: User = this.params.user as User;

五、实战:从登录页跳转到首页并传递用户信息

现在我们把前面学的所有内容结合起来,实现一个完整的登录跳转流程:

  1. 用户在登录页输入用户名和密码
  2. 点击登录按钮,验证成功后跳转到首页
  3. 将用户名传递给首页,在首页显示欢迎信息
  4. 在各个生命周期方法中添加日志,观察调用顺序

5.1 第一步:创建首页

pages目录下创建一个新的文件Home.ets

typescript 复制代码
import router from '@ohos.router';
import hilog from '@ohos.hilog';

const TAG: string = 'HomePage';
const DOMAIN: number = 0x0000;

@Entry
@Component
struct Home {
  // 接收登录页传递过来的用户名
  private params: Record<string, Object> = router.getParams() as Record<string, Object>;
  private username: string = this.params?.username as string || "游客";

  build() {
    Column() {
      Text(`欢迎回来,${this.username}!`)
        .fontSize(28)
        .fontWeight(FontWeight.Bold)
        .margin({ bottom: 30 });

      Text("这是首页")
        .fontSize(20)
        .margin({ bottom: 50 });

      Button("退出登录")
        .width(200)
        .height(50)
        .backgroundColor('#ff3b30')
        .onClick(() => {
          // 退出登录,返回登录页
          router.replaceUrl({
            url: 'pages/Login'
          });
        });
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center);
  }

  aboutToAppear() {
    hilog.info(DOMAIN, TAG, "首页即将显示:aboutToAppear");
  }

  onPageShow() {
    hilog.info(DOMAIN, TAG, "首页完全显示:onPageShow");
  }

  onPageHide() {
    hilog.info(DOMAIN, TAG, "首页被隐藏:onPageHide");
  }

  aboutToDisappear() {
    hilog.info(DOMAIN, TAG, "首页即将销毁:aboutToDisappear");
  }
}

5.2 第二步:修改登录页

修改我们上一篇文章写的登录页,添加跳转逻辑:

typescript 复制代码
import router from '@ohos.router';
import hilog from '@ohos.hilog';

const TAG: string = 'LoginPage';
const DOMAIN: number = 0x0000;

@Entry
@Component
struct LoginPage {
  @State username: string = "";
  @State password: string = "";
  @State isPasswordVisible: boolean = false;
  @State isLoading: boolean = false;

  build() {
    Column() {
      // Logo和标题部分和之前一样,这里省略...

      // 用户名输入框
      TextInput({ placeholder: "请输入手机号/用户名", text: this.username })
        .width('85%')
        .height(50)
        .padding({ left: 15, right: 15 })
        .backgroundColor('#f5f5f5')
        .borderRadius(8)
        .margin({ bottom: 15 })
        .onChange((value) => {
          this.username = value;
        });

      // 密码输入框
      // 这里省略...

      // 登录按钮
      Button(this.isLoading ? "登录中..." : "登录")
        .width('85%')
        .height(50)
        .backgroundColor(this.isLoginButtonEnabled() ? '#007aff' : '#cccccc')
        .fontSize(18)
        .borderRadius(8)
        .enabled(this.isLoginButtonEnabled() && !this.isLoading)
        .onClick(() => {
          this.handleLogin();
        });

      // 底部链接
      // 这里省略...
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#ffffff');
  }

  isLoginButtonEnabled(): boolean {
    return this.username.length > 0 && this.password.length > 0;
  }

  handleLogin() {
    // 简单的输入验证
    if (this.username.length < 3) {
      console.log("用户名长度不能少于3位");
      return;
    }

    if (this.password.length < 6) {
      console.log("密码长度不能少于6位");
      return;
    }

    // 模拟登录请求
    this.isLoading = true;
    
    setTimeout(() => {
      this.isLoading = false;
      hilog.info(DOMAIN, TAG, `登录成功!用户名:${this.username}`);
      
      // 登录成功,跳转到首页,并传递用户名
      router.replaceUrl({
        url: 'pages/Home',
        params: {
          username: this.username
        }
      });
    }, 2000);
  }

  aboutToAppear() {
    hilog.info(DOMAIN, TAG, "登录页即将显示:aboutToAppear");
  }

  onPageShow() {
    hilog.info(DOMAIN, TAG, "登录页完全显示:onPageShow");
  }

  onPageHide() {
    hilog.info(DOMAIN, TAG, "登录页被隐藏:onPageHide");
  }

  aboutToDisappear() {
    hilog.info(DOMAIN, TAG, "登录页即将销毁:aboutToDisappear");
  }
}

5.3 第三步:配置路由表

打开main_pages.json,确保首页已经注册:

json 复制代码
{
  "src": [
    "pages/Login",
    "pages/Home"
  ]
}

5.4 运行效果

  1. 应用启动后显示登录页
  2. 输入用户名和密码,点击登录
  3. 登录成功后跳转到首页,显示欢迎信息
  4. 点击"退出登录"按钮,返回到登录页

你可以在DevEco Studio的日志窗口中,看到各个生命周期方法的调用顺序,这样就能更直观地理解页面的生命周期了。

总结

今天我们学习了鸿蒙应用的生命周期和页面跳转,这是开发任何鸿蒙应用都必须掌握的基础知识。

核心要点总结:

  1. 应用生命周期有四个阶段:Create、Foreground、Background、Destroy
  2. 页面生命周期有四个核心回调:aboutToAppear、onPageShow、onPageHide、aboutToDisappear
  3. 使用router模块进行页面跳转,常用的有pushUrl和replaceUrl两种方式
  4. 通过路由参数可以在页面之间传递数据,支持基本类型和复杂对象
  5. 一定要在合适的生命周期方法中做合适的事情,避免出现内存泄漏和状态错误

福利时间!

我已经为大家准备了路由导航完整示例代码,包含了所有常用的跳转方式、数据传递方法,还有生命周期的详细演示。下载后直接导入DevEco Studio就能运行。

获取方式:

关注我的账号,私信回复"路由导航",即可免费获取完整源码!

下一篇文章,我会带大家深入学习鸿蒙的状态管理,教你如何在多个组件和多个页面之间共享数据。如果这篇文章对你有帮助,别忘了点赞、收藏、转发给你的朋友!有任何问题,欢迎在评论区留言。

相关推荐
轻口味2 小时前
HarmonyOS 6.1.1 全栈实战录 - 88 实战 Ability Kit 启动生命周期预热与快照恢复机
华为·harmonyos·鸿蒙
Goway_Hui2 小时前
【鸿蒙原生应用开发--ArkUI--013】Exercise-tracker 运动记录应用开发教程
华为·harmonyos
想你依然心痛2 小时前
HarmonyOS 6(API 23)实战:基于悬浮导航、沉浸光感与HMAF的“图谱智脑“——PC端AI智能体沉浸式知识图谱构建工作台
人工智能·ar·知识图谱·harmonyos·智能体
想你依然心痛3 小时前
HarmonyOS 6(API 23)实战:基于悬浮导航、沉浸光感与HMAF的“律界智脑“——PC端AI智能体沉浸式法律文档智能审查工作台
人工智能·华为·ar·harmonyos·智能体
特立独行的猫a3 小时前
鸿蒙 PC 平台 Python 第三方库移植全景指南
python·华为·harmonyos·三方库移植·鸿蒙pc
大雷神3 小时前
第31篇|位置信息写入照片记录:为什么拍照时要带上地点
harmonyos
Goway_Hui3 小时前
【鸿蒙原生应用开发--ArkUI--012】Currency-converter 汇率转换应用开发教程
华为·harmonyos
李二。4 小时前
鸿蒙 HarmonyOS 校园风登录页面开发实战 —— 基于 ArkTS 的 Stage 模型完整教程
华为·harmonyos
大雷神4 小时前
第30篇|图片文件落盘:沙箱路径、Uri 与后续读取
harmonyos