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

如何在返回首页时持续发送Cubit状态?解决emit异常

问题分析与解决方案

错误原因

  1. Timer泄漏导致Cubit关闭后仍触发emit:你的OfficeCubit启动了每秒执行的Timer.periodic,但未在Cubit被close时取消该定时任务。当Cubit因页面销毁/重建被关闭后,Timer仍会持续尝试发送状态,触发Bad state: Cannot emit new states after calling close异常。
  2. BlocProvider作用域错误:你在页面的build方法内创建BlocProvider,导致页面重建或切换时,Cubit会被重复实例化或销毁,既无法实现跨页面状态传递,也会加剧Timer泄漏问题。

修复步骤

1. 给OfficeCubit添加销毁逻辑,取消Timer

修改OfficeCubit代码,重写close方法,在Cubit销毁时停止定时任务:

class OfficeCubit extends Cubit<OfficeStates> {
  OfficeCubit():super(firstState(master,room1,room2,hall1,hall2)){
    pup();
  }
  String? _now;
  Timer? _everySecond;

  static OfficeCubit get(context)=>BlocProvider.of(context);

  void pup () {
    s.prepareMqttClient();
    _now=DateTime.now().second.toString();

    _everySecond=Timer.periodic(Duration(seconds: 1), (Timer t)  async {
      _now = DateTime.now().second.toString();
      emit(firstState(master,room1,room2,hall1,hall2));
    });
  }

  // 重写close方法,销毁时取消Timer
  @override
  Future<void> close() {
    _everySecond?.cancel();
    return super.close();
  }
}

2. 全局挂载BlocProvider,实现跨页面状态共享

修改main.dart,将BlocProvider放在MaterialApp外层,确保整个应用共享同一个OfficeCubit实例:

Widget build(BuildContext context) {
  return BlocProvider(
    create: (context) => OfficeCubit(),
    child: MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        appBarTheme: AppBarTheme(
            elevation: 30.0,
            backgroundColor: Colors.blueGrey[900],
            toolbarHeight: 60.0,
            centerTitle: true,
            titleTextStyle: TextStyle(
              color:Colors.white70,
            )
        ),
      ),
      home: MyHomePage(),
    ),
  );
}

3. 修改页面UI代码,移除局部BlocProvider

页面内不再创建新的OfficeCubit实例,直接使用全局提供的实例:

Widget build(BuildContext context) {
  return BlocBuilder<OfficeCubit,OfficeStates>(
    builder: (BuildContext context, state){
      var cubit = OfficeCubit.get(context);
      if (state is firstState){
        return Scaffold(/* 你的页面内容 */);
      } else {
        return CircularProgressIndicator();
      }
    },
  );
}

额外注意事项

  • 确保firstState中的master、room1等变量是实时更新的,否则emit的状态无变化会导致UI不刷新。
  • 其他页面如需监听Cubit状态,直接使用BlocBuilder或BlocListener即可,无需重复创建BlocProvider。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 10:54:55