You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

应用恢复后从二级路由返回时如何触发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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 12:12:57