大型软件工程中,代码和业务往往会划分为多个模块,分别由不同的开发人员进行开发。最终一个应用可能由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、附件
上述案例完整示例代码如下: (代码待补充)

被折叠的 条评论
为什么被折叠?



