升级hydrated_bloc/flutter_bloc遇__storage未初始化LateInitializationError
LateInitializationError: Field '__storage' has not been initialized after upgrading hydrated_bloc to 10 and flutter_bloc to 9
Error Stack
DartError: LateInitializationError: Field '__storage' has not been initialized. dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 307:3 throw_ errors.dart:307 packages/hydrated_bloc/src/hydrated_bloc.dart 107:22 get [__storage] hydrated_bloc.dart:107 packages/hydrated_bloc/src/hydrated_bloc.dart 154:19 onChange hydrated_bloc.dart:154 packages/bloc/src/bloc_base.dart 103:7 emit bloc_base.dart:103
My Code
initServices function
Future<void> initServices({String? env}) async { WidgetsFlutterBinding.ensureInitialized(); HydratedBloc.storage = await HydratedStorage.build( storageDirectory: kIsWeb ? HydratedStorageDirectory.web : HydratedStorageDirectory((await getTemporaryDirectory()).path), ); final from = getParams(); await EnvCubit.instance.init(from.fromBrand, env: env); }
main function
void main() async { await initServices(env: 'dev'); runApp(const MyApp()); }
Solution
hydrated_bloc 10移除了直接赋值HydratedBloc.storage的支持,必须通过HydratedBloc.initialize或HydratedBlocOverrides.runZoned方法,在所有HydratedBloc/Cubit实例创建前完成存储初始化。
Option 1: 使用HydratedBloc.initialize
修改initServices和main函数如下:
Future<void> initServices({String? env}) async { WidgetsFlutterBinding.ensureInitialized(); // 使用HydratedBloc.initialize初始化存储 await HydratedBloc.initialize( storage: () async => HydratedStorage.build( storageDirectory: kIsWeb ? HydratedStorageDirectory.web : HydratedStorageDirectory((await getTemporaryDirectory()).path), ), ); final from = getParams(); await EnvCubit.instance.init(from.fromBrand, env: env); } void main() async { await initServices(env: 'dev'); runApp(const MyApp()); }
Option 2: 用HydratedBlocOverrides.runZoned包裹初始化逻辑
如果希望将存储初始化封装在zone内:
void main() async { WidgetsFlutterBinding.ensureInitialized(); final storage = await HydratedStorage.build( storageDirectory: kIsWeb ? HydratedStorageDirectory.web : HydratedStorageDirectory((await getTemporaryDirectory()).path), ); await HydratedBlocOverrides.runZoned( () async { final from = getParams(); await EnvCubit.instance.init(from.fromBrand, env: 'dev'); runApp(const MyApp()); }, storage: storage, ); }
原因说明
hydrated_bloc 10中不再允许直接赋值静态字段HydratedBloc.storage,新的初始化方法能确保存储实例在所有HydratedBloc/Cubit尝试访问前完成设置,从而避免出现你遇到的LateInitializationError。
内容的提问来源于stack exchange,提问作者Alin1233
相关产品推荐
相关产品推荐

