Flutter本地存储完全指南
·
Flutter本地存储完全指南
引言
本地存储是移动应用开发中不可或缺的一部分,它允许应用在设备上持久化保存数据。本文将深入探讨Flutter中的各种本地存储方案和最佳实践。
一、SharedPreferences
1.1 添加依赖
dependencies:
shared_preferences: ^2.2.2
1.2 基本用法
import 'package:shared_preferences/shared_preferences.dart';
class PreferencesService {
Future<void> saveString(String key, String value) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(key, value);
}
Future<String?> getString(String key) async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString(key);
}
Future<void> saveInt(String key, int value) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setInt(key, value);
}
Future<int?> getInt(String key) async {
final prefs = await SharedPreferences.getInstance();
return prefs.getInt(key);
}
Future<void> saveBool(String key, bool value) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool(key, value);
}
Future<bool?> getBool(String key) async {
final prefs = await SharedPreferences.getInstance();
return prefs.getBool(key);
}
Future<void> remove(String key) async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove(key);
}
Future<void> clear() async {
final prefs = await SharedPreferences.getInstance();
await prefs.clear();
}
}
1.3 实际应用
class AuthService {
static const String _tokenKey = 'auth_token';
static const String _userIdKey = 'user_id';
Future<void> saveToken(String token) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(_tokenKey, token);
}
Future<String?> getToken() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString(_tokenKey);
}
Future<void> saveUserId(String userId) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(_userIdKey, userId);
}
Future<String?> getUserId() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString(_userIdKey);
}
Future<void> clearAuthData() async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove(_tokenKey);
await prefs.remove(_userIdKey);
}
}
二、Hive
2.1 添加依赖
dependencies:
hive: ^2.2.3
hive_flutter: ^1.1.0
dev_dependencies:
hive_generator: ^1.1.5
build_runner: ^2.4.6
2.2 初始化Hive
void main() async {
await Hive.initFlutter();
Hive.registerAdapter(UserAdapter());
await Hive.openBox<User>('users');
await Hive.openBox('settings');
runApp(const MyApp());
}
2.3 创建Adapter
import 'package:hive/hive.dart';
part 'user.g.dart';
@HiveType(typeId: 0)
class User extends HiveObject {
@HiveField(0)
late String id;
@HiveField(1)
late String name;
@HiveField(2)
late String email;
@HiveField(3)
late int age;
}
2.4 生成Adapter
flutter pub run build_runner build
2.5 使用Hive
class UserRepository {
final Box<User> _userBox;
UserRepository(this._userBox);
Future<void> saveUser(User user) async {
await _userBox.put(user.id, user);
}
User? getUser(String id) {
return _userBox.get(id);
}
List<User> getAllUsers() {
return _userBox.values.toList();
}
Future<void> deleteUser(String id) async {
await _userBox.delete(id);
}
}
三、SQFlite
3.1 添加依赖
dependencies:
sqflite: ^2.3.0
path_provider: ^2.1.0
3.2 创建数据库
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
class DatabaseHelper {
static Database? _database;
Future<Database> get database async {
if (_database != null) return _database!;
_database = await _initDatabase();
return _database!;
}
Future<Database> _initDatabase() async {
final dbPath = await getDatabasesPath();
final path = join(dbPath, 'example.db');
return await openDatabase(
path,
version: 1,
onCreate: (db, version) async {
await db.execute('''
CREATE TABLE users (
id TEXT PRIMARY KEY,
name TEXT,
email TEXT,
age INTEGER
)
''');
},
);
}
Future<void> insertUser(User user) async {
final db = await database;
await db.insert(
'users',
user.toMap(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
Future<User?> getUser(String id) async {
final db = await database;
final maps = await db.query(
'users',
where: 'id = ?',
whereArgs: [id],
);
if (maps.isNotEmpty) {
return User.fromMap(maps.first);
}
return null;
}
Future<List<User>> getAllUsers() async {
final db = await database;
final maps = await db.query('users');
return maps.map((map) => User.fromMap(map)).toList();
}
Future<void> updateUser(User user) async {
final db = await database;
await db.update(
'users',
user.toMap(),
where: 'id = ?',
whereArgs: [user.id],
);
}
Future<void> deleteUser(String id) async {
final db = await database;
await db.delete(
'users',
where: 'id = ?',
whereArgs: [id],
);
}
}
3.3 User模型
class User {
final String id;
final String name;
final String email;
final int age;
User({
required this.id,
required this.name,
required this.email,
required this.age,
});
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'email': email,
'age': age,
};
}
static User fromMap(Map<String, dynamic> map) {
return User(
id: map['id'],
name: map['name'],
email: map['email'],
age: map['age'],
);
}
}
四、文件存储
4.1 添加依赖
dependencies:
path_provider: ^2.1.0
4.2 文件操作
import 'dart:io';
import 'package:path_provider/path_provider.dart';
class FileStorageService {
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
Future<File> get _localFile async {
final path = await _localPath;
return File('$path/data.txt');
}
Future<String> readFile() async {
try {
final file = await _localFile;
final contents = await file.readAsString();
return contents;
} catch (e) {
return '';
}
}
Future<File> writeFile(String content) async {
final file = await _localFile;
return file.writeAsString(content);
}
Future<File> appendToFile(String content) async {
final file = await _localFile;
return file.writeAsString(content, mode: FileMode.append);
}
Future<void> deleteFile() async {
try {
final file = await _localFile;
if (await file.exists()) {
await file.delete();
}
} catch (e) {
// Handle error
}
}
}
4.3 保存JSON数据
import 'dart:convert';
class JsonStorageService {
Future<void> saveJson(String key, dynamic data) async {
final file = await _getJsonFile(key);
final jsonString = jsonEncode(data);
await file.writeAsString(jsonString);
}
Future<dynamic> loadJson(String key) async {
try {
final file = await _getJsonFile(key);
final jsonString = await file.readAsString();
return jsonDecode(jsonString);
} catch (e) {
return null;
}
}
Future<File> _getJsonFile(String key) async {
final path = await getApplicationDocumentsDirectory();
return File('${path.path}/$key.json');
}
}
五、存储方案对比
| 特性 | SharedPreferences | Hive | SQFlite | File |
|---|---|---|---|---|
| 数据类型 | 基本类型 | 对象 | 关系型 | 任意 |
| 查询能力 | 弱 | 中等 | 强 | 弱 |
| 性能 | 快 | 快 | 中 | 慢 |
| 适合场景 | 配置、token | 复杂对象 | 大量数据 | 文件存储 |
六、最佳实践
6.1 选择合适的存储方案
// 简单配置 - SharedPreferences
final prefs = await SharedPreferences.getInstance();
await prefs.setString('theme', 'dark');
// 复杂对象 - Hive
final userBox = Hive.box<User>('users');
await userBox.put('1', User(id: '1', name: 'John'));
// 大量数据 - SQFlite
final db = await DatabaseHelper().database;
await db.insert('users', user.toMap());
6.2 错误处理
try {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('key', 'value');
} catch (e) {
// 处理存储错误
}
6.3 数据加密
// 使用encrypt包加密敏感数据
import 'package:encrypt/encrypt.dart';
class SecureStorage {
final Encrypter _encrypter;
final IV _iv;
SecureStorage(this._encrypter, this._iv);
String encrypt(String plainText) {
return _encrypter.encrypt(plainText, iv: _iv).base64;
}
String decrypt(String encryptedText) {
return _encrypter.decrypt64(encryptedText, iv: _iv);
}
}
总结
选择合适的本地存储方案对于应用性能和用户体验至关重要:
- SharedPreferences:适合存储简单的配置和token
- Hive:适合存储复杂对象,性能优秀
- SQFlite:适合存储大量结构化数据
- File:适合存储文件和大型数据
通过合理选择存储方案,你可以构建高效、可靠的本地数据管理系统。
更多推荐
所有评论(0)