Flutter数独游戏JSON存储空值异常:实现继续游戏功能遇问题
解决Flutter数独游戏序列化空值异常问题
第一步:修正SudokuCell模型的JSON序列化逻辑
空值异常多数源于模型类toJson方法未处理null字段,需确保所有可能为空的字段都有兜底处理:
class SudokuCell { final int? value; final bool isFixed; final List<int> notes; SudokuCell({this.value, required this.isFixed, required this.notes}); // 处理空值的toJson方法 Map<String, dynamic> toJson() { return { 'value': value ?? 0, // 空值替换为业务允许的默认值,比如0 'isFixed': isFixed, 'notes': notes, }; } // 同步修正反序列化逻辑 factory SudokuCell.fromJson(Map<String, dynamic> json) { return SudokuCell( value: json['value'] == 0 ? null : json['value'], isFixed: json['isFixed'], notes: List<int>.from(json['notes']), ); } }
第二步:完善GameController的序列化逻辑
确保控制器中存储的二维单元格数组无null元素,且整体序列化逻辑覆盖所有字段:
class GameController { late List<List<SudokuCell>> grid; String? currentDifficulty; int? elapsedTime; // 序列化游戏数据 Map<String, dynamic> toJson() { final gridJson = grid.map((row) => row.map((cell) => cell.toJson()).toList()).toList(); return { 'grid': gridJson, 'currentDifficulty': currentDifficulty ?? 'easy', // 空值兜底 'elapsedTime': elapsedTime ?? 0, // 空值兜底 }; } // 反序列化游戏数据 factory GameController.fromJson(Map<String, dynamic> json) { final controller = GameController(); controller.grid = (json['grid'] as List) .map((rowJson) => (rowJson as List) .map((cellJson) => SudokuCell.fromJson(cellJson)) .toList()) .toList(); controller.currentDifficulty = json['currentDifficulty']; controller.elapsedTime = json['elapsedTime']; return controller; } }
第三步:SharedPreferences存储时的异常防护
存储前确保序列化后的JSON无null值,同时捕获序列化/反序列化异常便于排查:
// 存储游戏数据 Future<void> saveGame(GameController controller) async { final prefs = await SharedPreferences.getInstance(); try { final gameJson = jsonEncode(controller.toJson()); await prefs.setString('saved_game', gameJson); } catch (e) { print('序列化失败:$e'); } } // 读取游戏数据 Future<GameController?> loadGame() async { final prefs = await SharedPreferences.getInstance(); final gameJson = prefs.getString('saved_game'); if (gameJson == null) return null; try { final gameMap = jsonDecode(gameJson) as Map<String, dynamic>; return GameController.fromJson(gameMap); } catch (e) { print('反序列化失败:$e'); return null; } }
快速排查点
- 单独测试单个
SudokuCell的序列化:调用jsonEncode(SudokuCell(...).toJson()),定位具体抛出异常的字段 - 检查字段nullable修饰:确保非必填字段都标记为
int?/String?,避免未初始化的非空字段导致报错 - 验证二维数组完整性:确保
GameController.grid中没有null元素,初始化时要填满所有单元格
内容的提问来源于stack exchange,提问作者Adeen
相关产品推荐
相关产品推荐

