本地存储
Flutter 应用经常需要在本地保存数据,如用户偏好设置、登录状态、缓存数据等。
SharedPreferences — 键值对存储
SharedPreferences 是最常用的轻量级本地存储方案,适合保存简单的键值对数据。
安装
bash
flutter pub add shared_preferences基本用法
dart
import 'package:shared_preferences/shared_preferences.dart';
// 获取实例
final prefs = await SharedPreferences.getInstance();
// 写入数据
await prefs.setString('username', '张三');
await prefs.setInt('age', 25);
await prefs.setBool('isLoggedIn', true);
await prefs.setDouble('score', 98.5);
await prefs.setStringList('tags', ['flutter', 'dart']);
// 读取数据
final username = prefs.getString('username'); // '张三' 或 null
final age = prefs.getInt('age'); // 25 或 null
final isLoggedIn = prefs.getBool('isLoggedIn') ?? false; // 带默认值
// 删除数据
await prefs.remove('username');
// 清空所有数据
await prefs.clear();
// 检查 key 是否存在
final hasKey = prefs.containsKey('username');封装 StorageService
dart
class StorageService {
static StorageService? _instance;
late SharedPreferences _prefs;
static Future<StorageService> get instance async {
_instance ??= StorageService._();
await _instance!._init();
return _instance!;
}
StorageService._();
Future<void> _init() async {
_prefs = await SharedPreferences.getInstance();
}
// Token
String? getToken() => _prefs.getString('token');
Future<void> setToken(String token) => _prefs.setString('token', token);
Future<void> removeToken() => _prefs.remove('token');
// 登录状态
bool get isLoggedIn => getToken() != null;
// 主题模式
String? getThemeMode() => _prefs.getString('theme_mode');
Future<void> setThemeMode(String mode) => _prefs.setString('theme_mode', mode);
// 退出登录
Future<void> logout() async {
await removeToken();
}
}使用:
dart
final storage = await StorageService.instance;
if (storage.isLoggedIn) {
// 跳转首页
}
await storage.setToken('xxx');SharedPreferences 适用场景
| 适合 | 不适合 |
|---|---|
| 用户设置(主题、语言) | 大量结构化数据 |
| 登录 Token | 需要查询的数据 |
| 简单标志位 | 频繁更新的数据 |
| 少量缓存 | 敏感数据(密码等) |
文件读写
当需要存储较大数据(如图片、JSON 文件)时,使用文件读写。
安装
bash
flutter pub add path_provider获取目录
dart
import 'package:path_provider/path_provider.dart';
// 应用专属临时目录(可能被系统清除)
final tempDir = await getTemporaryDirectory();
// 应用专属文档目录(不会被清除)
final docDir = await getApplicationDocumentsDirectory();
// 外部存储目录(Android)
final externalDir = await getExternalStorageDirectory();读写文件
dart
import 'dart:io';
// 写入文件
Future<void> writeFile(String fileName, String content) async {
final dir = await getApplicationDocumentsDirectory();
final file = File('${dir.path}/$fileName');
await file.writeAsString(content);
}
// 读取文件
Future<String?> readFile(String fileName) async {
final dir = await getApplicationDocumentsDirectory();
final file = File('${dir.path}/$fileName');
if (await file.exists()) {
return await file.readAsString();
}
return null;
}
// 删除文件
Future<void> deleteFile(String fileName) async {
final dir = await getApplicationDocumentsDirectory();
final file = File('${dir.path}/$fileName');
if (await file.exists()) {
await file.delete();
}
}读写 JSON 文件
dart
import 'dart:convert';
// 写入
Future<void> saveData(String key, Map<String, dynamic> data) async {
final dir = await getApplicationDocumentsDirectory();
final file = File('${dir.path}/$key.json');
await file.writeAsString(jsonEncode(data));
}
// 读取
Future<Map<String, dynamic>?> loadData(String key) async {
final dir = await getApplicationDocumentsDirectory();
final file = File('${dir.path}/$key.json');
if (await file.exists()) {
final content = await file.readAsString();
return jsonDecode(content) as Map<String, dynamic>;
}
return null;
}数据库简介
对于需要复杂查询的大量结构化数据,使用数据库更合适。
sqflite
bash
flutter pub add sqflitesqflite 是最常用的 SQLite 数据库包,适合存储需要查询和关联的数据。
drift (原 moor)
bash
flutter pub add drift
flutter pub add drift_flutterdrift 是基于 SQLite 的高级 ORM 框架,支持类型安全的查询、代码生成等。
建议
- 简单键值对 → SharedPreferences
- 中等数据 / 文件缓存 → 文件读写
- 大量结构化数据 → sqflite / drift
本地存储方案对比
| 方案 | 适用场景 | 复杂度 | 查询能力 |
|---|---|---|---|
| SharedPreferences | 简单键值对 | ⭐ | 无 |
| 文件读写 | 大块数据、缓存 | ⭐⭐ | 无 |
| sqflite | 结构化数据、查询 | ⭐⭐⭐ | SQL |
| drift | 类型安全的数据库 | ⭐⭐⭐⭐ | ORM |
