Flutter之路由监听器

RouteListenerManager 路由监听管理器

概述

RouteListenerManager 是一个用于管理Flutter应用路由监听器的单例类,它提供了统一的路由事件监听和通知机制。该管理器配合 GlobalRouteObserver 类,能够全局监听应用的路由变化,包括路由跳转、返回、替换和移除等操作。

核心特性

  • 单例模式:确保全局只有一个路由监听管理器实例

  • 多种路由事件监听:支持路由跳转、返回、替换、移除四种事件类型

  • 异常处理:监听器执行过程中的异常不会影响其他监听器

  • 全局路由观察 :通过 GlobalRouteObserver 自动捕获所有路由变化

  • 灵活管理:支持动态添加、移除监听器

类结构

RouteListenerManager

单例实现
dart 复制代码
static final RouteListenerManager _instance = RouteListenerManager._internal();

factory RouteListenerManager() => _instance;

static RouteListenerManager get instance => _instance;

RouteListenerManager._internal();
监听器存储
  • _pushListeners: 路由跳转监听器列表

  • _popListeners: 路由返回监听器列表

  • _replaceListeners: 路由替换监听器列表

  • _removeListeners: 路由移除监听器列表

API 文档

监听器管理方法

添加监听器
addPushListener
dart 复制代码
void addPushListener(Function(String route) listener)
  • 功能:添加路由跳转监听器

  • 参数listener - 接收路由名称的回调函数

  • 用途:当发生路由跳转时触发

addPopListener
dart 复制代码
void addPopListener(Function(String route) listener)
  • 功能:添加路由返回监听器

  • 参数listener - 接收路由名称的回调函数

  • 用途:当发生路由返回时触发

addReplaceListener
dart 复制代码
void addReplaceListener(Function(String newRoute, String oldRoute) listener)
  • 功能:添加路由替换监听器

  • 参数listener - 接收新路由名称和旧路由名称的回调函数

  • 用途:当发生路由替换时触发

addRemoveListener
dart 复制代码
void addRemoveListener(Function(String route) listener)
  • 功能:添加路由移除监听器

  • 参数listener - 接收路由名称的回调函数

  • 用途:当发生路由移除时触发

移除监听器
removePushListener
dart 复制代码
void removePushListener(Function(String route) listener)
  • 功能:移除指定的路由跳转监听器
removePopListener
dart 复制代码
void removePopListener(Function(String route) listener)
  • 功能:移除指定的路由返回监听器
removeReplaceListener
dart 复制代码
void removeReplaceListener(Function(String newRoute, String oldRoute) listener)
  • 功能:移除指定的路由替换监听器
removeRemoveListener
dart 复制代码
void removeRemoveListener(Function(String route) listener)
  • 功能:移除指定的路由移除监听器
removeAllListener
dart 复制代码
void removeAllListener()
  • 功能:移除所有类型的监听器

  • 用途:清理所有监听器,通常在应用退出时调用

通知方法
notifyPush
dart 复制代码
void notifyPush(String route)
  • 功能:通知所有路由跳转监听器

  • 异常处理:单个监听器异常不会影响其他监听器执行

notifyPop
dart 复制代码
void notifyPop(String route)
  • 功能:通知所有路由返回监听器

  • 异常处理:单个监听器异常不会影响其他监听器执行

notifyReplace
dart 复制代码
void notifyReplace(String newRoute, String oldRoute)
  • 功能:通知所有路由替换监听器

  • 异常处理:单个监听器异常不会影响其他监听器执行

notifyRemove
dart 复制代码
void notifyRemove(String route)
  • 功能:通知所有路由移除监听器

  • 异常处理:单个监听器异常不会影响其他监听器执行

GlobalRouteObserver

类定义
dart 复制代码
class GlobalRouteObserver extends NavigatorObserver
重写方法
didPush
dart 复制代码
void didPush(Route<dynamic> route, Route<dynamic>? previousRoute)
  • 功能:监听路由跳转事件

  • 实现 :提取路由名称并调用 RouteListenerManager().notifyPush()

  • 日志:输出路由跳转信息

didPop
dart 复制代码
void didPop(Route<dynamic> route, Route<dynamic>? previousRoute)
  • 功能:监听路由返回事件

  • 实现 :提取路由名称并调用 RouteListenerManager().notifyPop()

  • 日志:输出路由返回信息

didReplace
dart 复制代码
void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute})
  • 功能:监听路由替换事件

  • 实现 :提取新旧路由名称并调用 RouteListenerManager().notifyReplace()

  • 日志:输出路由替换信息

  • 安全检查:确保新旧路由都不为空

didRemove
dart 复制代码
void didRemove(Route<dynamic> route, Route<dynamic>? previousRoute)
  • 功能:监听路由移除事件

  • 实现 :提取路由名称并调用 RouteListenerManager().notifyRemove()

  • 日志:输出路由移除信息

使用示例

1. 基本使用

dart 复制代码
// 获取管理器实例

final routeManager = RouteListenerManager.instance;

  


