Harmony之路:页面的舞台——Ability与页面路由的奥秘

一、引入:理解Stage模型的核心架构

在HarmonyOS 5的Stage模型中,UIAbility是应用功能的基本单元,它代表一个可独立运行的应用模块,每个UIAbility实例都对应一个窗口舞台(WindowStage),用于承载和管理页面(Page)的显示与交互。这种设计让应用能够以更灵活的方式组织功能,支持多窗口、多任务等复杂场景。

二、讲解:UIAbility生命周期与页面路由实战

1. UIAbility生命周期详解

UIAbility的生命周期包含四个核心状态:Create(创建)、Foreground(前台)、Background(后台)、Destroy(销毁),以及窗口相关的WindowStage生命周期。

基础生命周期示例:

import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';

export default class EntryAbility extends UIAbility {
  // Ability实例创建时触发
  onCreate(want, launchParam) {
    console.log('Ability创建完成');
    // 初始化Ability级资源,如用户Token、数据库连接等
  }

  // 窗口舞台创建时触发
  onWindowStageCreate(windowStage: window.WindowStage) {
    console.log('窗口舞台创建');
    // 加载首页页面
    windowStage.loadContent('pages/Index', (err, data) => {
      if (err) {
        console.error('页面加载失败', err);
        return;
      }
      console.log('页面加载成功');
    });
  }

  // Ability切换到前台时触发
  onForeground() {
    console.log('Ability进入前台');
    // 恢复前台资源,如开启定位、网络请求等
  }

  // Ability切换到后台时触发
  onBackground() {
    console.log('Ability进入后台');
    // 释放后台不需要的资源,如暂停动画、停止定位等
  }

  // 窗口舞台销毁时触发
  onWindowStageDestroy() {
    console.log('窗口舞台销毁');
    // 释放窗口相关资源
  }

  // Ability实例销毁时触发
  onDestroy() {
    console.log('Ability销毁');
    // 清理所有资源,如关闭数据库连接、注销监听等
  }
}

2. 页面路由基础跳转

使用@ohos.router模块实现页面间的跳转和数据传递。

基础跳转示例:

import router from '@ohos.router';

@Entry
@Component
struct IndexPage {
  @State message: string = '首页';

  build() {
    Column({ space: 20 }) {
      Text(this.message)
        .fontSize(24)
      
      Button('跳转到详情页')
        .width('80%')
        .height(40)
        .onClick(() => {
          // 使用pushUrl保留当前页面,可返回
          router.pushUrl({
            url: 'pages/DetailPage',
            params: {
              id: 123,
              title: '商品详情'
            }
          }, router.RouterMode.Standard);
        })
      
      Button('替换当前页')
        .width('80%')
        .height(40)
        .onClick(() => {
          // 使用replaceUrl替换当前页面,无法返回
          router.replaceUrl({
            url: 'pages/LoginPage'
          }, router.RouterMode.Single);
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

3. 目标页面接收参数

在目标页面中通过router.getParams()获取传递的参数。

import router from '@ohos.router';

@Entry
@Component
struct DetailPage {
  @State id: number = 0;
  @State title: string = '';

  aboutToAppear() {
    // 在页面显示时获取传递的参数
    const params = router.getParams();
    this.id = params['id'] || 0;
    this.title = params['title'] || '';
    console.log('接收到的参数:', params);
  }

  build() {
    Column({ space: 20 }) {
      Text(`商品ID: ${this.id}`)
        .fontSize(20)
      
      Text(`商品标题: ${this.title}`)
        .fontSize(18)
        .fontColor(Color.Gray)
      
      Button('返回上一页')
        .width('80%')
        .height(40)
        .onClick(() => {
          router.back(); // 返回上一页
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

4. 页面返回与参数回传

除了简单的返回,还可以在返回时传递数据给目标页面。

@Entry
@Component
struct EditPage {
  @State inputValue: string = '';

  build() {
    Column({ space: 20 }) {
      TextInput({ placeholder: '请输入内容', text: this.inputValue })
        .width('80%')
        .height(40)
        .onChange((value: string) => {
          this.inputValue = value;
        })
      
      Button('保存并返回')
        .width('80%')
        .height(40)
        .onClick(() => {
          // 返回并传递数据
          router.back({
            url: 'pages/Index',
            params: {
              result: this.inputValue,
              timestamp: new Date().getTime()
            }
          });
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

5. 路由实例模式详解

Router模块提供两种实例模式,控制页面的复用行为。

Standard模式(多实例):

// 每次跳转都会创建新实例
router.pushUrl({
  url: 'pages/DetailPage',
  params: { id: 1 }
}, router.RouterMode.Standard);

Single模式(单实例):

// 如果目标页面已存在,则复用并移动到栈顶
router.pushUrl({
  url: 'pages/DetailPage',
  params: { id: 1 }
}, router.RouterMode.Single);

6. 页面栈管理

管理页面栈的深度和状态。

// 获取页面栈深度
const stackSize = router.getLength();
console.log('当前页面栈深度:', stackSize);

// 清空历史页面栈(保留当前页面)
router.clear();

// 获取当前页面状态
const currentState = router.getState();
console.log('当前页面:', currentState);

// 获取指定索引的页面状态
const pageState = router.getStateByIndex(0);
console.log('首页状态:', pageState);

三、总结:掌握页面导航的核心要点

✅ 核心知识点回顾

  1. UIAbility是功能单元:每个UIAbility代表一个独立的应用模块,管理自己的生命周期和窗口舞台
  2. 页面路由是导航核心:使用@ohos.router模块实现页面跳转、参数传递和返回
  3. 生命周期管理:掌握onCreate、onWindowStageCreate、onForeground、onBackground等回调时机
  4. 参数传递方式:通过params传递数据,在目标页面使用router.getParams()获取
  5. 实例模式选择:Standard模式创建新实例,Single模式复用已有实例

⚠️ 常见问题与解决方案

  1. 页面跳转失败:检查main_pages.json中是否已注册目标页面路径
  2. 参数获取为空:确保在aboutToAppear()onPageShow()中获取参数
  3. 页面栈溢出:页面栈最大支持32个页面,及时使用router.clear()清理
  4. 内存泄漏:在onDestroy()中释放所有资源,避免内存泄漏

🎯 最佳实践建议

  1. 合理划分UIAbility:根据功能模块划分UIAbility,避免单个UIAbility过于臃肿
  2. 参数传递规范化:定义参数接口类型,避免类型错误
  3. 生命周期优化:在合适的生命周期回调中执行相应操作,如onForeground中恢复数据,onBackground中释放资源
  4. 页面栈管理:控制页面栈深度,避免过深导致性能问题

下一步预告:在第六篇中,我们将深入学习列表渲染,掌握使用List和ForEach高效渲染复杂列表的技巧,让应用能够展示丰富的数据内容。

posted @ 2025-12-23 23:01  蓝莓Reimay  阅读(3)  评论(0)    收藏  举报