You need to enable JavaScript to run this app. Flutter启动时通过Provider使用SharedPreferences未初始化报错如何解决
优惠活动
大模型
产品
解决方案
定价
更多

Flutter启动时通过Provider使用SharedPreferences未初始化报错如何解决

修复方案

你遇到的问题本质是MySharedPreferences内部的prefs实例是异步初始化的,Provider同步创建实例后直接调用read方法时,异步初始化逻辑还没执行完,prefs仍为null。

推荐优先使用提前初始化方案,该方案不会出现启动加载闪屏,适配你启动阶段就要读取配置的场景:

具体修改步骤

步骤1:修改main函数,提前初始化SharedPreferences

void main() async {
  // runApp前执行异步操作必须加这行,确保Flutter框架绑定初始化完成
  WidgetsFlutterBinding.ensureInitialized();
  // 提前完成SharedPreferences初始化
  final sharedPrefs = await SharedPreferences.getInstance();
  // 把已经初始化完成的实例传入你的封装类
  final myPrefs = MySharedPreferences(initPrefs: sharedPrefs);
  runApp(MyApp(myPrefs: myPrefs));
}

步骤2:修改MyApp类接收预初始化的配置实例

class MyApp extends StatelessWidget {
  final MySharedPreferences myPrefs;
  const MyApp({super.key, required this.myPrefs});

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        // 直接传入已经初始化完成的实例,无需异步生成
        Provider<MySharedPreferences>.value(value: myPrefs),
        Provider<User>(create: (_) => User.create()),
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        theme: MyStyle.getThemeData(),
        title: 'TestApp',
        home: PgSelectStartup(),
      ),
    );
  }
}

步骤3:修改MySharedPreferences新增构造方法

修改my_shared_preferences.dart,新增直接接收已初始化实例的构造:

class MySharedPreferences {
  final SharedPreferences prefs;
  // 新增构造,直接接收初始化完成的prefs实例
  MySharedPreferences({required SharedPreferences initPrefs}) : prefs = initPrefs;

  // 原有create方法可保留用于其他非启动场景调用
  static Future<MySharedPreferences> create() async {
    final prefs = await SharedPreferences.getInstance();
    return MySharedPreferences(initPrefs: prefs);
  }

  String? read(String key) {
    return prefs.getString(key);
  }
}

可选方案:不修改main函数的降级实现

如果确实不想在main函数提前初始化,可以改用FutureProvider配合加载占位页实现:

  1. 替换Provider定义:
FutureProvider<MySharedPreferences?>(
  create: (_) => MySharedPreferences.create(),
  initialData: null,
)
  1. 修改PgSelectStartup逻辑:
class PgSelectStartup extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final myPrefs = context.watch<MySharedPreferences?>();
    // 初始化未完成时展示加载占位页
    if (myPrefs == null) {
      return const Scaffold(body: Center(child: CircularProgressIndicator()));
    }
    return myPrefs.read("login") == null ? PgStartupNew() : PgStartupLogin();
  }
}

内容的提问来源于stack exchange,提问作者sosnus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 23:42:04