You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LateInitializationError求助:sharedPreferences字段未初始化

解决LateInitializationError: Field 'sharedPreferences' has not been initialized问题

你的问题出在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 15:48:28