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

Flutter中如何正确初始化SharedPreferences 2.0.15版本?

正确初始化SharedPreferences的几种方案

你的代码里用late修饰了_preferences,但initState中调用的getLocalData是异步操作,不会等待初始化完成就继续执行后续逻辑。如果在_preferences还没拿到实例的时候就切换页面并尝试读取值,必然会触发未初始化的错误。

下面是几种靠谱的解决方式:

方案一:用FutureBuilder绑定初始化与UI渲染

通过FutureBuilder等待SharedPreferences实例获取完成后,再渲染页面并使用它,避免提前访问未初始化的变量:

late SharedPreferences _preferences;

@override
Widget build(BuildContext context) {
  return FutureBuilder(
    future: SharedPreferences.getInstance(),
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.done) {
        if (snapshot.hasError) {
          return Text('初始化失败: ${snapshot.error}');
        }
        _preferences = snapshot.data!;
        // 这里写你的页面UI逻辑
        return Scaffold(
          appBar: AppBar(title: const Text('我的页面')),
          body: Center(
            child: Text('存储的值: ${_preferences.getString('user_name')}'),
          ),
        );
      }
      // 初始化过程中显示加载状态
      return const Center(child: CircularProgressIndicator());
    },
  );
}

方案二:全局提前初始化(推荐)

在main函数里先完成SharedPreferences的初始化,再启动App,这样所有页面都能直接使用已准备好的实例,不用每次都异步等待:

void main() async {
  // 必须先调用这个,确保Flutter核心绑定初始化完成
  WidgetsFlutterBinding.ensureInitialized();
  // 全局初始化SharedPreferences
  final prefs = await SharedPreferences.getInstance();
  runApp(MyApp(prefs: prefs));
}

class MyApp extends StatelessWidget {
  final SharedPreferences prefs;

  const MyApp({super.key, required this.prefs});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(prefs: prefs),
    );
  }
}

// 页面直接接收已初始化的实例
class HomePage extends StatelessWidget {
  final SharedPreferences prefs;

  const HomePage({super.key, required this.prefs});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('首页')),
      body: Center(
        child: Text('存储的用户ID: ${prefs.getString('user_id')}'),
      ),
    );
  }
}

方案三:用状态标记控制初始化完成后再操作

在页面中添加一个初始化完成的标记,确保只有初始化完成后才执行页面跳转或取值操作:

late SharedPreferences _preferences;
bool _isInitDone = false;

@override
void initState() {
  super.initState();
  _initPrefs();
}

Future<void> _initPrefs() async {
  _preferences = await SharedPreferences.getInstance();
  setState(() {
    _isInitDone = true;
  });
}

@override
Widget build(BuildContext context) {
  if (!_isInitDone) {
    return const Center(child: CircularProgressIndicator());
  }
  // 初始化完成后渲染页面
  return Scaffold(
    appBar: AppBar(title: const Text('首页')),
    body: ElevatedButton(
      onPressed: () {
        // 跳转时直接把已初始化的实例传给下一页
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => SecondPage(prefs: _preferences),
          ),
        );
      },
      child: const Text('跳转到详情页'),
    ),
  );
}

// 详情页直接使用传入的实例
class SecondPage extends StatelessWidget {
  final SharedPreferences prefs;

  const SecondPage({super.key, required this.prefs});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('详情页')),
      body: Center(
        child: Text('获取到的偏好值: ${prefs.getString('theme_mode')}'),
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 18:55:12