使用Shared Preferences实现Flutter Map数据本地持久化报错求助
解决方案
步骤1:确认pubspec.yaml添加依赖
不需要引入path_provider,这个场景下用不到,只需要添加shared_preferences即可:
dependencies: flutter: sdk: flutter shared_preferences: ^2.2.2
dart:convert为内置库,无需额外引入。
步骤2:封装持久化工具类
以下工具类直接解决两类报错:
- 类型匹配错误:将Map转成JSON字符串存储,完全避开List
类型转换问题 - 空指针错误:读取时无存储数据默认返回空Map,永远不会返回null
import 'dart:convert'; import 'package:shared_preferences/shared_preferences.dart'; class WordStorageUtil { static const String _savedWordsKey = 'user_saved_words'; // 保存全量记忆句子Map static Future<void> saveSavedWords(Map<String, String> savedWords) async { final prefs = await SharedPreferences.getInstance(); String jsonStr = jsonEncode(savedWords); await prefs.setString(_savedWordsKey, jsonStr); } // 读取记忆句子Map,返回值永远非空 static Future<Map<String, String>> getSavedWords() async { final prefs = await SharedPreferences.getInstance(); String? jsonStr = prefs.getString(_savedWordsKey); if (jsonStr == null) return {}; Map<String, dynamic> jsonMap = jsonDecode(jsonStr); return jsonMap.map((key, value) => MapEntry(key, value as String)); } // 单条新增/更新记忆句子便捷方法 static Future<void> updateSentence(String word, String sentence) async { Map<String, String> currentData = await getSavedWords(); currentData[word] = sentence; await saveSavedWords(currentData); } // 单条删除记忆句子便捷方法 static Future<void> deleteSentence(String word) async { Map<String, String> currentData = await getSavedWords(); currentData.remove(word); await saveSavedWords(currentData); } }
步骤3:业务代码接入示例
// 全局存储用户自定义记忆句子的变量 Map<String, String> Savedwords = {}; // 页面初始化时读取本地存储数据 @override void initState() { super.initState(); loadLocalData(); } Future<void> loadLocalData() async { // 直接读取即可,无需做空判断,不会返回null Savedwords = await WordStorageUtil.getSavedWords(); // 遍历操作不会触发空指针错误 Savedwords.forEach((word, sentence) { debugPrint('$word: $sentence'); }); setState(() {}); } // 用户新增/修改记忆句子时调用 void onSaveSentence(String word, String inputSentence) async { await WordStorageUtil.updateSentence(word, inputSentence); // 刷新本地变量 Savedwords = await WordStorageUtil.getSavedWords(); }
报错根因说明
- 第一类String不是List
子类型的错误:你之前大概率是尝试用 setStringList方法存储Map,或者把读取到的String值强行转成List导致的,本方案统一用JSON字符串存取,完全规避类型冲突 - 第二类空指针错误:你之前读取数据时没有做空判断,首次启动App无存储数据时读返回null,直接调用遍历方法就会触发空指针,本方案默认返回空Map,永远不会返回null
内容的提问来源于stack exchange,提问作者Green Haired Orangutan
相关产品推荐
相关产品推荐

