【Flutter 必备插件】数据存储 shared_preferences
shared_preferences 是 Flutter 中最常用的轻量级数据持久化解决方案,它提供了一个简单的 key-value 存储机制,适合存储用户配置、应用设置等小型数据。
基础概念
什么是 shared_preferences
shared_preferences是Flutter官方推荐的轻量级数据持久化方案,在不同的平台中,它基于不同的原生机制开发:
- iOS:使用 NSUserDefaults
- Android:使用 PreferencesDataStore
- Web:使用 localStorage
- Windows/macOS/Linux:使用本地文件存储
特点和适用场景
特点:
- 轻量级,适合存储小量数据
- 异步API,不阻塞主线程
- 支持基本数据类型
- 跨平台兼容
- 无需数据库配置
适用场景:
- 用户偏好设置
- 应用配置信息
- 主题、语言等UI配置
- 简单的缓存数据
- 用户登录状态
- 部分页面数据(首页):在获取首页列表数据时我们常常会先展示旧数据,带给用户更好的体验,不至于一打开页面就是空白的,当我们采用持久化列表数据后,可以直接先展示本地数据,当网络数据请求回来后在进行数据更新。
实战
1. 添加依赖
dependencies:
shared_preferences: ^2.5.3
2. 封装
library;
import 'package:shared_preferences/shared_preferences.dart';
class SharedPreferencesService {
late SharedPreferencesWithCache _prefs;
// 单例模式
static final SharedPreferencesService _instance = SharedPreferencesService._internal();
factory SharedPreferencesService() => _instance;
SharedPreferencesService._internal();
Future<void> init() async {
_prefs = await SharedPreferencesWithCache.create(cacheOptions: const SharedPreferencesWithCacheOptions());
}
// --- 存储方法 ---
Future<void> setString(String key, String value) async {
await _prefs.setString(key, value);
}
Future<void> setInt(String key, int value) async {
await _prefs.setInt(key, value);
}
Future<void> setDouble(String key, double value) async {
await _prefs.setDouble(key, value);
}
Future<void> setBool(String key, bool value) async {
await _prefs.setBool(key, value);
}
Future<void> setStringList(String key, List<String> value) async {
await _prefs.setStringList(key, value);
}
// --- 获取方法 ---
String? getString(String key) => _prefs.getString(key);
int? getInt(String key) => _prefs.getInt(key);
double? getDouble(String key) => _prefs.getDouble(key);
bool? getBool(String key) => _prefs.getBool(key);
List<String>? getStringList(String key) => _prefs.getStringList(key);
// --- 删除 & 清除 ---
Future<void> remove(String key) async {
await _prefs.remove(key);
}
Future<void> clearAll() async {
await _prefs.clear();
}
}
3. 使用方式(初始化+调用)
你可以在应用启动时初始化该服务:
main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final sharedPreferencesService = SharedPreferencesService();
await sharedPreferencesService.init();
runApp(const MyApp());
}
在业务中使用:
// 存储
SharedPreferencesService().setString('username', 'john_doe');
SharedPreferencesService().setBool('is_logged_in', true);
// 读取
String? username = SharedPreferencesService().getString('username');
bool? isLoggedIn = SharedPreferencesService().getBool('is_logged_in');
// 删除
SharedPreferencesService().remove('username');
// 清空所有
SharedPreferencesService().clearAll();
4. 实战案例:用于配置管理系统
import 'package:flutter/material.dart';
import 'package:shared_preferences.dart';
class AppSettings {
static const String themeKey = 'app_theme';
static const String languageKey = 'app_language';
static const String fontSizeKey = 'font_size';
// 主题设置
static Future<void> setDarkMode(bool isDark) async {
await SharedPreferencesService().setBool(themeKey, isDark);
}
static bool isDarkMode() {
return SharedPreferencesService().getBool(themeKey) ?? false;
}
// 语言设置
static Future<void> setLanguage(String languageCode) async {
await SharedPreferencesService().setString(languageKey, languageCode);
}
static String getLanguage() {
return SharedPreferencesService().getString(languageKey) ?? 'en';
}
// 字体大小设置
static Future<void> setFontSize(double size) async {
await SharedPreferencesService().setDouble(fontSizeKey, size);
}
static double getFontSize() {
return SharedPreferencesService().getDouble(fontSizeKey) ?? 14.0;
}
}
// 使用Provider进行状态管理
class AppSettingsProvider extends ChangeNotifier {
bool _isDarkMode;
String _language;
double _fontSize;
AppSettingsProvider() :
_isDarkMode = AppSettings.isDarkMode(),
_language = AppSettings.getLanguage(),
_fontSize = AppSettings.getFontSize();
bool get isDarkMode => _isDarkMode;
String get language => _language;
double get fontSize => _fontSize;
Future<void> toggleTheme() async {
_isDarkMode = !_isDarkMode;
await AppSettings.setDarkMode(_isDarkMode);
notifyListeners();
}
Future<void> updateLanguage(String newLanguage) async {
_language = newLanguage;
await AppSettings.setLanguage(newLanguage);
notifyListeners();
}
Future<void> updateFontSize(double newSize) async {
_fontSize = newSize;
await AppSettings.setFontSize(newSize);
notifyListeners();
}
}
5. 性能优化【干货】
- 批量操作
// 使用事务批量处理
Future<void> batchUpdate() async {
await Future.wait([
SharedPreferencesService().setString('key1', 'value1'),
SharedPreferencesService().setInt('key2', 123),
SharedPreferencesService().setBool('key3', true)
]);
}
- 数据序列化
import 'dart:convert';
class UserSettings {
final String theme;
final String language;
final double fontSize;
UserSettings({required this.theme, required this.language, required this.fontSize});
Map<String, dynamic> toJson() => {
'theme': theme,
'language': language,
'fontSize': fontSize,
};
factory UserSettings.fromJson(Map<String, dynamic> json) => UserSettings(
theme: json['theme'],
language: json['language'],
fontSize: json['fontSize'],
);
// 保存到SharedPreferences
Future<void> save() async {
await SharedPreferencesService().setString('user_settings', jsonEncode(toJson()));
}
// 从SharedPreferences加载
static Future<UserSettings?> load() async {
final String? jsonStr = SharedPreferencesService().getString('user_settings');
if (jsonStr == null) return null;
return UserSettings.fromJson(jsonDecode(jsonStr));
}
}
FAQ【干货】
-
数据类型限制
Q:shared_preferences只支持基本数据类型
A:使用JSON序列化存储复杂对象
-
并发访问问题
Q:多处同时写入可能造成数据不一致
A:使用单例模式和锁机制
-
存储空间限制
Q:不适合存储大量数据
A:使用数据库或文件存储大型数据
浙公网安备 33010602011771号