Appearance
Flutter 持久化存储
持久化存储概述
在 Flutter 应用中,持久化存储是指将数据保存在设备上,以便在应用重启后仍然可以访问。Flutter 提供了多种持久化存储方案,适用于不同的使用场景。
存储方案
1. SharedPreferences
SharedPreferences 是一种轻量级的键值对存储方案,适用于存储简单的数据,如用户偏好设置、令牌等。
安装:
bash
flutter pub add shared_preferences示例:
dart
import 'package:shared_preferences/shared_preferences.dart';
// 保存数据
Future<void> saveData() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('username', 'flutter');
await prefs.setInt('age', 3);
await prefs.setBool('isLoggedIn', true);
await prefs.setDouble('score', 99.5);
await prefs.setStringList('items', ['item1', 'item2', 'item3']);
}
// 读取数据
Future<void> loadData() async {
final prefs = await SharedPreferences.getInstance();
final username = prefs.getString('username');
final age = prefs.getInt('age');
final isLoggedIn = prefs.getBool('isLoggedIn');
final score = prefs.getDouble('score');
final items = prefs.getStringList('items');
print('Username: $username');
print('Age: $age');
print('Is Logged In: $isLoggedIn');
print('Score: $score');
print('Items: $items');
}
// 删除数据
Future<void> removeData() async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove('username');
// 清除所有数据
// await prefs.clear();
}2. 本地文件存储
本地文件存储适用于存储较大的数据,如图片、音频、JSON 数据等。
示例:
dart
import 'dart:io';
import 'dart:convert';
import 'package:path_provider/path_provider.dart';
// 保存数据到文件
Future<void> saveToFile() async {
final directory = await getApplicationDocumentsDirectory();
final file = File('${directory.path}/data.json');
final data = {
'username': 'flutter',
'age': 3,
'isLoggedIn': true,
};
await file.writeAsString(jsonEncode(data));
}
// 从文件读取数据
Future<void> loadFromFile() async {
final directory = await getApplicationDocumentsDirectory();
final file = File('${directory.path}/data.json');
if (await file.exists()) {
final contents = await file.readAsString();
final data = jsonDecode(contents);
print(data);
} else {
print('File does not exist');
}
}
// 删除文件
Future<void> deleteFile() async {
final directory = await getApplicationDocumentsDirectory();
final file = File('${directory.path}/data.json');
if (await file.exists()) {
await file.delete();
}
}3. SQLite
SQLite 是一种关系型数据库,适用于存储结构化数据,如用户信息、产品数据等。
安装:
bash
flutter pub add sqflite path示例:
dart
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 path = join(await getDatabasesPath(), 'app_database.db');
return await openDatabase(
path,
version: 1,
onCreate: (db, version) {
return db.execute(
'CREATE TABLE users(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, email TEXT)',
);
},
);
}
// 插入数据
Future<void> insertUser(Map<String, dynamic> user) async {
final db = await database;
await db.insert('users', user, conflictAlgorithm: ConflictAlgorithm.replace);
}
// 查询所有用户
Future<List<Map<String, dynamic>>> getUsers() async {
final db = await database;
return await db.query('users');
}
// 根据ID查询用户
Future<Map<String, dynamic>?> getUser(int id) async {
final db = await database;
final users = await db.query('users', where: 'id = ?', whereArgs: [id]);
return users.isNotEmpty ? users.first : null;
}
// 更新用户
Future<void> updateUser(int id, Map<String, dynamic> user) async {
final db = await database;
await db.update('users', user, where: 'id = ?', whereArgs: [id]);
}
// 删除用户
Future<void> deleteUser(int id) async {
final db = await database;
await db.delete('users', where: 'id = ?', whereArgs: [id]);
}
}
// 使用
final dbHelper = DatabaseHelper();
// 插入用户
await dbHelper.insertUser({'name': 'Flutter', 'email': 'flutter@example.com'});
// 查询所有用户
final users = await dbHelper.getUsers();
print(users);
// 根据ID查询用户
final user = await dbHelper.getUser(1);
print(user);
// 更新用户
await dbHelper.updateUser(1, {'name': 'Flutter Updated', 'email': 'updated@example.com'});
// 删除用户
await dbHelper.deleteUser(1);4. Hive
Hive 是一个轻量级的 NoSQL 数据库,适用于存储复杂的对象,性能比 SQLite 更好。
安装:
bash
flutter pub add hive hive_flutter示例:
dart
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
// 初始化 Hive
void initHive() async {
await Hive.initFlutter();
// 注册适配器(如果需要存储自定义对象)
// Hive.registerAdapter(UserAdapter());
await Hive.openBox('userBox');
}
// 保存数据
void saveUser() {
final box = Hive.box('userBox');
box.put('user', {
'name': 'Flutter',
'email': 'flutter@example.com',
'age': 3,
});
// 保存列表
box.put('items', ['item1', 'item2', 'item3']);
}
// 读取数据
void loadUser() {
final box = Hive.box('userBox');
final user = box.get('user');
final items = box.get('items');
print('User: $user');
print('Items: $items');
}
// 删除数据
void removeUser() {
final box = Hive.box('userBox');
box.delete('user');
// 清除所有数据
// box.clear();
}
// 存储自定义对象
@HiveType(typeId: 0)
class User extends HiveObject {
@HiveField(0)
String name;
@HiveField(1)
String email;
@HiveField(2)
int age;
User({required this.name, required this.email, required this.age});
}
// 生成适配器
// 运行命令: flutter pub run build_runner build
// 使用自定义对象
void saveCustomUser() {
final box = Hive.box<User>('userBox');
final user = User(name: 'Flutter', email: 'flutter@example.com', age: 3);
box.put('user', user);
}
void loadCustomUser() {
final box = Hive.box<User>('userBox');
final user = box.get('user');
print('User: ${user?.name}, ${user?.email}, ${user?.age}');
}5. 其他存储方案
Firebase Firestore
适用于需要云同步的应用。
安装:
bash
flutter pub add firebase_core firebase_firestoreGraphQL
适用于需要与 GraphQL API 交互的应用。
安装:
bash
flutter pub add graphql_flutter存储方案对比
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| SharedPreferences | 简单易用,适合存储小数据 | 存储容量有限,不适合复杂数据 | 存储用户偏好设置、令牌等 |
| 本地文件存储 | 适合存储大文件,如图片、音频等 | 需要手动管理文件,不适合结构化数据 | 存储图片、音频、JSON 数据等 |
| SQLite | 适合存储结构化数据,支持 SQL 查询 | 学习曲线较陡,性能可能不如 NoSQL | 存储用户信息、产品数据等 |
| Hive | 性能好,适合存储复杂对象 | 功能相对简单,不支持 SQL 查询 | 存储复杂对象,如用户配置、应用状态等 |
| Firebase Firestore | 云同步,实时数据 | 需要网络连接,可能产生费用 | 需要云同步的应用 |
存储最佳实践
根据数据类型选择合适的存储方案:
- 简单键值对:SharedPreferences
- 大文件:本地文件存储
- 结构化数据:SQLite
- 复杂对象:Hive
- 需要云同步:Firebase Firestore
合理管理存储空间:
- 定期清理不需要的数据
- 对大文件进行压缩
- 使用分页加载减少内存使用
数据安全:
- 敏感数据加密存储
- 不要在本地存储密码等敏感信息
- 使用安全的存储机制,如 Keychain (iOS) 或 Keystore (Android)
错误处理:
- 处理存储操作可能出现的错误
- 提供适当的错误提示
备份与恢复:
- 对于重要数据,提供备份和恢复功能
- 考虑使用云存储作为备份
总结
Flutter 提供了多种持久化存储方案,每种方案都有其适用场景。选择合适的存储方案并合理使用,可以使应用的数据管理更加高效和可靠。在实际开发中,根据数据的类型、大小和使用场景选择最适合的存储方案是非常重要的。