Flutter中用Riverpod和HTTP解析JSON失败,求排查
Flutter JSON解析映射阶段失败的问题排查与修复
问题描述
参考Flutter官方文档实现后台JSON解析,请求能正常获取响应内容,但在映射到实体类阶段停止执行,仅打印到“genderData out 2 parsed”,相关代码如下:
class NameClass { final String name; NameClass({required this.name}); } var nameList = [ 'Martine', 'Els', 'Dirk', 'Alain', ]; class GenderData { final String gender; final int count; final String name; final double prob; const GenderData({ required this.gender, required this.count, required this.name, required this.prob, }); factory GenderData.fromJson(Map<String, dynamic> json) { return GenderData( gender: json['gender'] as String, count: json['count'] as int, name: json['name'] as String, prob: json['prob'] as double, ); } } var _names = "name[]=" + nameList.join('&name[]=').toString(); GenderData? out; Future<List<GenderData>> getGenderData() async { print("getGenderData out"); final response = await get(Uri.parse('https://api.genderize.io/?${_names}')); print("response.body"); print(response.body); return compute(parsePhotos, response.body); } List<GenderData> parsePhotos(String responseBody) { print("genderData out 1"); final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>(); print("genderData out 2 parsed"); print(parsed); out = parsed.map<GenderData>((json) => GenderData.fromJson(json)).toList(); print("genderData out 3"); return (out); }
问题根源
核心是类型不匹配导致的隐式运行错误:
- 全局变量
out的类型是GenderData?(单个可空对象),但parsed.map(...).toList()返回的是List<GenderData>(对象列表),将列表赋值给单个对象类型的变量会直接抛出类型错误,代码执行到这一行就中断,无法继续打印“genderData out 3”。 parsePhotos函数声明返回List<GenderData>,但最后返回的是out(GenderData?类型),类型完全不兼容,即使前面的赋值不报错,这里也会出现编译错误。
修复方案
修改parsePhotos函数,删除多余的全局变量,直接处理并返回列表:
// 删除全局的GenderData? out;变量 List<GenderData> parsePhotos(String responseBody) { print("genderData out 1"); final parsed = jsonDecode(responseBody) as List<dynamic>; print("genderData out 2 parsed"); print(parsed); final genderList = parsed.map<GenderData>((json) => GenderData.fromJson(json as Map<String, dynamic>)).toList(); print("genderData out 3"); return genderList; }
额外优化建议
为避免API返回字段类型不符合预期导致的崩溃,在GenderData.fromJson中增加空安全与类型兼容处理:
factory GenderData.fromJson(Map<String, dynamic> json) { return GenderData( gender: json['gender'] as String? ?? 'unknown', count: json['count'] as int? ?? 0, name: json['name'] as String? ?? '', prob: (json['prob'] as num?)?.toDouble() ?? 0.0, ); }
内容的提问来源于stack exchange,提问作者Hadi Majidi
相关产品推荐
相关产品推荐

