当前位置: 首页 > news >正文

Flutter 数据存储的四种核心方式 · 从 SharedPreferences 到 SQLite:Flutter 数据持久化终极整理


  1. Shared Preferences (偏好设置)

这是最简单的方法,用于保存一些简单的键值对。

步骤:

  1. 添加依赖:在 pubspec.yaml 文件中添加:
    dependencies:shared_preferences: ^2.2.2 # 请使用最新版本
    
    然后运行 flutter pub get。
  2. 使用方法:
    import 'package:shared_preferences/shared_preferences.dart';// 保存数据
    void saveData() async {final prefs = await SharedPreferences.getInstance();await prefs.setInt('counter', 42); // 保存整数await prefs.setBool('isDarkMode', true); // 保存布尔值await prefs.setString('token', 'abc123xyz'); // 保存字符串await prefs.setStringList('favorites', ['item1', 'item2']); // 保存字符串列表
    }// 读取数据
    void readData() async {final prefs = await SharedPreferences.getInstance();final int? counter = prefs.getInt('counter');final bool? isDarkMode = prefs.getBool('isDarkMode');final String? token = prefs.getString('token');final List<String>? favorites = prefs.getStringList('favorites');print('Counter: $counter');print('isDarkMode: $isDarkMode');print('Token: $token');print('Favorites: $favorites');
    }// 删除数据
    void removeData() async {final prefs = await SharedPreferences.getInstance();await prefs.remove('counter'); // 删除单个键// await prefs.clear(); // 清空所有数据
    }
    

优点:简单易用。 缺点:只能存储基本数据类型,不适合大量或复杂数据。


  1. 文件存储 (Files)

用于存储更复杂的数据,比如将对象序列化为 JSON 字符串后存入文件。

