07-超级App软件平台@路由规则设计-【通用路由管理组件设计】

通用路由管理工具组件设计

本专题为软件平台路由规则设计不限于移动端 ,涵盖 移动端Web电脑(桌面)手表与手环等智能穿戴 。在 01~06 基础上,抽象出一套跨端可复用 的路由管理组件设计:统一协议、各端适配层、可插拔拦截器与扩展点。软件体系 覆盖 iOS、Android、HarmonyOS、Flutter、MacOS、WinOS、WebApp、ReactNative、WatchOS 及智能穿戴形态,便于在各端保持一致的路由语义与配置,详见 08-软件体系与多平台路由对照


一、设计目标与原则

1.1 目标

  • 协议统一:path、query、navigate 方式(push/replace/present)在各端语义一致。
  • 多端适配:同一套「路由表 + 拦截器 + 深链接」逻辑,通过各端适配层落地到具体平台 API。
  • 可扩展:支持动态路由表、拦截器链、服务发现、编译期/运行时双轨注册。
  • 可观测:统一埋点、耗时与降级入口,便于监控与排障。

1.2 原则

  • 单一数据源:路由表(含动态下发)为唯一真实来源,深链接、App 内跳转均解析为 path + params 后查表。
  • 平台无关接口:核心接口不依赖 UIKit/Activity/Widget,仅依赖 path、params、result 等抽象。
  • 适配器隔离:平台相关实现(如 pushViewController/startActivity/context.go)封装在适配层,核心层只调用「打开目标」「返回结果」等抽象接口。

二、核心抽象与整体架构

2.1 概念模型(思维导图)

mindmap root((通用路由组件)) 协议层 Path 规范 Query / Params Navigate 方式 核心层 RouteTable 路由表 InterceptorChain 拦截器链 Router 门面 适配层 九端 iOS Android HarmonyOS Flutter MacOS WinOS WebApp ReactNative WatchOS 扩展 深链接注入 动态表合并 监控埋点

2.2 分层架构图

flowchart TB subgraph 调用方 A[业务 / 深链接 / H5] end subgraph 门面 B[Router.navigate / open / getService] end subgraph 核心层 C[Path 解析] D[RouteTable 查找] E[InterceptorChain] F[Target 执行] end subgraph 适配层 九端 G[iOS/MacOS/WatchOS] H[Android/HarmonyOS] I[Flutter/ReactNative] J[WebApp/WinOS] end A --> B --> C --> D --> E --> F F --> G F --> H F --> I F --> J

2.3 统一 Path 与参数规范

  • Path :建议统一为 绝对路径 ,如 /module/page/detail/action/share/service/user;支持动态段,如 /detail/:id
  • Query/Params:键值对,字符串为主;复杂对象可序列化为 JSON 或由各端约定类型(如 extra)。
  • 路由类型与执行方式
    • 页面跳转push(压栈)、replace(替换当前)、present(模态),对应打开完整页面。
    • 功能唤醒getService(获取服务实例)、invokeAction(执行动作/能力)、openModal(打开弹窗)、openOverlay(打开浮层),不必然改变导航栈或打开整页。

三、核心接口定义(平台无关)

以下用伪代码 + 各端示例描述,便于在多端实现时对齐语义。

3.1 路由表与路由项

text 复制代码
RouteItem:
  path: string              // 如 "/page/detail"、"/action/share"、"/service/user"
  pattern?: string           // 如 "/page/detail/:id" 用于匹配与参数提取
  type: "page" | "service" | "action" | "modal"   // 页面跳转 / 服务获取 / 功能动作 / 弹窗浮层
  target: PlatformTarget     // 由各端适配层解析为页面、服务工厂、Action 回调、弹窗 Builder 等
  defaultParams?: Map<string, string>
  • page:页面跳转,适配层执行 openPage / replacePage / present。
  • service:功能唤醒之服务获取,适配层执行 resolveService,返回实例。
  • action:功能唤醒之动作执行,适配层执行 invokeAction(如分享、埋点、业务逻辑),无返回值或返回结果。
  • modal:功能唤醒之弹窗/浮层,适配层执行 openModal / openOverlay,不压主栈。

iOS(Swift)示例target 可存闭包 () -> UIViewController() -> Any(服务)、或 ([String: String]) -> Void(Action)。
Android(Kotlin)示例target 可为 Class<*>(Context, Map) -> Intent、或 (Context, Map) -> Any(服务/动作)。
Flutter(Dart)示例target 可为 Widget Function(RouteParams)、或 Future<T> Function(RouteParams)(服务/动作)。

3.2 路由表接口

text 复制代码
IRouteTable:
  register(item: RouteItem): void
  unregister(path: string): void
  merge(items: RouteItem[]): void   // 动态下发合并
  lookup(path: string, params?: Map): RouteResult?   // 返回匹配的 RouteItem + 解析后的 params

