Flutter解析API响应创建Game对象时遭遇List类型不匹配异常的解决方案咨询
Flutter JSON解析错误:type 'List' is not a subtype of type 'List<Map<String, dynamic>>'
问题背景
我从API获取了如下响应文本,尝试创建新的Game对象时触发了类型不匹配的错误:
API响应内容:
{success: true, games: [{game_id: 3, game_gide: {0: b, 1: , 2: , 3: a, 11: b, 14: e}, game_cells: [3,8,23,18,2,7,17,22,1,6,16,21], game_questions: [{title: question 2 h, answer: abcde, isTrue: false}, {title: question 1 h, answer: xxxxx, isTrue: false}]}
错误信息:
Unhandled Exception: type 'List' is not a subtype of type 'List<Map<String, dynamic>>'
Game与Question类代码:
class Game { String gameId; String gameLevel; List<int> gameCells; List<Question> gameQuestions; Game({ this.gameId, this.gameLevel, this.gameCells, this.gameQuestions, }); static fromJson(Map<String, dynamic> parsedJson){ print(parsedJson['game_vertical_questions']); return Game( gameId: parsedJson['game_id'], gameLevel: parsedJson['game_level'], gameCells: (jsonDecode(parsedJson['game_cells']) as List<dynamic>).cast<int>(), gameQuestions : Question.listFromJson(parsedJson['game_questions']), ); } } class Question { String title; String answer; bool isTrue; Question({ this.title, this.answer, this.isTrue}); static listFromJson(List<Map<String, dynamic>> list) { List<Question> questions = []; for (var value in list) { questions.add(Question.fromJson(value)); } return questions; } static fromJson(Map<String, dynamic> parsedJson){ return Question( title: parsedJson["title"], answer: parsedJson["answer"], isTrue: parsedJson["isTrue"] ); } }
触发错误的代码:
var jsonData = json.decode(response.body); var res = jsonData["games"]; for (var g in res){ //print(g); Game game = Game.fromJson(g); setState(() { gamesList.add(game); }); }
错误指向Game类中的这一行:
gameQuestions : Question.listFromJson(parsedJson['game_questions']),
错误原因分析
这个错误的核心是类型不匹配:你的Question.listFromJson方法要求传入List<Map<String, dynamic>>类型的参数,但parsedJson['game_questions']实际是List<dynamic>类型(json.decode返回的集合默认是dynamic泛型),Dart无法自动将List<dynamic>隐式转换为List<Map<String, dynamic>>,因此抛出了类型转换异常。
另外你提供的API响应存在JSON格式不规范问题:所有键和字符串值都没有用双引号包裹(比如success应该是"success",b应该是"b"),虽然Dart的json.decode可能兼容部分不规范JSON,但这可能导致解析后的结构和预期不一致,也是潜在隐患。
解决办法
1. 修改Question.listFromJson的参数类型
将方法参数从List<Map<String, dynamic>>改为List<dynamic>,并在内部显式转换每个元素类型:
class Question { // ... 其他代码不变 static listFromJson(List<dynamic> list) { List<Question> questions = []; for (var value in list) { // 显式转换每个元素为Map<String, dynamic> questions.add(Question.fromJson(value as Map<String, dynamic>)); } return questions; } // ... 其他代码不变 }
2. 增加空值判断与类型校验
在Game.fromJson中对game_questions做空值判断,同时修正字段映射错误(API里是game_gide,但你代码里用的是game_level):
static fromJson(Map<String, dynamic> parsedJson){ return Game( gameId: parsedJson['game_id'].toString(), // 确保转为String类型 gameLevel: parsedJson['game_gide']?.toString(), // 修正字段名不匹配问题 gameCells: (parsedJson['game_cells'] as List<dynamic>).cast<int>(), // 无需jsonDecode,game_cells已是数组 gameQuestions: parsedJson['game_questions'] != null ? Question.listFromJson(parsedJson['game_questions'] as List<dynamic>) : [], // 空数组作为默认值避免空指针 ); }
3. 修复API响应的JSON格式(如果可控)
建议让API返回标准JSON格式,所有键和字符串值用双引号包裹,示例如下:
{ "success": true, "games": [ { "game_id": 3, "game_gide": {"0": "b", "1": "", "2": "", "3": "a", "11": "b", "14": "e"}, "game_cells": [3,8,23,18,2,7,17,22,1,6,16,21], "game_questions": [ {"title": "question 2 h", "answer": "abcde", "isTrue": false}, {"title": "question 1 h", "answer": "xxxxx", "isTrue": false} ] } ] }
标准格式能避免很多解析时的意外问题。
内容的提问来源于stack exchange,提问作者Amr Zankalony
相关产品推荐
相关产品推荐

