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

Flutter如何在App加载前完成SharedPreferences初始化 避免Instance of Future提示

问题原因
  • 你直接在build的三元表达式中返回异步方法createSharedObject(),该方法返回的是Future对象,未等待执行完成就转为字符串显示,就会出现Instance of Future提示。
  • 你在main函数、MyApp的build方法中手动创建_MyHomePageState实例调用初始化方法是无效的,手动创建的State和页面实际挂载的State不是同一个实例,初始化的sp对象不会同步到页面的State中。
修复方案

步骤1:在main函数提前完成sp初始化

Flutter支持main方法异步,直接在启动app前等待sp初始化完成:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // 等待sp初始化完成再启动app
  final SharedPreferences sp = await SharedPreferences.getInstance();
  runApp(MyApp(sp: sp));
}

注意SharedPreferences.getInstance()是全局单例,初始化一次之后后续所有调用返回的都是同一个实例

步骤2:逐层透传sp实例到使用页面

修改MyApp接收初始化好的sp,再传递给首页:

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: MyHomePage(sp: sp),
    );
  }
}

步骤3:改造首页代码,删除多余的初始化逻辑

class MyHomePage extends StatefulWidget {
  final SharedPreferences sp;
  const MyHomePage({super.key, required this.sp});

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String? baslik, mesaj;
  List<String> kaydedilenNotlar = [];
  List<String> kaydedilenBasliklar = [];
  late SharedPreferences sharedPreferences;

  @override
  void initState() {
    super.initState();
    // 直接取透传过来的实例,无需再异步初始化
    sharedPreferences = widget.sp;
    // 可以直接读取本地存储的数据
    kaydedilenNotlar = sharedPreferences.getStringList("not") ?? [];
    kaydedilenBasliklar = sharedPreferences.getStringList("baslik") ?? [];
  }

  // 原有createSharedObject方法可以直接删除

步骤4:修改build中的展示逻辑

删除build中调用异步初始化方法的代码,直接读取sp内容:

body: TabBarView(
  children: [
    Center(child: Text("${kaydedilenNotlar}")),
    Center(child: Text("2. sayfa")),
    Center(child: Text("3. sayfa")),
  ],
),
补充优化建议
  • 点击保存按钮调用setStringList之后,调用setState((){})刷新页面,新保存的内容就会实时更新。
  • 如果项目页面较多,不想逐层传递sp实例,可以使用get_it等依赖注入工具将sp注册为全局单例,使用时直接获取即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 11:00:05