// 添加路由跳转监听器

routeManager.addPushListener((String route) {

  print('路由跳转到: $route');

  // 执行自定义逻辑,如埋点统计、页面预加载等

});

  


// 添加路由返回监听器

routeManager.addPopListener((String route) {

  print('从路由返回: $route');

  // 执行自定义逻辑,如清理资源、保存状态等

});

  


// 添加路由替换监听器

routeManager.addReplaceListener((String newRoute, String oldRoute) {

  print('路由替换: $oldRoute -> $newRoute');

  // 执行自定义逻辑

});

2. 在MaterialApp中注册全局观察者

dart 复制代码
class MyApp extends StatelessWidget {

  @override

  Widget build(BuildContext context) {

    return MaterialApp(

      navigatorObservers: [

        GlobalRouteObserver(), // 注册全局路由观察者

      ],

      // 其他配置...

    );

  }

}

3. 动态管理监听器

dart 复制代码
class MyPage extends StatefulWidget {

  @override

  _MyPageState createState() => _MyPageState();

}

  


class _MyPageState extends State<MyPage> {

  late Function(String) routeListener;

  


  @override

  void initState() {

    super.initState();

    

    // 创建监听器

    routeListener = (String route) {

      print('页面 $route 被访问');

    };

    

    // 添加监听器

    RouteListenerManager.instance.addPushListener(routeListener);

  }

  


  @override

  void dispose() {

    // 移除监听器,避免内存泄漏

    RouteListenerManager.instance.removePushListener(routeListener);

    super.dispose();

  }

}

4. 清理所有监听器

dart 复制代码
// 在应用退出时清理所有监听器

void cleanup() {

  RouteListenerManager.instance.removeAllListener();

}

设计模式

单例模式

  • 确保全局只有一个 RouteListenerManager 实例

  • 通过私有构造函数和静态实例实现

  • 提供工厂构造函数和静态getter两种访问方式

观察者模式

  • RouteListenerManager 作为主题(Subject)

  • 各种监听器作为观察者(Observer)

  • 当路由事件发生时,自动通知所有注册的观察者

策略模式

  • 不同类型的路由事件使用不同的处理策略

  • 通过函数回调实现灵活的事件处理逻辑

异常处理

所有通知方法都包含异常处理机制:

dart 复制代码
void notifyPush(String route) {

  for (final listener in _pushListeners) {

    try {

      listener(route);

    } catch (e) {

      debugPrint('Route push listener error: $e');

    }

  }

}
  • 单个监听器的异常不会影响其他监听器的执行

  • 异常信息会通过 debugPrint 输出到控制台

  • 确保系统的稳定性和可靠性

注意事项

  1. 内存管理:及时移除不再需要的监听器,避免内存泄漏

  2. 异常处理:监听器函数应该处理可能的异常情况

  3. 性能考虑:避免在监听器中执行耗时操作

  4. 线程安全:当前实现不是线程安全的,如需多线程访问请添加同步机制

  5. 路由名称:确保路由有明确的名称,避免使用 'unknown' 作为路由名称

扩展建议

  1. 添加路由参数传递:支持传递路由参数给监听器

  2. 添加条件监听:支持基于条件的监听器注册

  3. 添加优先级机制:支持监听器的优先级排序

  4. 添加异步支持:支持异步监听器函数

  5. 添加统计功能:添加路由访问统计和分析功能

总结

RouteListenerManager 提供了一个强大而灵活的路由监听机制,通过单例模式和观察者模式的结合,实现了全局路由事件的统一管理。该设计具有良好的扩展性和维护性,能够满足大多数Flutter应用的路由监听需求。

相关推荐
QQ1__8115175155 小时前
Spring boot名城小区物业管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·vue.js·spring boot
钛态5 小时前
前端微前端架构:大项目的救命稻草还是自找麻烦?
前端·vue·react·web
一粒黑子5 小时前
【实战解析】阿里开源 PageAgent:纯前端 GUI Agent,一行JS让网页支持自然语言操控
前端·javascript·开源
独角鲸网络安全实验室6 小时前
2026微信小程序抓包全解析:从实操落地到合规风控,解锁前端调试新范式
前端·微信小程序·小程序·抓包·系统代理绕过·https证书严格校验·进程隔离
紫微AI6 小时前
前端文本测量成了卡死一切创新的最后瓶颈,pretext实现突破了
前端·人工智能·typescript
GISer_Jing6 小时前
AI前端(From豆包)
前端·aigc·ai编程
IT枫斗者6 小时前
前端部署后如何判断“页面是不是最新”?一套可落地的版本检测方案(适配 Vite/Vue/React/任意 SPA)
前端·javascript·vue.js·react.js·架构·bug
测试修炼手册6 小时前
[测试技术] 深入理解 JSON Web Token (JWT)
前端·json
AI老李6 小时前
2026 年 Web 前端开发的 8 个趋势!
前端
里欧跑得慢6 小时前
15. Web可访问性最佳实践:让每个用户都能平等访问
前端·css·flutter·web