Flutter如何在全应用中访问同一个SharedPreferences实例
完全可以在应用启动阶段一次性完成SharedPreferences实例初始化,实现全应用同步访问,彻底消除各页面重复编写FutureBuilder的冗余代码。
核心原理
SharedPreferences.getInstance()本身是轻量异步操作,仅在首次获取时会读取本地磁盘缓存,耗时极短。把初始化逻辑前置到应用入口runApp()之前执行,等实例获取完成再启动应用,后续整个应用生命周期内都可以直接同步访问该实例,不需要重复等待异步加载。
具体实现步骤
1. 启动入口前置初始化
修改应用主入口main函数,在应用启动前完成实例赋值:
import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; // 全局可访问的SharedPreferences实例,启动完成后一定已赋值 late final SharedPreferences globalPrefs; Future<void> main() async { // 初始化Flutter引擎绑定 WidgetsFlutterBinding.ensureInitialized(); // 一次性获取SharedPreferences实例 globalPrefs = await SharedPreferences.getInstance(); // 实例初始化完成后再启动应用 runApp(const MyApp()); }
这里用late final修饰是安全的:所有页面、业务逻辑的代码执行都在runApp()之后,此时globalPrefs已经完成赋值,不会出现延迟初始化错误。
2. 全应用直接同步访问
后续任意页面、任意业务逻辑中,只要导入上述全局变量所在的文件,就可以直接同步读写数据,完全不需要嵌套FutureBuilder:
// 读取深色模式配置 bool isDarkMode = globalPrefs.getBool('dark_mode') ?? false; // 写入配置(写入操作本身是异步的,不需要等待实例加载) Future<void> toggleDarkMode(bool value) async { await globalPrefs.setBool('dark_mode', value); }
可选优化:封装统一工具类
如果不想直接暴露全局变量,可以封装专门的SharedPreferences工具类,统一管理存储key、默认值逻辑,避免硬编码导致的bug:
class SpStorage { static late final SharedPreferences _instance; // 初始化方法,在main函数中调用 static Future<void> init() async { _instance = await SharedPreferences.getInstance(); } // 封装配置读写,统一处理默认值 static bool get darkMode => _instance.getBool('dark_mode') ?? false; static Future<void> setDarkMode(bool value) => _instance.setBool('dark_mode', value); static String get token => _instance.getString('access_token') ?? ''; static Future<void> setToken(String value) => _instance.setString('access_token', value); static int get fontSize => _instance.getInt('font_size') ?? 14; static Future<void> setFontSize(int size) => _instance.setInt('font_size', size); }
对应main函数中初始化逻辑替换为await SpStorage.init();即可,后续访问配置直接调用SpStorage.darkMode、SpStorage.setToken(xxx),维护成本更低。
注意事项
- 禁止把初始化逻辑放到页面生命周期(如initState)中执行,必须放在
runApp()之前的启动流程,保证全局访问时实例已就绪 - 如果项目中已经接入get_it等依赖注入框架,也可以把初始化完成的SharedPreferences实例注册为全局单例,实现效果和全局变量一致,更符合分层架构规范
- 调用
clear()方法清空所有存储数据时,不需要重新获取实例,原有实例可以继续正常使用
内容的提问来源于stack exchange,提问作者Coder
相关产品推荐
相关产品推荐

