news 2026/5/21 2:51:01

Flutter 数据存储之 SharedPreferences 键值对存储

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flutter 数据存储之 SharedPreferences 键值对存储

目录

一、简介

二、核心概念

三、使用步骤

1. 添加依赖

2. 导入包

3. 获取实例

4. 数据操作方法

四、工程化封装

4.1 为什么要封装?

4.2 统一键值管理:SPKeys

4.3 工具类实现:SPUtils

4.4 在项目中使用

4.5 小结

五、总结


一、简介

SharedPreferencesFlutter官方提供的轻量级本地数据存储方案,适用于保存用户配置、登录状态、简单设置等键值对(Key-Value)数据。

其底层基于平台原生实现(Android 的SharedPreferences和 iOS 的NSUserDefaults),具有操作简单、读写高效的特点。

二、核心概念

特性

说明

数据类型支持

intdoubleboolStringList<String>

存储位置

自动持久化到设备本地

数据持久性

应用卸载时数据会被清除

异步操作

所有读写操作均为异步(Future

跨平台一致性

自动适配 Android/iOS/Web/桌面端

三、使用步骤

1. 添加依赖

# pubspec.yaml dependencies: # 存储键值对数据的轻量级解决方案,适用于保存用户设置、偏好等小型数据。 shared_preferences: ^2.5.4

2. 导入包

import 'package:shared_preferences/shared_preferences.dart';

3. 获取实例

final prefs = await SharedPreferences.getInstance();

4. 数据操作方法

操作类型

方法签名

示例

写入数据

setInt(String key, int value)

prefs.setInt('age', 25);

setDouble(String key, double value)

prefs.setDouble('price', 9.99);

setBool(String key, bool value)

prefs.setBool('isDark', true);

setString(String key, String value)

prefs.setString('name', 'Tom');

setStringList(String key, List<String> value)

prefs.setStringList('tags', ['a','b']);

读取数据

get(String key)/getInt()/getBool()

prefs.getInt('age') ?? 0;

删除数据

remove(String key)

prefs.remove('tempData');

清空数据

clear()

prefs.clear();

四、工程化封装

在 Flutter 开发中,shared_preferences(SP) 几乎是每个项目的标配,但在实际搬砖过程中,如果直接在业务层满大街写SharedPreferences.getInstance(),不仅代码显得臃肿,后期维护 Key 值更是一场灾难。今天分享一套我在项目中沉淀的 SP 封装方案,通过 工具类化 和 常量化,实现逻辑解耦。

4.1 为什么要封装?

很多新手喜欢在initState里异步获取 SP 实例,这种做法有两个明显的弊端:

  1. 代码重复:每个页面都要写一遍异步等待。

  2. 硬编码:prefs.getString('user_token')里的字符串一旦写错一个字母,排查起来非常头疼。

我们的目标是:全局初始化一次,到处同步调用,Key 值统一管理

4.2 统一键值管理:SPKeys

首先,新建sp_keys.dart,我们利用私有构造函数,确保 Key 值只在一个地方定义。

/// Description: 定义存储键值对的键 /// CreateDate: 2025/12/22 11:31 /// Author: agg class SPKeys { SPKeys._(); // 闭合构造函数,防止被实例化 static const String userToken = 'user_token'; static const String themeMode = 'theme_mode'; static const String userInfo = 'user_info'; }

4.3 工具类实现:SPUtils

sp_utils.dart中,我们引入late关键字,通过在应用启动时预加载,将后续的 IO 操作转化为类似同步的调用。

import 'dart:convert'; import 'package:shared_preferences/shared_preferences.dart'; /// /// Description: 存储键值对数据工具类 /// CreateDate: 2025/12/22 9:54 /// Author: agg /// class SPUtils { // 使用 late 关键字,如果未初始化就调用会直接报错,方便开发者定位 static late SharedPreferences _prefs; /// 初始化:在 main.dart 中 await SPUtils.init() static Future<void> init() async { _prefs = await SharedPreferences.getInstance(); } // ==================== 核心方法 ==================== /// 保存数据 /// 支持 String, int, double, bool, List<String> /// 以及可以通过 jsonEncode 转换的 Map 或 Object static Future<bool> set(String key, dynamic value) { if (value is String) return _prefs.setString(key, value); if (value is int) return _prefs.setInt(key, value); if (value is bool) return _prefs.setBool(key, value); if (value is double) return _prefs.setDouble(key, value); if (value is List<String>) return _prefs.setStringList(key, value); // 如果是 Map 或自定义对象,转为 json 字符串存储 return _prefs.setString(key, jsonEncode(value)); } static String getString(String key, {String defaultValue = ''}) { return _prefs.getString(key) ?? defaultValue; } static int getInt(String key, {int defaultValue = 0}) { return _prefs.getInt(key) ?? defaultValue; } static bool getBool(String key, {bool defaultValue = false}) { return _prefs.getBool(key) ?? defaultValue; } static double getDouble(String key, {double defaultValue = 0.0}) { return _prefs.getDouble(key) ?? defaultValue; } static List<String> getStringList( String key, { List<String> defaultValue = const [], }) { return _prefs.getStringList(key) ?? defaultValue; } /// 获取复杂对象 (Map 或 List) /// 读取后需手动转换类型: Map user = SPUtils.getObject('user'); static dynamic getObject(String key) { String? jsonStr = _prefs.getString(key); if (jsonStr == null || jsonStr.isEmpty) return null; try { return jsonDecode(jsonStr); } catch (e) { print("SPUtils getObject error: $e"); return null; } } // ==================== 工具方法 ==================== static bool containsKey(String key) => _prefs.containsKey(key); static Future<bool> remove(String key) => _prefs.remove(key); static Future<bool> clear() => _prefs.clear(); }

4.4 在项目中使用

  1. 入口预装载 在 main.dart 的 main 函数中,先确保 Flutter 引擎初始化,然后加载 SP。

    void main() async { // 必须调用,确保与原生层交互正常 WidgetsFlutterBinding.ensureInitialized(); // 预装载 SP,耗时极短,但收益巨大 await SPUtils.init(); runApp(const MyApp()); }
  2. 业务逻辑层调用 在任何 Widget 或 Controller 里读写数据,都不再需要 await 获取实例。

// 存储 Token SPUtils.set(SPKeys.userToken, "ey...123"); // 存储复杂的用户信息 Map<String, dynamic> user = {"name": "agg", "age": 18}; SPUtils.set(SPKeys.userInfo, user); // 获取数据 String token = SPUtils.getString(SPKeys.userToken);

4.5 小结

  • 同步化体验:虽然 SP 的原生 API 是异步的,但通过在main函数预加载实例,我们可以像操作内存变量一样操作本地持久化数据。

  • 安全提示:由于使用了late,如果在init()还没完成时就强行调用读取方法,程序会 Crash,所以务必在runApp之前完成初始化。

  • 选型建议:SP 适合存储小体量的配置信息(如登录态、主题颜色、引导页状态),如果是大批量的结构化数据,建议使用HiveSQFlite

五、总结

SharedPreferences是 Flutter 生态中最基础的持久化方案,具有上手简单、跨平台兼容的优势,适用于存储小型、非敏感的键值对数据。

官方文档:SharedPreferences API

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/20 17:19:51

Vivado使用从零实现:SPI接口控制器设计全过程

从零构建SPI主控制器&#xff1a;Vivado实战全记录 你有没有遇到过这样的场景&#xff1f;手头有个传感器&#xff0c;文档写得清清楚楚“支持SPI接口”&#xff0c;可你的FPGA板子上偏偏没有现成的IP核可用。这时候&#xff0c;是去翻Xilinx库找现成模块&#xff0c;还是自己动…

作者头像 李华
网站建设 2026/5/20 11:56:14

LangFlow Glances系统资源概览插件

LangFlow Glances 系统资源概览插件 在构建 AI 应用的今天&#xff0c;一个常见的困境是&#xff1a;我们能在画布上轻松拖出一条完美的 LLM 工作流&#xff0c;点击“运行”后却陷入等待——页面卡住、响应缓慢&#xff0c;甚至直接崩溃。日志里只留下一行冷冰冰的“Killed”&…

作者头像 李华
网站建设 2026/5/20 11:56:11

Keil5下载与ST-Link配置:项目应用快速上手

Keil5与ST-Link实战指南&#xff1a;从零搭建STM32开发环境 你有没有经历过这样的场景&#xff1f; 新买了一块STM32最小系统板&#xff0c;兴冲冲打开Keil准备烧录第一个“Hello World”程序&#xff08;比如点个LED&#xff09;&#xff0c;结果点击“Download”时弹出一串…

作者头像 李华
网站建设 2026/5/20 11:56:05

LangFlow结合语音识别打造多模态AI交互流程

LangFlow结合语音识别打造多模态AI交互流程 在智能设备越来越“能听会说”的今天&#xff0c;用户不再满足于键鼠输入的冰冷交互。想象这样一个场景&#xff1a;你走进家门&#xff0c;对着空气说一句“今天好累”&#xff0c;房间自动调暗灯光、播放舒缓音乐&#xff0c;甚至建…

作者头像 李华
网站建设 2026/5/20 12:57:16

LangFlow问答系统搭建全过程演示

LangFlow问答系统搭建全过程演示 在企业知识库日益膨胀的今天&#xff0c;员工每天要花数小时查找制度文档、重复解答相同问题。一个能秒级响应“年假怎么休”“报销流程是什么”的智能助手&#xff0c;不再是锦上添花&#xff0c;而是效率刚需。但传统开发方式需要写几十行代码…

作者头像 李华
网站建设 2026/5/20 18:00:46

SQL 基础知识总结1

SQL 基础知识总结1. SQL 是什么&#xff1f;SQL​ 是结构化查询语言&#xff0c;是用于管理和操作关系型数据库的标准语言。它可以用来&#xff1a;查询数据插入、更新、删除数据创建、修改、删除数据库对象&#xff08;如表、视图等&#xff09;管理数据库权限2. 核心概念数据…

作者头像 李华