升级Bloc到v8.0.0后Bloc Observer无法输出日志问题排查
问题原因分析
核心问题出在BlocOverrides.runZoned的使用逻辑错误:
- Bloc v8.0.0版本开始引入
BlocOverrides实现zone级别的Bloc配置隔离,blocObserver的配置仅在runZoned的回调函数作用域内生效 - 你当前代码中
BlocOverrides.runZoned的回调为空,你的runApp调用以及后续所有Bloc/Cubit实例的创建逻辑都在该作用域之外,因此Observer无法捕获到任何Bloc相关的生命周期、事件、状态变化回调
解决方案
提供两种可选用法,根据你的业务场景选择即可:
方案1:将业务启动逻辑移入runZoned回调
适合需要针对不同zone配置不同BlocObserver的场景,修正后的main函数代码如下:
void main() async { WidgetsFlutterBinding.ensureInitialized(); HttpOverrides.global = MyHttpOverrides(); await Hive.initFlutter(); Hive.registerAdapter(UserAdapter()); await Hive.openBox<User>('user'); await Firebase.initializeApp(); BlocOverrides.runZoned( // 把原本写在runZoned外的runApp移入此处 () => runApp(const MyApp()), blocObserver: SimpleBlocObserver(), ); }
方案2:全局配置BlocObserver
如果你不需要分区配置Observer,可以直接全局赋值,无需使用BlocOverrides.runZoned,代码更简洁:
void main() async { WidgetsFlutterBinding.ensureInitialized(); // 全局注册自定义BlocObserver Bloc.observer = SimpleBlocObserver(); HttpOverrides.global = MyHttpOverrides(); await Hive.initFlutter(); Hive.registerAdapter(UserAdapter()); await Hive.openBox<User>('user'); await Firebase.initializeApp(); runApp(const MyApp()); }
注意事项
- 不要在Observer生效的作用域外提前实例化Bloc/Cubit,否则这些实例的所有行为都不会被监听
- 如果使用了GetIt、Provider等依赖注入框架,请确保Bloc/Cubit的实例化逻辑在Observer生效之后触发,或者将依赖注册逻辑也移入
runZoned回调内
内容的提问来源于stack exchange,提问作者biniyam112
相关产品推荐
相关产品推荐

