在 Flutter 项目中,本地存储通常可以分为几类:
第一类是轻量 Key-Value 存储,例如 shared_preferences、get_storage、mmkv,适合保存开关、配置、登录状态等简单数据。
第二类是安全存储,例如 flutter_secure_storage,适合保存 token、refresh token、密钥等敏感信息。
第三类是轻量 NoSQL / 本地数据库,例如 hive_ce、sembast、objectbox、drift,适合保存列表、缓存、结构化数据、离线数据等。
本文主要介绍 Flutter 项目中常见、好用、相对轻量的本地存储方案,并给出选择建议。
一、先给结论:怎么选?
| 场景 | 推荐方案 |
|---|---|
| 保存主题、语言、开关、引导页状态 | shared_preferences |
| 保存简单 JSON、页面缓存、非敏感配置 | get_storage / shared_preferences |
| 保存 token、refresh token、用户凭证 | flutter_secure_storage |
| 保存 Flutter Web / 多端简单本地数据 | shared_preferences / hive_ce / sembast |
| 保存对象列表、离线缓存、草稿箱 | hive_ce / sembast |
| 保存复杂查询、关系型数据 | drift |
| 追求高性能对象数据库、数据量较大 | objectbox |
| 移动端高性能 Key-Value | mmkv |
一句话总结:
简单配置用 shared_preferences,敏感数据用 flutter_secure_storage,对象缓存用 hive_ce,复杂关系数据用 drift,高性能本地数据库用 objectbox。
二、shared_preferences
1. 简介
shared_preferences 是 Flutter 官方维护的轻量 Key-Value 存储插件,主要用于保存简单配置数据。它底层会包装 Android 的 SharedPreferences、iOS 的 NSUserDefaults 等平台能力。官方文档中也提到,从 2.3.0 开始提供了新的 SharedPreferencesAsync 和 SharedPreferencesWithCache API,旧的 SharedPreferences API 未来会被废弃,新项目更推荐使用新版 API。
2. 适合存什么?
适合:
- 是否第一次打开 App
- 主题模式
- 语言设置
- 用户是否同意隐私协议
- 某些功能开关
- 上次选择的 tab
- 简单的用户偏好
不适合:
- token 等敏感信息
- 大量列表数据
- 复杂对象关系
- 高频读写数据
- 强一致性业务数据
3. 安装
dependencies:shared_preferences:^latest4. 推荐用法:SharedPreferencesAsync
import'package:shared_preferences/shared_preferences.dart';classAppPrefs{finalSharedPreferencesAsync_prefs=SharedPreferencesAsync();Future<void>setDarkMode(bool value)async{await_prefs.setBool('dark_mode',value);}Future<bool>getDarkMode()async{returnawait_prefs.getBool('dark_mode')??false;}Future<void>setLanguage(Stringvalue)async{await_prefs.setString('language',value);}Future<String>getLanguage()async{returnawait_prefs.getString('language')??'zh_CN';}}5. 优点
- 官方维护
- 接入简单
- 多平台支持好
- 适合轻量配置
- 学习成本低
6. 缺点
- 不适合大量数据
- 不适合敏感信息
- 不适合复杂查询
- 旧 API 未来会逐步被替代
三、flutter_secure_storage
1. 简介
flutter_secure_storage 是 Flutter 中常用的安全存储插件,用于保存敏感数据。它会使用平台级安全能力,例如 iOS Keychain、Android 加密存储等。官方介绍中也说明它用于以 Key-Value 形式安全存储敏感数据,并支持 Android、iOS、macOS、Windows、Linux 等平台。
2. 适合存什么?
适合:
- access token
- refresh token
- 登录凭证
- 用户密钥
- 设备绑定信息
- 加密盐值
- 敏感配置
不适合:
- 大量列表数据
- 普通业务缓存
- 图片、文件、大 JSON
- 高频大量读写
3. 安装
dependencies:flutter_secure_storage:^latest4. 基础用法
import'package:flutter_secure_storage/flutter_secure_storage.dart';classTokenStorage{staticconst_storage=FlutterSecureStorage();Future<void>saveToken(Stringtoken)async{await_storage.write(key:'access_token',value:token);}Future<String?>getToken()async{returnawait_storage.read(key:'access_token');}Future<void>clearToken()async{await_storage.delete(key:'access_token');}}5. 优点
- 安全性高
- 适合保存 token
- API 简单
- 支持多平台
6. 缺点
- 性能不如普通 Key-Value 存储
- 不适合大量数据
- 不同平台行为可能略有差异
- 需要关注备份、卸载、系统迁移等边界情况
7. 实战建议
实际项目中不要把所有用户数据都放进 flutter_secure_storage。
推荐方式:
- token / refresh token -> flutter_secure_storage
- 主题 / 语言 / 普通配置 -> shared_preferences
- 用户资料缓存 / 页面缓存 -> hive_ce / sembast
四、get_storage
1. 简介
get_storage 是一个非常轻量、同步读写的 Key-Value 存储库。它会先把数据放在内存中,每次操作后再备份到磁盘。官方文档中描述它是一个快速、超轻量、同步的内存 Key-Value 存储,并支持 String、int、double、Map、List 等类型。
它常见于 GetX 项目,但不代表只能在 GetX 中使用。
2. 适合存什么?
适合:
- 简单配置
- 页面状态缓存
- 轻量 JSON
- 临时偏好设置
- 非敏感用户信息
不适合:
- token
- 大量数据
- 复杂查询
- 高可靠业务数据
3. 安装
dependencies:get_storage:^latest4. 使用示例
import'package:get_storage/get_storage.dart';Future<void>main()async{awaitGetStorage.init();finalbox=GetStorage();box.write('theme','dark');finaltheme=box.read<String>('theme');box.remove('theme');}封装一下:
classLocalCache{finalGetStorage_box=GetStorage();voidsaveUserName(Stringname){_box.write('user_name',name);}StringgetUserName(){return_box.read<String>('user_name')??'';}voidclear(){_box.erase();}}5. 优点
- 非常简单
- 同步 API,使用方便
- 读写速度快
- 适合小型项目
- 适合 GetX 项目
6. 缺点
- 不是官方方案
- 不适合敏感数据
- 不适合大规模数据
- 复杂数据维护能力较弱
五、MMKV
1. 简介
mmkv 是腾讯微信团队开源的高性能 Key-Value 存储方案。Flutter 的 mmkv 包介绍中提到,它是一个高效、小巧、易用的移动端 Key-Value 存储框架,目前主要支持 Android 和 iOS。
2. 适合存什么?
适合:
- 高频读取的简单配置
- 移动端缓存
- 启动阶段需要快速读取的数据
- 性能敏感的 Key-Value 数据
不适合:
- Flutter Web 项目
- 桌面端优先项目
- 复杂对象关系
- 强 SQL 查询需求
3. 特点
- 性能优秀
- 移动端表现好
- 适合替代部分 SharedPreferences 场景
- 底层能力成熟
4. 注意点
mmkv 更偏移动端,虽然包生态中有一些平台实现,但如果你的项目非常重视 Flutter Web、Windows、macOS、Linux 的统一体验,需要谨慎选择。
六、hive_ce
1. 简介
过去很多 Flutter 项目会使用 Hive。现在更推荐关注 hive_ce,它是 Hive 的社区延续版本。hive_ce 官方介绍中提到,它是一个轻量、快速的 Key-Value 数据库,使用纯 Dart 编写;变更记录也说明 2.3.0 是 Hive Community Edition 的首次发布,并支持 Flutter Web WASM 编译。
2. 适合存什么?
适合:
- 对象缓存
- 离线列表
- 搜索历史
- 草稿箱
- 用户资料缓存
- 简单业务数据
- 接口响应缓存
不适合:
- 复杂 SQL 关系查询
- 强事务关系模型
- 超复杂数据分析
3. 安装
dependencies:hive_ce:^latesthive_ce_flutter:^latestdev_dependencies:build_runner:^latesthive_ce_generator:^latest4. 基础用法
import'package:hive_ce_flutter/hive_flutter.dart';Future<void>main()async{awaitHive.initFlutter();finalbox=awaitHive.openBox('app_cache');awaitbox.put('name','Zender');finalname=box.get('name');awaitbox.delete('name');}5. 保存对象示例
classUserCache{finalBoxbox;UserCache(this.box);Future<void>saveUser(Map<String,dynamic>user)async{awaitbox.put('user',user);}Map<String,dynamic>?getUser(){finalvalue=box.get('user');if(valueisMap){returnMap<String,dynamic>.from(value);}returnnull;}}6. 优点
- 轻量
- 速度快
- 纯 Dart
- 适合缓存对象
- API 简单
- 比 shared_preferences 更适合存结构化数据
7. 缺点
- 复杂查询能力有限
- 对象模型变更需要注意兼容
- 不适合强关系型数据
七、sembast
1. 简介
sembast 是一个纯 Dart 的 NoSQL 文档型本地数据库。官方介绍中提到,它适用于 Dart VM 和 Flutter,不需要插件,支持 Android、iOS、macOS、Linux、Windows 等平台;数据库以单文件形式存在,数据会在打开时加载到内存,变更会追加写入文件。
2. 适合存什么?
适合:
- 本地文档数据
- 列表缓存
- 离线数据
- 简单查询
- 多平台 Flutter 应用
不适合:
- 超大规模数据
- 复杂 SQL join
- 极致性能场景
- 强类型对象数据库场景
3. 安装
dependencies:sembast:^latestpath_provider:^latestpath:^latest4. 使用示例
import'package:path/path.dart';import'package:path_provider/path_provider.dart';import'package:sembast/sembast_io.dart';classSembastDb{lateDatabasedb;finalstore=intMapStoreFactory.store('users');Future<void>init()async{finaldir=awaitgetApplicationDocumentsDirectory();finaldbPath=join(dir.path,'app.db');db=awaitdatabaseFactoryIo.openDatabase(dbPath);}Future<int>insertUser(Map<String,dynamic>user)async{returnawaitstore.add(db,user);}Future<List<RecordSnapshot<int,Map<String,dynamic>>>>getUsers()async{returnawaitstore.find(db);}}5. 优点
- 纯 Dart
- 跨平台好
- 文档模型灵活
- 适合保存 JSON 类数据
- 支持简单查询
6. 缺点
- 数据量很大时不一定合适
- 类型约束没有 Drift/ObjectBox 强
- 复杂业务模型维护成本会上升
八、drift
1. 简介
drift 是 Flutter/Dart 中非常成熟的响应式 SQLite 封装库,适合关系型数据、本地复杂查询、离线业务数据。官方介绍中提到,Drift 是一个用于 Dart 和 Flutter 应用存储关系型数据的响应式库;drift_flutter 则提供 Flutter 项目中更方便的数据库初始化能力。
2. 适合存什么?
适合:
- 本地订单
- 聊天记录
- 离线任务
- 复杂列表筛选
- 多表关系
- 分页查询
- 本地搜索
- 需要 SQL 能力的数据
不适合:
- 只保存一个主题色
- 只保存一个 token
- 极简单配置
- 不想引入代码生成的小项目
3. 安装
dependencies:drift:^latestdrift_flutter:^latestdev_dependencies:drift_dev:^latestbuild_runner:^latest4. 表定义示例
import'package:drift/drift.dart';classTodosextendsTable{IntColumngetid=>integer().autoIncrement()();TextColumngettitle=>text()();BoolColumngetdone=>boolean().withDefault(constConstant(false))();DateTimeColumngetcreatedAt=>dateTime()();}5. 适合中大型项目
如果你的 Flutter App 有比较明显的业务数据,例如:
- 本地草稿
- 消息列表
- 收藏列表
- 下载记录
- 订单记录
- 离线表单
- 多条件筛选
这类场景用 drift 会比 shared_preferences、get_storage 更可靠。
6. 优点
- 基于 SQLite
- 关系型数据能力强
- 支持响应式查询
- 适合复杂业务
- 生态成熟
7. 缺点
- 接入成本高于 Key-Value
- 需要表结构设计
- 通常需要代码生成
- 小项目可能显得偏重
九、objectbox
1. 简介
objectbox 是一个高性能对象数据库。官方介绍中提到,ObjectBox Flutter 数据库适合跨平台和 AI 驱动应用,并支持向量搜索、相似度搜索、设备端 AI 等能力。
它适合需要较高性能、本地对象持久化、较多数据读写的 App。
2. 适合存什么?
适合:
- 大量对象数据
- 离线业务数据
- 高性能本地缓存
- 本地搜索
- AI / RAG / 向量检索相关数据
- IoT / 边缘设备数据
不适合:
- 只保存少量配置
- 只保存 token
- 非常简单的小项目
- 对包体积极其敏感的场景
3. 优点
- 性能强
- 对象模型友好
- 适合大量本地数据
- 支持高级能力,例如向量搜索
4. 缺点
- 接入复杂度高于 Hive/Sembast
- 需要生成代码
- 概念比 Key-Value 存储多
- 小项目可能没必要
十、localstorage
1. 简介
localstorage 是一个简单的本地存储库,风格类似前端的 localStorage。官方说明中特别提醒,它不适合存储大量数据或敏感数据。
2. 适合场景
适合:
- Demo 项目
- 小工具
- 简单页面状态
- 少量本地缓存
不适合:
- 生产级复杂业务
- 敏感数据
- 大量数据
- 复杂查询
3. 使用建议
如果是正式项目,我更推荐优先选择:
- shared_preferences
- flutter_secure_storage
- hive_ce
- sembast
- drift
localstorage 更适合非常简单的场景。
十一、核心对比表
| 方案 | 类型 | 是否适合敏感数据 | 是否适合复杂查询 | 数据量 | 推荐指数 |
|---|---|---|---|---|---|
| shared_preferences | Key-Value | 否 | 否 | 小 | ★★★★★ |
| flutter_secure_storage | 安全 Key-Value | 是 | 否 | 小 | ★★★★★ |
| get_storage | Key-Value | 否 | 否 | 小 | ★★★★ |
| mmkv | 高性能 Key-Value | 一般 | 否 | 小到中 | ★★★★ |
| hive_ce | NoSQL / KV 数据库 | 可自行加密 | 一般 | 中 | ★★★★★ |
| sembast | NoSQL 文档数据库 | 可自行加密 | 一般 | 中 | ★★★★ |
| drift | SQLite ORM | 否 | 是 | 中到大 | ★★★★★ |
| objectbox | 对象数据库 | 否 | 强 | 中到大 | ★★★★ |
| localstorage | 简单本地存储 | 否 | 否 | 小 | ★★★ |
十二、按业务场景选择
1. 保存 App 配置
例如:
- 主题模式
- 语言
- 是否首次打开
- 是否开启通知
- 是否显示某个弹窗
推荐:shared_preferences
理由:
官方维护、简单稳定、配置型数据非常适合
2. 保存登录 token
推荐:flutter_secure_storage
不要用:
shared_preferences、get_storage、hive、普通文件
原因:
token 属于敏感数据,应该使用系统安全存储能力。
推荐封装:
classAuthStorage{staticconst_storage=FlutterSecureStorage();staticconst_accessTokenKey='access_token';staticconst_refreshTokenKey='refresh_token';Future<void>saveTokens({requiredStringaccessToken,requiredStringrefreshToken,})async{await_storage.write(key:_accessTokenKey,value:accessToken);await_storage.write(key:_refreshTokenKey,value:refreshToken);}Future<String?>getAccessToken(){return_storage.read(key:_accessTokenKey);}Future<String?>getRefreshToken(){return_storage.read(key:_refreshTokenKey);}Future<void>clear()async{await_storage.delete(key:_accessTokenKey);await_storage.delete(key:_refreshTokenKey);}}3. 保存用户信息缓存
例如:
- 昵称
- 头像
- 会员状态
- 用户偏好
- 上次接口返回的用户资料
推荐:hive_ce、sembast
如果只是极少字段,也可以用:shared_preferences
4. 保存列表缓存
例如:
- 首页 feed 流
- 搜索历史
- 收藏列表
- 最近使用
- 草稿箱
推荐:hive_ce、sembast
如果需要多条件筛选和分页查询:drift
5. 保存复杂离线业务数据
例如:
- 订单
- 聊天记录
- 离线任务
- 下载记录
- 本地表单
- 多表关联数据
推荐:drift、objectbox
选择建议:
- 偏 SQL、关系型、多表查询:drift
- 偏对象模型、高性能、对象持久化:objectbox
6. 保存 AI / 向量搜索相关本地数据
推荐:objectbox
原因:
ObjectBox 官方已经强调其在设备端 AI、RAG、相似度搜索、向量搜索等方向的能力。
十三、Flutter 项目中的推荐组合
小型项目
组合:shared_preferences + flutter_secure_storage
适合:
- 工具类 App
- 个人项目
- 简单业务
- 无复杂离线数据
示例:
- 主题、语言 -> shared_preferences
- token -> flutter_secure_storage
中型项目
组合:shared_preferences + flutter_secure_storage + hive_ce
适合:
- 有登录
- 有接口缓存
- 有用户资料
- 有列表缓存
- 有草稿数据
示例:
- 主题、语言 -> shared_preferences
- token -> flutter_secure_storage
- 用户资料、首页缓存、草稿 -> hive_ce
中大型项目
组合:shared_preferences + flutter_secure_storage + drift
适合:
- 复杂业务 App
- 有离线能力
- 有本地多表数据
- 有分页查询
- 有搜索和筛选
示例:
- 基础配置 -> shared_preferences
- 登录凭证 -> flutter_secure_storage
- 订单、聊天、收藏、任务 -> drift
高性能本地对象存储项目
组合:shared_preferences + flutter_secure_storage + objectbox
适合:
- 数据量较大
- 高频读写
- 对象模型复杂
- 端侧 AI / 向量检索
- 离线优先应用
十四、不要滥用本地存储
很多项目容易犯一个错误:什么都往本地存。
本地存储应该遵循几个原则:
- 能不存就不存
- 敏感数据加密存
- 缓存数据要有过期策略
- 用户退出登录要清理用户级缓存
- 不同用户的数据要隔离
- 重要业务数据要考虑同步和冲突
例如接口缓存建议加上时间戳:
classCacheData{finalMap<String,dynamic>data;finalint cacheTime;CacheData({requiredthis.data,requiredthis.cacheTime,});boolgetisExpired{finalnow=DateTime.now().millisecondsSinceEpoch;returnnow-cacheTime>10*60*1000;}}十五、推荐封装思路
不要在业务代码里到处直接调用存储库。
不推荐:
finalprefs=SharedPreferencesAsync();awaitprefs.setString('token',token);推荐:
先定义统一 Key 管理:
classStorageKeys{staticconstthemeMode='theme_mode';staticconstlanguage='language';staticconstaccessToken='access_token';staticconstuserInfo='user_info';}然后封装成服务:
classAppStorage{finalSharedPreferencesAsync_prefs=SharedPreferencesAsync();Future<void>setThemeMode(Stringvalue){return_prefs.setString(StorageKeys.themeMode,value);}Future<String>getThemeMode()async{returnawait_prefs.getString(StorageKeys.themeMode)??'system';}Future<void>setLanguage(Stringvalue){return_prefs.setString(StorageKeys.language,value);}Future<String>getLanguage()async{returnawait_prefs.getString(StorageKeys.language)??'zh_CN';}}如果项目使用 Riverpod,可以这样注入:
finalappStorageProvider=Provider<AppStorage>((ref){returnAppStorage();});使用:
finalstorage=ref.read(appStorageProvider);awaitstorage.setThemeMode('dark');这样做的好处是:
- 统一管理 key
- 方便替换存储方案
- 方便单元测试
- 业务代码更干净
- 避免 key 到处散落
十六、最终推荐
如果是普通 Flutter 项目,我建议这样选:
- 简单配置:shared_preferences
- 敏感数据:flutter_secure_storage
- 对象缓存:hive_ce
- 文档型缓存:sembast
- 复杂关系数据:drift
- 高性能对象数据库:objectbox
最通用的组合是:
shared_preferences + flutter_secure_storage + hive_ce
如果项目有复杂离线业务,升级为:
shared_preferences + flutter_secure_storage + drift
如果项目对本地性能要求很高,或者需要端侧 AI / 向量能力,可以考虑:
shared_preferences + flutter_secure_storage + objectbox
总体来说,不存在一个存储库适合所有场景。Flutter 本地存储的最佳实践不是“选最强的”,而是“按数据类型分层存储”。简单配置、敏感信息、业务缓存、复杂离线数据应该分别选择不同的存储方案。