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

Flutter调用Navigator.pop弹出页面报'!_debugLocked': is not true错误

报错原因

!_debugLocked': is not true是Flutter路由框架的保护性断言,触发条件非常明确:当Navigator路由栈正处于事务处理阶段(入栈、出栈、路由动画执行、组件构建过程中),有新的路由操作被调用,此时路由栈的调试锁未释放,直接抛出断言阻断流程。

对应到当前场景,触发报错的两个核心原因:

  • BlocListener的listener回调触发时机不与帧周期绑定:如果状态变更恰好发生在Widget树构建流程中,listener会在build阶段同步执行,而Flutter明确禁止在build过程中操作路由,直接触发锁断言。
  • 调用FlushbarHelper.createSuccess().show(context)时,Flushbar本质是通过Navigator.push插入一个Overlay路由,该入栈操作是异步调度执行的。在同步调用栈中紧接着执行Navigator.pop(context),会出现Flushbar入栈事务未完成就触发出栈操作的情况,两个路由事务冲突触发报错。

之前尝试的两种方案无效的原因:

  • addPostFrameCallback仅保证等待当前帧绘制完成,但Flushbar入栈会自行调度新帧执行路由动画和栈更新,单帧结束后入栈事务大概率还未完成,依然会撞锁。
  • 固定500ms延迟属于硬编码的不可靠方案:低端设备上Flushbar入栈动画耗时可能超过500ms,依然会触发报错;高端设备上用户会平白多等半秒,体验很差,且给出的示例代码中Future.delayed缺少末尾闭合括号,本身存在语法错误无法正常执行。
解决方案

方案1:拆分路由逻辑(推荐,无兼容性问题)

把成功提示的展示逻辑从创建标签页迁移到标签列表页,从根源避免路由操作冲突,这也是Flutter跨页通信的标准实践:

  1. 创建标签页的BlocListener中,创建成功后仅触发列表刷新、执行页面返回操作,通过返回值传递成功状态:
BlocListener<CreateLabelCubit, CreateLabelState>(
  listener: (context, state) {
    if (state.networkState == NetworkState.success) {
      // 刷新标签列表数据
      labelListBloc.add(LabelListFetched());
      // 关闭当前创建页,返回成功标识给上一页
      Navigator.pop(context, true);
    } else if (state.networkState == NetworkState.failure) {
      // 失败提示不需要触发页面退出,无路由冲突,可直接展示
      FlushbarHelper.createError(message: state.toString()).show(context);
    }
  },
  // 其余组件配置保持不变
)
  1. 标签列表页跳转创建标签页时,等待页面返回结果,收到成功标识后再展示成功提示:
// 标签列表页跳转创建页的逻辑
final createResult = await Navigator.push<bool>(
  context,
  MaterialPageRoute(builder: (_) => const CreateLabelPage()),
);
if (createResult == true && context.mounted) {
  FlushbarHelper.createSuccess(message: 'Create Label Successful!').show(context);
}

该方案完全符合Flutter路由设计规范,pop页面和展示提示的路由操作在不同上下文执行,不存在任何锁冲突,不需要依赖帧回调或延迟,稳定性最高。

方案2:同页展示提示的兼容写法

如果不想调整跨页逻辑,就确保pop操作在所有路由事务、构建流程完全结束后执行,替代不可靠的单帧等待和长延迟:

BlocListener<CreateLabelCubit, CreateLabelState>(
  listener: (context, state) {
    if (state.networkState == NetworkState.success) {
      labelListBloc.add(LabelListFetched());
      FlushbarHelper.createSuccess(message: 'Create Label Successful!').show(context);
      
      // 等待当前帧绘制完成+Flushbar入栈调度完成再执行pop
      WidgetsBinding.instance.addPostFrameCallback((_) async {
        // 100ms足够覆盖Flushbar的入栈调度耗时,远短于500ms,体验更好
        await Future.delayed(const Duration(milliseconds: 100));
        // 增加挂载和栈顶判断,避免重复pop
        if (context.mounted && ModalRoute.of(context)?.isCurrent == true) {
          Navigator.pop(context);
        }
      });
    } else if (state.networkState == NetworkState.failure) {
      FlushbarHelper.createError(message: state.toString()).show(context);
    }
  },
  // 其余组件配置保持不变
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 13:33:24