Flutter中Injectable+Get_it集成SharedPreferences报错及解决方法
这个报错我之前也遇到过!核心问题是SharedPreferences.getInstance()是异步操作,但你同步获取LoginCheckBloc时,它依赖的SharedPref所需要的SharedPreferences实例还没完成初始化。Injectable处理异步依赖需要特殊配置,下面是完整的解决步骤:
1. 标记异步依赖为预解析
修改你的InjectableModule,给SharedPreferences的getter添加@preResolve注解,告诉Injectable在初始化阶段先等待这个异步操作完成:
@module abstract class InjectableModule { @preResolve // 新增这个注解 @lazySingleton Future<SharedPreferences> get prefs => SharedPreferences.getInstance(); }
2. 异步初始化GetIt依赖
在main函数中,需要异步等待所有预解析的依赖完成初始化,再启动App:
void main() async { // 必须确保Flutter绑定先初始化 WidgetsFlutterBinding.ensureInitialized(); // 异步等待依赖配置完成(Injectable生成的代码会处理@preResolve的依赖) await configureDependencies(); runApp(MyApp()); }
注意:当你使用
@preResolve后,Injectable生成的configureDependencies()会变成异步函数,所以必须用await等待它完成。
3. 保持SharedPref与LoginCheckBloc的代码不变
你的SharedPref和LoginCheckBloc的依赖注入逻辑是正确的,不需要修改:
@LazySingleton() class SharedPref { final String _token = 'token'; final SharedPreferences _pref; SharedPref(this._pref); Future<String> getToken() async { return _pref.getString(_token) ?? ''; } Future<void> setToken(String token) async { await _pref.setString(_token, token); } }
@injectable class LoginCheckBloc extends Bloc<LoginCheckEvent, LoginCheckState> { final SharedPref sharedPref; LoginCheckBloc({@required this.sharedPref}) : super(const LoginCheckState.initial()); @override Stream<LoginCheckState> mapEventToState(LoginCheckEvent event) async* { if (event is CheckLogin) { final String token = await sharedPref.getToken(); yield token.isEmpty ? const LoginCheckState.notLogin() : const LoginCheckState.successLogin(); } } }
4. 正常获取LoginCheckBloc实例
现在所有异步依赖都已经在初始化阶段完成了,你原来的获取方式就不会再报错:
BlocProvider<LoginCheckBloc>( create: (BuildContext context) => getIt<LoginCheckBloc>()..add(CheckLogin()), )
额外说明
@preResolve的作用是让Injectable在初始化GetIt时,优先等待被标记的异步依赖完成,将结果存入GetIt容器。这样后续获取依赖时,拿到的就是已经就绪的实例,而不是未完成的Future。如果有多个异步依赖,都可以用@preResolve标记,configureDependencies()会自动等待所有它们完成。
内容的提问来源于stack exchange,提问作者ali hoseinpoor
相关产品推荐
相关产品推荐