步骤:

  1. 添加依赖:需要路径支持包。
    dependencies:path_provider: ^2.0.15 # 请使用最新版本
    
  2. 使用方法:
    import 'dart:io';
    import 'dart:convert'; // 用于 JSON 编码解码
    import 'package:path_provider/path_provider.dart';// 定义一个数据模型
    class Settings {final String username;final int score;Settings({required this.username, required this.score});// 将对象转为 Map,便于转为 JSONMap<String, dynamic> toJson() => {'username': username,'score': score,};// 从 Map/JSON 创建对象factory Settings.fromJson(Map<String, dynamic> json) {return Settings(username: json['username'],score: json['score'],);}
    }// 获取应用文档目录的路径
    Future<String> get _localPath async {final directory = await getApplicationDocumentsDirectory();return directory.path;
    }// 获取文件的引用
    Future<File> get _localFile async {final path = await _localPath;return File('$path/settings.json');
    }// 写入文件(保存数据)
    Future<File> saveSettings(Settings settings) async {final file = await _localFile;// 将对象转为 JSON 字符串final jsonString = jsonEncode(settings.toJson());// 将字符串写入文件return file.writeAsString(jsonString);
    }// 读取文件(读取数据)
    Future<Settings> readSettings() async {try {final file = await _localFile;// 读取文件内容final contents = await file.readAsString();// 将 JSON 字符串解析为 Mapfinal jsonMap = jsonDecode(contents) as Map<String, dynamic>;// 从 Map 创建 Settings 对象return Settings.fromJson(jsonMap);} catch (e) {// 如果文件不存在或出错,返回一个默认值return Settings(username: 'Guest', score: 0);}
    }
    

优点:灵活,可以存储任何格式的数据。 缺点:需要手动处理序列化和反序列化,处理大量结构化数据时查询效率低。


  1. SQLite 数据库 (sqflite)

最适合存储大量需要复杂查询的结构化数据。

步骤:

  1. 添加依赖:
    dependencies:sqflite: ^2.3.0 # 请使用最新版本path_provider: ^2.0.15path: ^1.8.3
    
  2. 使用方法(简化示例):
    import 'package:sqflite/sqflite.dart';
    import 'package:path/path.dart';class Dog {final int? id;final String name;final int age;Dog({this.id, required this.name, required this.age});Map<String, dynamic> toMap() {return {'id': id,'name': name,'age': age,};}// ... fromMap 方法
    }class DatabaseHelper {static final _databaseName = "my_database.db";static final _databaseVersion = 1;static final table = 'dogs';static final columnId = 'id';static final columnName = 'name';static final columnAge = 'age';// 单例模式DatabaseHelper._privateConstructor();static final DatabaseHelper instance = DatabaseHelper._privateConstructor();static Database? _database;Future<Database> get database async {if (_database != null) return _database!;_database = await _initDatabase();return _database!;}_initDatabase() async {String path = join(await getDatabasesPath(), _databaseName);return await openDatabase(path,version: _databaseVersion,onCreate: _onCreate,);}// 创建表Future _onCreate(Database db, int version) async {await db.execute('''CREATE TABLE $table ($columnId INTEGER PRIMARY KEY AUTOINCREMENT,$columnName TEXT NOT NULL,$columnAge INTEGER NOT NULL)''');}// 插入一条数据(C)Future<int> insert(Dog dog) async {Database db = await instance.database;return await db.insert(table, dog.toMap());}// 查询所有数据(R)Future<List<Dog>> queryAll() async {Database db = await instance.database;List<Map> maps = await db.query(table);return maps.map((map) => Dog.fromMap(map)).toList();}// 更新数据(U)// 删除数据(D)// ... 其他方法
    }
    

优点:功能强大,查询高效,适合复杂数据。 缺点:需要编写较多的样板代码(Boilerplate Code)。可以考虑使用更高级的封装库,如drift(原 moor)来简化操作。


  1. 云端存储 (Firebase Firestore)

如果你的应用需要在线同步、实时更新或多用户支持,Firebase 是绝佳选择。

步骤:

  1. 在 Firebase 控制台创建项目并配置 Flutter 应用(官方文档很详细)。
  2. 添加依赖:
    dependencies:cloud_firestore: ^4.9.1 # 请使用最新版本
    
  3. 使用方法:
    import 'package:cloud_firestore/cloud_firestore.dart';// 获取 Firestore 实例
    final FirebaseFirestore firestore = FirebaseFirestore.instance;// 添加数据
    void addUser() {firestore.collection('users').add({'name': 'John Doe','age': 30,}).then((value) => print("User Added")).catchError((error) => print("Failed to add user: $error"));
    }// 读取数据(实时监听)
    Stream<QuerySnapshot> readUsers() {return firestore.collection('users').snapshots(); // 返回一个流,数据变化时会自动推送新数据
    }// 在 UI 中使用 StreamBuilder 来显示实时数据
    Widget build(BuildContext context) {return StreamBuilder<QuerySnapshot>(stream: readUsers(),builder: (context, snapshot) {if (snapshot.hasError) {return Text('Something went wrong');}if (snapshot.connectionState == ConnectionState.waiting) {return Text("Loading");}return ListView(children: snapshot.data!.docs.map((DocumentSnapshot document) {Map<String, dynamic> data = document.data()! as Map<String, dynamic>;return ListTile(title: Text(data['name']),subtitle: Text('Age: ${data['age']}'),);}).toList(),);},);
    }
    

优点:无需自己搭建后端,支持实时同步,功能强大。 缺点:需要网络连接,会产生费用(有免费额度)。


总结与建议

· 简单配置/用户偏好:毫不犹豫地使用 shared_preferences。
· 缓存图片或下载文件:使用文件存储。
· 复杂的本地数据(如待办事项、笔记、通讯录):使用 sqflite 数据库。如果你觉得 sqflite 代码太繁琐,可以研究一下 hive(一个非常快且无样板代码的键值数据库)或 drift(一个强大的 SQLite 封装库)。
· 需要在线同步、实时协作:使用 Firebase Firestore。
· 综合应用:一个应用通常会组合使用多种方案。例如,用 shared_preferences 存用户主题设置,用 sqflite 存本地文章草稿,同时用 Firestore 将最终文章同步到云端。

希望这份整理能帮助你清晰地规划 Flutter 应用中的数据保存策略!


文章转载自:

http://RVqIxlJA.ngghw.cn
http://2Hl0xJPE.ngghw.cn
http://72Kxyiio.ngghw.cn
http://y8NISmLI.ngghw.cn
http://0hCENbLT.ngghw.cn
http://JQ72ydPV.ngghw.cn
http://Kjxx3nDW.ngghw.cn
http://2XwxaQxX.ngghw.cn
http://VnTYx6Bg.ngghw.cn
http://1NU30x84.ngghw.cn
http://1o94Yvq5.ngghw.cn
http://4XTfoIEi.ngghw.cn
http://6PDO41kF.ngghw.cn
http://5GS2iIKs.ngghw.cn
http://9R45zQdD.ngghw.cn
http://qsbUfYuy.ngghw.cn
http://49l4NwDp.ngghw.cn
http://ErTb1JBk.ngghw.cn
http://RtWl1bT3.ngghw.cn
http://OgY3ReWu.ngghw.cn
http://w2DahfPn.ngghw.cn
http://boQFli4x.ngghw.cn
http://sEebWNot.ngghw.cn
http://tQqSS7BO.ngghw.cn
http://dpXXPzuO.ngghw.cn
http://SaHxfnxu.ngghw.cn
http://MTYB2573.ngghw.cn
http://J6oaRvqz.ngghw.cn
http://o7otpEOX.ngghw.cn
http://Ek7ODcja.ngghw.cn
http://www.dtcms.com/a/381209.html

相关文章:

  • 容器问答题下
  • 题目:盛水最多的容器(medium)
  • win7 R 4.4.0和RStudio1.25的版本兼容性以及系统区域设置有关 导致Plots绘图面板被禁用,但是单独页面显示
  • 中级统计师-统计法规-第六章 统计行政许可制度
  • Coze源码分析-资源库-创建知识库-前端源码-核心逻辑与接口
  • MySQL数据库-03(字段的约束)
  • Secure Boot 的Linux系统中添加模块
  • 内存泄漏的危害(Memory Leak)
  • Linux进程概念(中):进程优先级和环境变量
  • 【完整源码+数据集+部署教程】X片唇部实例分割系统源码和数据集:改进yolo11-swintransformer
  • 【.Net技术栈梳理】08-控制反转(IoC)与依赖注入(DI)
  • GFSK调制解调介绍(蓝牙GFSK BT=0.5)
  • 【202509新版】Hexo + GitHub Pages 免费部署个人博客|保姆级教程 第二部
  • 【算法--链表】147.对链表进行插入排序--通俗讲解
  • 亚马逊产品转化怎么提高?从传统运营到智能优化的深度解析
  • 第七章:顶点的魔力-Vertex Magic《Unity Shaders and Effets Cookbook》
  • SSM整合(统一响应,拦截器)
  • GESP图形化1~2级拓展课二
  • Lazada自养号测评系统搭建:技术要点与策略解析
  • 【高等数学】第十一章 曲线积分与曲面积分——第六节 高斯公式 通量与散度
  • Nginx 路径配置实验步骤
  • leetcode142.环形链表II
  • 【Python】家庭用电数据分析Prophet预测
  • std::thread是可以被std::move吗?
  • Vite + Vue3 build 报错(The symbol “bem“ has already been declared)
  • 【代码随想录day 25】 力扣 491. 递增子序列
  • Kanji Dojo,一款日语学习工具
  • 机器人检验报告包含内容
  • .gitignore文件的作用及用法
  • numpy数组的升维和降维的方法集锦