RouteResult{ item: RouteItem, params: Map<string, string>, navigateMode: "push"|"replace"|"present" }

RouteContext (拦截器与适配器共用):{ path: string, params: Map, result: RouteResult, platformContext: unknown },便于拦截器修改 params 或决定是否中断。

3.3 拦截器接口

text 复制代码
IRouteInterceptor:
  order: number              // 越小越先执行
  process(context: RouteContext): boolean | Promise<boolean>
  onInterrupt?(context: RouteContext): void

RouteContext :包含 path, params, routeResult, platformContext(各端的 Context/Context/BuildContext 等)。

process 返回 false 或 reject,则不再执行后续拦截器与目标,并调用 onInterrupt

3.4 门面接口(Router)

text 复制代码
IRouter:
  // 页面跳转
  navigate(path: string, params?: Map, options?: NavigateOptions): Promise<boolean>
  replace(path: string, params?: Map): Promise<boolean>
  present(path: string, params?: Map): Promise<boolean>
  // 功能唤醒
  getService<T>(path: string, params?: Map): T | null        // 服务获取
  invokeAction(path: string, params?: Map): Promise<unknown> // 动作执行,可返回结果
  openModal(path: string, params?: Map): Promise<boolean>    // 弹窗/浮层
  handleOpenURL(url: string | Uri): boolean   // 深链接入口,解析后按路由类型分发

NavigateOptions{ mode: "push"|"replace"|"present", animated?: boolean }
功能唤醒 与页面跳转共用同一路由表;查表后根据 RouteItem.type 分发到 getService / invokeAction / openModal 或 navigate。


四、各端适配层设计

4.1 适配器接口(平台无关抽象)

text 复制代码
IPlatformRouterAdapter:
  // 页面跳转
  openPage(result: RouteResult, platformContext: unknown): void
  replacePage(result: RouteResult, platformContext: unknown): void
  presentPage(result: RouteResult, platformContext: unknown): void
  // 功能唤醒
  resolveService(result: RouteResult, platformContext: unknown): unknown | null
  invokeAction(result: RouteResult, platformContext: unknown): Promise<unknown>
  openModal(result: RouteResult, platformContext: unknown): void   // 弹窗/浮层
}

核心层只持有 IPlatformRouterAdapter,在「查找 + 拦截通过」后根据 RouteItem.type 调用对应方法:page → openPage/replacePage/presentPage;service → resolveService;action → invokeAction;modal → openModal。

功能唤醒与页面跳转统一 :同一 path 协议、同一路由表、同一拦截器链;仅根据 RouteItem.type 在适配层走不同分支(打开页面 vs 获取服务 vs 执行动作 vs 打开弹窗),便于运营链路上「一个 path 既可跳转页也可唤醒能力」。

4.2 iOS 适配层要点(Swift)

  • openPage :从 RouteResult.item.target 得到 ViewController 类型或工厂闭包,创建 VC,取 platformContext 为当前 top VC,执行 navigationController?.pushViewController(vc)show(vc)
  • replacePagesetViewControllersreplaceViewController
  • presentPagepresent(vc, animated: true)
  • resolveService:若 target 为协议类型,从容器或模块内获取实现并返回。
  • 深链接 :在 AppDelegate/SceneDelegate 中收到 URL 后,解析为 path + query,调用 Router.shared.handleOpenURL(url)

4.3 Android 适配层要点(Kotlin)

  • openPageRouteResult 中 target 为 Class<Activity> 或 Intent 工厂;startActivity(Intent(context, target).apply { putExtras(...) })
  • replacePagefinish() 当前再 startActivity,或使用 Single Task / 自定义栈。
  • presentPage :可对应 startActivityFLAG_ACTIVITY_NEW_TASK 或 Dialog 风格 Activity。
  • resolveService:通过路由 path 映射到接口实现类,从模块或 DI 容器获取实例。
  • 深链接 :在 MainActivity 的 onNewIntent/onCreate 中取 intent.data,解析为 path + query,调用 Router.handleOpenURL(uri)

4.4 Flutter 适配层要点(Dart)

  • openPage :将 RouteResult.path 与 params 拼成 go_router 的 location,调用 context.go(location)context.push(location);若使用自定义 Navigator 2.0,则更新 state 的 pages 并 notifyListeners。
  • replacePagecontext.go 或替换栈顶。
  • presentPagecontext.push 或使用 showDialog/命名路由的 modal 语义。
  • resolveService:path 映射到 GetIt/Provider 或模块内注册的工厂,返回实例。
  • 深链接 :在 app_linksgetInitialLink/uriLinkStream 中解析 Uri,转为 path + query,调用 Router.handleOpenURL(uri)

4.5 其他平台适配层要点摘要

