【鸿蒙ArkUI路由/导航系列】八:Navigation跨包路由,迈入高级路由能力

大型软件工程中,代码和业务往往会划分为多个模块,分别由不同的开发人员进行开发。最终一个应用可能由Hap,Hsp,Har多种包组成,页面路由需要在不同的包中流转。

针对这种情况,Navigation路由框架也支持跨包跳转,如从Hap中的主页,跳转到Hsp/Har中的子页面,也可以从Hsp/Har中的子页面返回到Hap中的主页。

如下示例中,Hap包中有两个页面 HapPageA和HapPageB,Hsp包中有两个页面HspPageA和HspPageB,Har包中也有两个页面HarPageA,HarPageB,实现这六个页面之间的相互跳转。

1、模块配置

首先,跨包路由需要使用Navigation系统路由表,需要在hap,hsp,har包中分别配置对应的路由表。步骤如下:

Step 1

在每个模块的module.json5中增加"routerMap"字段,并且指定内容为"$profile:router_map";

Hap模块: 

Hsp模块: 

Har模块: 

Step 2

在每个模块的 "src/main/resources/base/profile/"目录(如果没有该目录的话,自己创建一个即可)下创建一个router_map.json文件

Steps3

在router_map.json文件中填写具体的路由表信息(下面仅以Hap模块中的配置为例),示例如下:

{
  "routerMap": [
    {
      "name": "HapPageA",
      "pageSourceFile": "src/main/ets/pages/HapPageA.ets",
      "buildFunction": "HapPageABuilder",
      "data": {
        "description": "this is HapPageA"
      }
    },
    {
      "name": "HapPageB",
      "pageSourceFile": "src/main/ets/pages/HapPageB.ets",
      "buildFunction": "HapPageBBuilder",
      "data": {
        "description": "this is HapPageB"
      }
    }
  ]
}

路由表由一个名字为routerMap的数组组成,数组中的每一个item代表一个路由跳转目的地,需要由"name","pageSourceFile","buildFunction"三个必选字段和一个"data"可选字段组成。

name代表Navigation路由跳转时pushPath指定的name,pageSourceFile代表对应的页面所在的文件路径,buildFunction代表文件中构建页面的@Builder函数,data则表示一个可选的参数,在目标NavDestination页面的onReady生命周期中可以通过传入的NavDestinationContext.getConfigInRouteMap()函数拿到该data数据。

2、代码编写

下面以Hap包中的HapPageA为例:

import { ControlPanel } from './Common';
@Component
export struct HapPageA {
  build() {
    NavDestination() {
      Stack({alignContent: Alignment.Center}) {
        ControlPanel()
      }.width('100%').height('100%')
    }.title('HapPageA')
    .onReady((ctx: NavDestinationContext) => {
      let config = ctx.getConfigInRouteMap();
      console.log(`testTag HapPageA config.data: ${JSON.stringify(config?.data)}`)
    })
  }
}

// 页面的buildFunction,用于构造页面
@Builder
export function HapPageABuilder(): void {
  HapPageA()
}

其中Common是为了方便演示页面间跳转抽出来的一个控制面板组件,示例如下:

@Component
export struct ControlPanel {
  private stack: NavPathStack | undefined = undefined;
  aboutToAppear(): void {
    let info = this.queryNavigationInfo();
    this.stack = info?.pathStack;
  }
  build() {
    Column() {
      Button('push HapPageA').onClick(() => {
        this.stack?.pushPath({ name: 'HapPageA' })
      })
      Button('push HapPageB').onClick(() => {
        this.stack?.pushPath({ name: 'HapPageB' })
      })
      Button('push HarPageA').onClick(() => {
        this.stack?.pushPath({ name: 'HarPageA' })
      })
      Button('push HarPageB').onClick(() => {
        this.stack?.pushPath({ name: 'HarPageB' })
      })
      Button('push HspPageA').onClick(() => {
        this.stack?.pushPath({ name: 'HspPageA' })
      })
      Button('push HspPageB').onClick(() => {
        this.stack?.pushPath({ name: 'HspPageB' })
      })
    }
  }
}

3、编译构建

因为Har和Hsp是被Hap模块依赖的,所以需要先编译Har和Hsp,然后把他们的编译产物放到一个公共目录里面。

Step 1:编译Har

Step 2:编译Hsp

Step 3:配置依赖包

将Har和Hsp的编译产物放到一个公共路径中,这里为了演示方便,我们在工程根目录创建一个libs目录,把前面两个步骤的产物都复制到该目录:

Step 4:配置依赖关系

由于Hap依赖于前面的Hsp和Har,因此需要在Hap模块的oh-package.json5配置文件中增加依赖关系,示例如下:

{
  "name": "entry",
  "version": "1.0.0",
  "description": "Please describe the basic information.",
  "main": "",
  "author": "",
  "license": "",
  "dependencies": {
    "har_a": "file:../libs/HAR_A.har", // 因为演示中使用的是本地依赖包,所以通过file指示一个固定的文件。
    "hsp_a": "file:../libs/HSP_A-default.tgz", // 因为演示中使用的是本地依赖包,所以通过file指示一个固定的文件。
  }
}

配置好依赖关系后,需要指定 ohpm install 命令安装对应的包。

Step 5:编译运行

最后编译构建Hap包 

需要注意的是由于Hap依赖于Hsp,所以安装到设备中时需要同时安装Hap和Hsp,应用才能正常运行。

如下为演示效果:

4、附件

上述案例完整示例代码如下: (代码待补充)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值