Flutter Provider开发Todo应用重启后待办数据丢失问题求助
问题根因
所有待办数据仅保存在应用运行时的内存中,未做本地持久化处理。应用冷启动、重启时内存会被系统回收,Taskdata类初始化默认返回空任务列表,之前添加的待办自然全部丢失。代码中配置的restorationScopeId仅支持应用在后台被系统临时杀死后的短时间状态恢复,无法实现永久本地存储。
修复方案
采用shared_preferences实现轻量本地持久化,步骤如下:
1. 添加依赖
在项目pubspec.yaml的dependencies节点下新增依赖:
dependencies: flutter: sdk: flutter provider: ^6.1.1 shared_preferences: ^2.2.2
执行flutter pub get完成依赖安装。
2. 改造任务模型,支持序列化
本地存储无法直接保存Dart对象,需要给任务类增加JSON互转方法,修改task_model.dart代码:
class task{ final String name; bool isDone; task( {this.isDone=false,required this.name}); void toggleDone(){ isDone=!isDone; } // 对象转可存储的Map结构 Map<String, dynamic> toJson() { return { 'name': name, 'isDone': isDone, }; } // 从存储的Map解析为任务对象 factory task.fromJson(Map<String, dynamic> json) { return task( name: json['name'] as String, isDone: json['isDone'] as bool, ); } }
3. 改造状态管理类,增加持久化逻辑
修改task_data.dart,实现应用启动时读本地数据、数据变更时自动存本地的逻辑:
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:todo/task_model.dart'; class Taskdata extends ChangeNotifier{ List<task> tasks = []; static const String _storageKey = 'todo_task_list'; Taskdata() { // 初始化时自动加载本地存储的任务 _loadLocalTasks(); } // 读取本地存储的任务 Future<void> _loadLocalTasks() async { final prefs = await SharedPreferences.getInstance(); final String? storedTasks = prefs.getString(_storageKey); if (storedTasks != null) { final List<dynamic> jsonList = jsonDecode(storedTasks); tasks = jsonList.map((item) => task.fromJson(item as Map<String, dynamic>)).toList(); notifyListeners(); } } // 保存当前任务列表到本地 Future<void> _saveTasksToLocal() async { final prefs = await SharedPreferences.getInstance(); final String jsonStr = jsonEncode(tasks.map((t) => t.toJson()).toList()); await prefs.setString(_storageKey, jsonStr); } void addTask(String newTaskTitle){ final task2= task(name: newTaskTitle); tasks.add(task2); _saveTasksToLocal(); notifyListeners(); } void udatetask(task task){ task.toggleDone(); _saveTasksToLocal(); notifyListeners(); } void deleteTask(task task){ tasks.remove(task); _saveTasksToLocal(); notifyListeners(); } }
额外优化建议
- 现有代码类名未遵循Dart开发规范,比如
task应为大驼峰命名Task、AddtaskScreeen存在拼写错误(Screen少写了n),建议调整避免后续协作出问题 AddtaskScreeen中TextEditingController定义在StatelessWidget中会有内存泄漏风险,建议将该页面改为StatefulWidget,在dispose生命周期中释放控制器- 当前持久化方案适合轻量待办场景,后续如果需要增加任务分类、截止时间、提醒等复杂功能,可以替换为hive、sqflite等本地数据库方案
内容的提问来源于stack exchange,提问作者Vipin
相关产品推荐
相关产品推荐

