You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 04:45:38