平台 适配层要点
HarmonyOS Want.uri → path/params;router.pushUrl;Ability 与路由表映射。
MacOS 同 iOS(VC/Window 栈);NSWindow、NSViewController。
WinOS 协议/启动参数 → path/params;Frame.Navigate 或主窗口导航。
WebApp path = location.pathname,query = searchParams;History.pushState/replaceState;Vue Router / React Router。
ReactNative Linking 收 URL → path/params;React Navigation 的 linking 与 navigate。
WatchOS 简化 path 表;与 iPhone 同步或本地 WKInterfaceController 栈。

五、navigate 完整流程时序图

从调用 Router.navigate(path) 到适配器执行打开页面,各层协作顺序如下。

sequenceDiagram participant B as 业务/深链接 participant R as Router participant T as RouteTable participant C as InterceptorChain participant A as Adapter participant P as 目标页 B->>R: navigate(path, params) R->>R: parse(path, params) R->>T: lookup(path, params) T-->>R: RouteResult | null alt result 为 null R-->>B: false end R->>C: process(context) loop 拦截器 C->>C: process alt 拦截 C-->>B: onInterrupt end end C-->>R: continue R->>A: openPage(result) | replacePage(result) A->>P: 打开页面 A-->>R: 完成 R-->>B: true

六、数据流与职责划分(泳道图)

flowchart LR subgraph 调用方 A[navigate / handleOpenURL] end subgraph 核心 B[解析 path/query] C[RouteTable.lookup] D[InterceptorChain] E[按 type 分发] end subgraph 平台 F[页面: openPage/replace/present] G[功能唤醒: getService/invokeAction/openModal] end A --> B --> C --> D --> E --> F E --> G

七、路由表来源与动态合并(流程图)

flowchart TB subgraph 来源 S1[静态注册 各端 register] S2[编译期生成 如 APT] S3[服务端下发 JSON] end subgraph 合并 M[IRouteTable.merge] end subgraph 查找 L[lookup path] end S1 --> M S2 --> M S3 --> M M --> L
  • 各端启动时:先加载静态/编译期表,再可选拉取服务端表并 merge(含版本/灰度),最后所有 navigate 均走同一 lookup

八、与深链接、组件化、声明式的衔接

  • 深链接 :外部 URL(Scheme 或 Universal Link/App Link)进入 App 后,统一解析为 path + query ,再调用 Router.navigate(path, params)handleOpenURL,与 App 内跳转共用同一路由表与拦截器。
  • 组件化:各模块只依赖「Router + path 协议」,不依赖具体页面类;路由表可由各模块在初始化时 register,或通过编译期生成 + SPI 按需加载。
  • 声明式:在 Flutter 侧,适配层可基于 go_router 或自定义 RouterDelegate,由「状态 → pages」驱动;在 iOS/Android 侧,可用「目标栈状态」驱动一次 setViewControllers / 重建 Fragment 栈,与通用 Router 的「navigate/replace」语义对齐。
  • 同体系跨端协同 :同一产品在多端(iOS、Android、Web、电脑、手表等)共用同一 path 协议 与路由语义;各端实现各自的 Adapter,但对同一 path 的业务目标一致。这样可实现:一条链接在 Web 打开为 Web 页、在 App 打开为 App 页;手表与手机通过 path 同步实现接力;「在电脑上继续」等跨端续传依赖同一 path+query。设计时需保证路由表/动态配置在体系内统一或按端态下发,path 命名空间与类型(页面/功能唤醒)在体系内一致。

九、目录与模块建议(跨端可对照)

便于多端实现时对齐,建议目录结构(按端拆分实现,接口保持一致):

text 复制代码
router_core/           # 各端可抽成接口/协议层,或共用文档
  - types: RouteItem, RouteResult, RouteContext, NavigateOptions
  - IRouteTable, IRouteInterceptor, IRouter, IPlatformRouterAdapter
router_impl/           # 各端实现
  - RouteTableImpl
  - InterceptorChain
  - Router (门面,持有 Table + Chain + Adapter)
router_adapter_ios/
router_adapter_android/
router_adapter_harmonyos/
router_adapter_flutter/
router_adapter_macos/
router_adapter_winos/
router_adapter_web/
router_adapter_reactnative/
router_adapter_watchos/
router_plugin_deeplink/   # 深链接注入与 handleOpenURL
router_plugin_dynamic/   # 动态表拉取与 merge

十、小结

  • 通用路由管理组件 通过 统一 path/query、IRouteTable、IRouteInterceptor、IRouter、IPlatformRouterAdapter 抽象,实现「协议统一、多端适配、可扩展」。
  • 同时支持页面跳转路由 (openPage/replacePage/presentPage)与功能唤醒路由 (getService、invokeAction、openModal),同一路由表内用 RouteItem.type(page / service / action / modal)区分,深链接与运营链可共用一个 path 既跳页也唤能力。
  • 各端在适配层实现页面跳转与功能唤醒的对应 API 及深链接注入,核心层只做解析、查表、拦截与按类型分发。
  • 路由表可来自静态注册、编译期生成与动态下发,通过 merge 统一入口,便于与 02~06 所述方案无缝集成。

