Flutter读取JSON数据出现RangeError空数组索引错误如何解决
错误根因
RangeError (index): Invalid value: Valid value range is empty: 0 错误本质是你在承载JSON解析结果的列表为空时,直接执行了下标为0的访问操作,和你调整JSON外层结构没有关联,问题出在异步加载时序校验、空值判断、解析逻辑三个环节。
可落地修复步骤
- 异步加载状态优先校验
读取本地JSON属于异步操作,必须通过FutureBuilder完整覆盖加载中、加载失败、数据为空三种边界场景,禁止未判断状态就直接访问列表下标,参考代码:import 'package:flutter/services.dart'; import 'dart:convert'; Widget build(BuildContext context) { return FutureBuilder<List<Breakfast>>( future: _loadBreakfastJson(), builder: (context, snapshot) { // 加载中状态处理 if (snapshot.connectionState != ConnectionState.done) { return const Center(child: CircularProgressIndicator()); } // 无数据/数据为空状态处理 if (snapshot.hasError || !snapshot.hasData || snapshot.data!.isEmpty) { return const SizedBox.shrink(); // 可替换为自定义空状态组件 } // 走到此处列表必然有数据,访问下标不会触发范围错误 return BreakfastCard(data: snapshot.data![0]); }, ); } // JSON加载解析抽离方法 Future<List<Breakfast>> _loadBreakfastJson() async { final jsonStr = await rootBundle.loadString("assets/breakfast.json"); final List<dynamic> jsonList = json.decode(jsonStr); return jsonList.map((item) => Breakfast.fromJson(item)).toList(); } - 匹配JSON结构与解析逻辑
确保解析逻辑和JSON结构完全对应,举两种常见结构的适配方案:- 外层为数组的JSON示例:
对应解析逻辑直接把decode结果转List即可,和上面[ {"name":"全麦面包","calorie":210,"img":"xxx.png"}, {"name":"无糖豆浆","calorie":90,"img":"yyy.png"} ]_loadBreakfastJson方法一致。
2. 外层为对象包裹数组的JSON示例:
对应解析逻辑需要先取包裹的数组字段:{ "code":0, "data": [ {"name":"全麦面包","calorie":210,"img":"xxx.png"} ] }Future<List<Breakfast>> _loadBreakfastJson() async { final jsonStr = await rootBundle.loadString("assets/breakfast.json"); final Map<String, dynamic> jsonObj = json.decode(jsonStr); final List<dynamic> jsonList = jsonObj['data']; return jsonList.map((item) => Breakfast.fromJson(item)).toList(); } - 新增列表安全取值兜底
可扩展List的安全取值方法,避免硬编码下标触发越界:extension ListSafeExt<T> on List<T> { T? safeGet(int index) => index >= 0 && index < length ? this[index] : null; } // 使用示例 final firstItem = snapshot.data!.safeGet(0); if (firstItem != null) { return BreakfastCard(data: firstItem); }
必查校验项
- 确认
pubspec.yaml中已正确声明JSON文件的assets路径,路径错误会导致读不到文件返回空数据 - 确认模型类
fromJson方法没有字段名拼写错误,字段不匹配会导致解析失败生成空列表 - 如果是渲染全量列表,优先用
ListView.builder按需渲染,不要硬编码访问多个下标
内容的提问来源于stack exchange,提问作者Gheh
相关产品推荐
相关产品推荐

