LateInitializationError求助:sharedPreferences字段未初始化
你的问题出在CacheHelper的实现方式上,虽然你在main中调用了init()方法,但由于sharedPreferences是静态变量,结合当前实例方法的调用方式,可能存在初始化状态未被正确识别的问题(比如热重载导致静态变量重置,或者实例化调用的方式让初始化逻辑不够可靠)。
以下是两种可行的修复方案:
方案一:使用静态方法实现
将init和saveData都改为静态方法,直接通过类名调用,避免实例化带来的不确定性:
class CacheHelper { static late final SharedPreferences sharedPreferences; // 改为静态初始化方法 static Future<void> init() async { sharedPreferences = await SharedPreferences.getInstance(); } // 改为静态存储方法 static Future<bool> saveData({required String key, required dynamic value}) async { if (value is bool) { return await sharedPreferences.setBool(key, value); } else if (value is String) { return await sharedPreferences.setString(key, value); } else if (value is int) { return await sharedPreferences.setInt(key, value); } else { return await sharedPreferences.setDouble(key, value); } } }
修改main函数的调用方式:
void main() async { WidgetsFlutterBinding.ensureInitialized(); await CacheHelper.init(); // 直接调用静态方法 runApp( const MyApp(), ); }
登录方法中调用存储方法:
Future login() async { try { emit(LoginLoading()); final response = await api.post(EndPoints.signIn, data: { ApiKey.email: signInEmail.text.isEmpty ? signUpEmail.text : signInEmail.text, ApiKey.password: signInPassword.text.isEmpty ? signUpPassword.text : signInPassword.text }); final user = LoginModel.fromJson(response); CacheHelper.saveData(key: ApiKey.accessToken, value: user.accessToken); // 直接调用静态方法 emit(LoginSuccess()); } catch (e) { emit(LoginFailure(message: e.toString())); } }
方案二:使用单例模式实现
确保CacheHelper只有一个实例,避免多次实例化可能带来的问题:
class CacheHelper { // 单例实例 static final CacheHelper _instance = CacheHelper._internal(); late final SharedPreferences sharedPreferences; // 工厂构造函数返回单例 factory CacheHelper() => _instance; // 私有构造函数 CacheHelper._internal(); Future<void> init() async { sharedPreferences = await SharedPreferences.getInstance(); } Future<bool> saveData({required String key, required dynamic value}) async { if (value is bool) { return await sharedPreferences.setBool(key, value); } else if (value is String) { return await sharedPreferences.setString(key, value); } else if (value is int) { return await sharedPreferences.setInt(key, value); } else { return await sharedPreferences.setDouble(key, value); } } }
main函数调用方式不变:
void main() async { WidgetsFlutterBinding.ensureInitialized(); await CacheHelper().init(); runApp( const MyApp(), ); }
登录方法中的调用保持不变,但此时每次调用CacheHelper()都会返回同一个实例,确保sharedPreferences已经被正确初始化:
CacheHelper().saveData(key: ApiKey.accessToken, value: user.accessToken);
这两种方案都能确保sharedPreferences在被访问前已经完成初始化,解决你遇到的LateInitializationError问题。
内容的提问来源于stack exchange,提问作者Penjel
相关产品推荐
相关产品推荐

