应用恢复后从二级路由返回时如何触发pop回调函数?
解决GoRouter应用被杀死后返回值丢失问题
核心问题在于:应用被系统杀死后,原RouteA页面的实例已销毁,之前await push的Future无法完成,导致无法接收返回值。需要通过持久化存储或全局状态管理提前保存返回值,待RouteA重建后读取处理。
方案一:本地持久化存储返回值
使用SharedPreferences将RouteB的返回值提前保存,RouteA重建后读取并处理。
1. RouteB中保存返回值
// RouteB内选择完成后的逻辑 onTap: () async { final prefs = await SharedPreferences.getInstance(); // 将选中结果存入本地存储 await prefs.setString('route_b_result', '用户选中的内容'); GoRouter.of(context).pop(); }
2. RouteA中读取并处理结果
class RouteA extends StatefulWidget { const RouteA({super.key}); @override State<RouteA> createState() => _RouteAState(); } class _RouteAState extends State<RouteA> { @override void initState() { super.initState(); // 页面初始化时检查是否有保存的返回值 _checkSavedResult(); } Future<void> _checkSavedResult() async { final prefs = await SharedPreferences.getInstance(); final result = prefs.getString('route_b_result'); if (result != null) { // 处理返回结果 print(result); // 清除已处理的结果,避免重复触发 await prefs.remove('route_b_result'); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('RouteA')), body: Center( child: ElevatedButton( onPressed: () async { // 正常场景下仍可通过await获取返回值 final result = await GoRouter.of(context).push('/routeB'); if (result != null) { print(result); } }, child: const Text('跳转到RouteB'), ), ), ); } }
方案二:全局状态管理监听返回值
通过全局状态容器(以Riverpod为例)存储返回值,RouteA监听状态变化,即使重建也能获取结果。
1. 定义全局状态Provider
final routeBResultProvider = StateProvider<String?>((ref) => null);
2. RouteB中更新状态
// RouteB内选择完成后的逻辑 onTap: () { // 将结果存入全局状态 ref.read(routeBResultProvider.notifier).state = '用户选中的内容'; GoRouter.of(context).pop(); }
3. RouteA中监听并处理结果
class RouteA extends ConsumerStatefulWidget { const RouteA({super.key}); @override ConsumerState<RouteA> createState() => _RouteAState(); } class _RouteAState extends ConsumerState<RouteA> { @override void initState() { super.initState(); // 初始化时检查全局状态 WidgetsBinding.instance.addPostFrameCallback((_) { final result = ref.read(routeBResultProvider); if (result != null) { _handleResult(result); } }); } @override Widget build(BuildContext context) { // 监听全局状态变化 ref.listen<String?>(routeBResultProvider, (previous, next) { if (next != null && previous != next) { _handleResult(next); } }); return Scaffold( appBar: AppBar(title: const Text('RouteA')), body: Center( child: ElevatedButton( onPressed: () async { final result = await GoRouter.of(context).push('/routeB'); if (result != null) { _handleResult(result); } }, child: const Text('跳转到RouteB'), ), ), ); } void _handleResult(String result) { print(result); // 处理完成后重置状态 ref.read(routeBResultProvider.notifier).state = null; } }
补充:确保路由栈的恢复
要实现应用杀死后恢复[A, B]的路由栈,需配置GoRouter的路由信息持久化:
final _prefs = SharedPreferences.getInstance(); class AppRouter { static final GoRouter router = GoRouter( initialLocation: '/', // 恢复路由栈 restoreRouteInformation: (state) async { final prefs = await _prefs; final json = prefs.getString('route_stack'); if (json != null) { final List<Map<String, dynamic>> stack = List.castFrom(jsonDecode(json)); return RouteInformation( location: stack.last['location'], state: {'stack': stack}, ); } return null; }, // 保存路由栈 saveRouteInformation: (state) async { final prefs = await _prefs; final stack = state.routeInformationList .map((e) => {'location': e.location, 'state': e.state}) .toList(); await prefs.setString('route_stack', jsonEncode(stack)); }, routes: [ GoRoute( path: '/', builder: (context, state) => const RouteA(), ), GoRoute( path: '/routeB', builder: (context, state) => const RouteB(), ), ], ); }
内容的提问来源于stack exchange,提问作者davdog00
相关产品推荐
相关产品推荐

