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配合加载占位页实现:
- 替换Provider定义:
FutureProvider<MySharedPreferences?>( create: (_) => MySharedPreferences.create(), initialData: null, )
- 修改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
相关产品推荐
相关产品推荐

