Flutter中get_it注入SharedPreferences报实例未就绪错误解决
问题报错
开发中使用get_it做依赖注入、flutter_bloc做状态管理时,抛出如下连锁错误:
I/flutter (23661): Error while creating WeatherInfoLocalDataSource I/flutter (23661): Error while creating WeatherInfoRepository I/flutter (23661): Error while creating GetWeatherInfoByCityName I/flutter (23661): Error while creating WeatherInfoBloc ════════ Exception caught by widgets library ═══════════════════════════════════ The following assertion was thrown building _BodyBuilder: You tried to access an instance of SharedPreferences that is not ready yet 'package:get_it/get_it_impl.dart': package:get_it/get_it_impl.dart:1 Failed assertion: line 404 pos 9: 'instanceFactory.isReady' The relevant error-causing widget was Scaffold lib\…\pages\weather_info_page.dart:25 When the exception was thrown, this was the stack ════════ Exception caught by rendering library ═════════════════════════════════ Each child must be laid out exactly once. The relevant error-causing widget was Scaffold
问题根因
代码共存在三处问题,直接触发上述报错:
- 异步依赖未等待初始化完成:
SharedPreferences通过registerSingletonAsync注册,属于异步初始化实例。原main函数调用di.init()后,没有等待所有异步实例就绪就直接启动App,导致依赖链上的本地数据源、仓储层、用例、Bloc依次初始化失败,抛出实例未就绪的断言错误;后续Scaffold构建时因为Bloc初始化异常,连带触发子组件布局次数异常的渲染错误。 - http客户端注册写法错误:注册
http.Client时遗漏构造括号,实际注入容器的是Client类的构造函数引用,而非可用的Client实例,远程数据源初始化时会拿到类型不匹配的对象。 - Bloc内的异步方法调用遗漏
await关键字,异步流程执行顺序不符合预期。
修复方案
- 修改main入口函数,等待依赖注册、所有异步实例初始化完成后再启动App:
void main() async { WidgetsFlutterBinding.ensureInitialized(); await di.init(); // 等待所有异步注册的实例就绪 await di.sl.allReady(); runApp(const MyApp()); }
- 修正依赖注入容器中
http.Client的注册代码,补全构造括号:
//! External sl.registerSingletonAsync<SharedPreferences>( () => SharedPreferences.getInstance()); // 补全构造括号,注册Client实例而非构造方法引用 sl.registerLazySingleton(() => http.Client()); sl.registerLazySingleton(() => InternetConnectionChecker());
- 排查Bloc层所有异步调用逻辑,补全遗漏的
await关键字,确保事件处理、用例/仓储调用按预期顺序执行。
内容的提问来源于stack exchange,提问作者Njordww
相关产品推荐
相关产品推荐

