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

Flutter中addPostFrameCallback回调未触发的推送跳转问题排查

问题根因

这是Flutter帧调度的时序问题导致的:
你使用的是可缓存最近事件的Stream(比如RxDart的BehaviorSubject),在main函数中发送的跳转事件,会在首页initState执行、刚完成stream订阅时立刻被推送过来。此时如果应用首帧已经完成绘制,后续没有新的帧调度触发(冷启动后无用户操作、无UI更新),你新增的addPostFrameCallback会一直等待下一次帧绘制才会执行,这就是切后台再切回(触发新的帧绘制)才会执行跳转的原因。

解决方案

方案1:判断当前调度阶段,决定直接执行还是注册回调

修改首页的监听逻辑,增加调度阶段判断即可解决:

@override
void initState() {
  super.initState();

  MainSingleton().notificationStream.stream.listen((redirect) {
    if (redirect == null) return;
    log("Home page found a redirect request: going to $redirect");
    
    final binding = WidgetsBinding.instance!;
    // 判断是否已经过了当前帧的回调阶段
    if (binding.schedulerPhase == SchedulerPhase.postFrameCallbacks) {
      // 直接执行跳转
      log("Directly execute redirect");
      Application.router.navigateTo(context, redirect);
      // 跳转后清空SharedPreferences缓存,避免重复跳转
      SharedPreferences.getInstance().then((sp) => sp.remove('redirect'));
    } else {
      binding.addPostFrameCallback((_) {
        log("Callback called");
        Application.router.navigateTo(context, redirect);
        SharedPreferences.getInstance().then((sp) => sp.remove('redirect'));
      });
    }
  });
}

方案2:用Future.delayed(Duration.zero)替代addPostFrameCallback

该方法也可以保证context已挂载可正常使用,不需要额外判断帧阶段:

@override
void initState() {
  super.initState();

  MainSingleton().notificationStream.stream.listen((redirect) {
    if (redirect == null) return;
    log("Home page found a redirect request: going to $redirect");
    Future.delayed(Duration.zero, () {
      log("Redirect executed");
      Application.router.navigateTo(context, redirect);
      SharedPreferences.getInstance().then((sp) => sp.remove('redirect'));
    });
  });
}

优化建议

你也可以调整逻辑时序彻底规避该问题:

  • main函数只做读取SharedPreferences、暂存路由的操作,不要提前发送到stream
  • 在首页initState的addPostFrameCallback中再读取暂存的路由信息,有有效值就直接跳转,跳转后清空缓存
    不需要依赖stream做跨阶段的事件传递,逻辑更简单也更稳定。

内容的提问来源于stack exchange,提问作者Slot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 21:54:05