You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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结构完全对应,举两种常见结构的适配方案:
    1. 外层为数组的JSON示例:
    [
      {"name":"全麦面包","calorie":210,"img":"xxx.png"},
      {"name":"无糖豆浆","calorie":90,"img":"yyy.png"}
    ]
    
    对应解析逻辑直接把decode结果转List即可,和上面_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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 00:45:03