十一、核心类示范实现(伪代码)

便于各端实现时对齐行为,以下给出 RouteTableImplInterceptorChainRouter 的骨干逻辑。

csharp 复制代码
类 RouteTableImpl 实现 IRouteTable:
  _exact: Map<string, RouteItem>      // 精确 path
  _patterns: List<{ pattern: string, item: RouteItem }>   // 带 :id 等

  方法 register(item):
    若 item.pattern 含动态段,追加到 _patterns;否则 _exact[item.path] = item

  方法 lookup(path, params):
    若 _exact[path] 存在,返回 (item, params)
    遍历 _patterns,若匹配则返回 (item, mergedParams)
    返回 null

  方法 merge(items):
    对 items 中每条,register(item)  // 动态下发合并,后注册可覆盖
css 复制代码
类 InterceptorChain:
  _list: List<IRouteInterceptor>

  方法 add(interceptor): _list.append(interceptor)
  方法 process(context):
    对 _list 按 order 排序后遍历:
      若 !interceptor.process(context): interceptor.onInterrupt(context); 返回 false
    返回 true
lua 复制代码
类 Router 实现 IRouter:
  依赖: IRouteTable table, InterceptorChain chain, IPlatformRouterAdapter adapter

  方法 navigate(path, params, options):
    result = table.lookup(path, params)
    若 result == null: 返回 false
    context = RouteContext(path, params, result, platformContext)
    若 !chain.process(context): 返回 false
    根据 options.mode 与 result.type 调用 adapter.openPage / replacePage / resolveService
    返回 true

  方法 handleOpenURL(url):
    (path, params) = parseURL(url)
    返回 navigate(path, params)

十二、各端统一调用示例(同一语义)

以下三端均使用相同语义:path、params、navigate 方式;仅底层由各端适配器实现。

12.1 iOS(Swift)业务侧

swift 复制代码
// 注册(在模块初始化时)
Router.shared.register(path: "/page/detail") { params in
    DetailViewController(itemId: params["id"] ?? "")
}

// 跳转(与 Android / Flutter 语义一致)
Router.shared.navigate(path: "/page/detail", params: ["id": "123"])
Router.shared.replace(path: "/page/list")
Router.shared.handleOpenURL(URL(string: "myapp://page/detail?id=123")!)

12.2 Android(Kotlin)业务侧

kotlin 复制代码
// 注册
Router.register(RouteItem(path = "/page/detail", target = DetailActivity::class.java))

// 跳转
Router.navigate(context, "/page/detail", params = mapOf("id" to "123"))
Router.replace(context, "/page/list")
Router.handleOpenURL(context, Uri.parse("myapp://page/detail?id=123"))

12.3 Flutter(Dart)业务侧

dart 复制代码
// 注册(在 go_router 或自定义 RouteTable 中)
routeTable.register('/page/detail', (params) => DetailPage(id: params['id']!));

// 跳转
Router.navigate(context, '/page/detail', params: {'id': '123'});
Router.replace(context, '/page/list');
Router.handleOpenURL(Uri.parse('myapp://page/detail?id=123'));

上述三端均通过同一 path 与 params 规范 接入深链接与动态下发的路由表,实现「一次配置、多端一致」的通用路由管理组件。HarmonyOSMacOSWinOSWebAppReactNativeWatchOS 的适配层实现同一套 navigate(path, params) / handleOpenURL 语义,仅底层调用各平台导航 API,见 08-软件体系与多平台路由对照


参考文献

  • 《01-软件平台路由规则设计-总纲》全文.
  • 02~06 专题文档(URL Scheme、Universal Links、组件化路由、声明式路由、超级 App 路由体系).
相关推荐
没有故事的Zhang同学6 小时前
02-Debug调试@网络-Wireshark网络抓包工具:从原理到实践
程序员
SimonKing6 小时前
GitHub 10万星的OpenCode,正在悄悄改变我们的工作流
java·后端·程序员
xiezhr7 小时前
36岁程序员被曝复工当晚猝死出租屋内
程序员·996·程序员日常·猝死·加班
xiezhr7 小时前
米哈游36岁程序员被曝复工当晚猝死出租屋内
游戏·程序员·游戏开发
codetown1 天前
2026年Zig编程语言权威指南:从系统级底层架构到现代软件工程实践
后端·程序员
修己xj2 天前
三月,我只想做好这四件事
程序员
不要秃头啊2 天前
别再谈提效了:AI 时代的开发范式本质变了
前端·后端·程序员