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

Flutter使用Hive添加收藏元素时调用null的routes属性报错如何解决?

问题根因

1. 报错直接触发原因

你在TransportService.getMarshrutWithStops方法的第75行List<Routes> routes = routesbyTransportType[ttId].routes;中,routesbyTransportType[ttId]返回了null,直接调用null对象的routes属性触发了NoSuchMethodError。

2. 收藏逻辑核心错误

你的Hive操作key不匹配:

  • 保存收藏时,你用列表下标index作为Hive的key存储数据:favoriteRoutesBox.put(index, _routes[index]);
  • 删除收藏时,你用业务id_routes[index].route.ttId作为key删除:favoriteRoutesBox.delete(_routes[index].route.ttId);
    两者完全不对应,导致你点击取消收藏时根本删不掉对应存储的条目,甚至可能误删其他数据。删除操作完成后你也没有调用setState刷新UI状态,页面状态和Hive存储状态不一致,重新进入收藏页时传入的widget.ttId可能已经是无效值,导致routesbyTransportType中找不到对应key的条目,触发空异常。

3. 缺少防御性校验

getMarshrutWithStops方法没有对routesbyTransportType[ttId]做非空判断,就算fetchTransportWithRoutes执行完成,也无法保证routesbyTransportType中一定存在入参ttId对应的条目。


修复方案

1. 修复Service层空校验

修改getMarshrutWithStops方法,增加非空判断:

Future<List<RouteWithStops>> getMarshrutWithStops(int ttId) async {
  if (routesbyTransportType.isEmpty) {
    await fetchTransportWithRoutes();
  }
  // 增加非空判断
  final transportItem = routesbyTransportType[ttId];
  if (transportItem == null || transportItem.routes == null) {
    return [];
  }
  List<Routes> routes = transportItem.routes;
  List<ScheduleVariants> variants = [];

  variants.addAll(await api.fetchSchedule());

  List<RouteWithStops> routesWithStops = [];

  for (Routes route in routes) {
    final routeWithStops = RouteWithStops();
    // 匹配到对应的调度变体再添加,避免取不到值报错
    final matchedVariant = variants.where((variant) => variant.mrId == route.mrId).firstOrNull;
    if (matchedVariant != null) {
      routeWithStops.route = route;
      routeWithStops.variant = matchedVariant;
      routesWithStops.add(routeWithStops);
    }
  }
  return routesWithStops;
}

2. 统一Hive操作的key,修复收藏逻辑

推荐用业务唯一id作为Hive的key,避免列表顺序变化导致key错位,同时删除后刷新UI:

Widget getIcon(int index) {
  // 用业务id判断是否存在收藏
  final routeId = _routes[index].route.ttId;
  if (favoriteRoutesBox.containsKey(routeId)) {
    return Icon(Icons.favorite, color: Colors.red);
  }
  return Icon(Icons.favorite_border);
}

void onFavoritePress(int index) {
  final routeId = _routes[index].route.ttId;
  if (favoriteRoutesBox.containsKey(routeId)) {
    favoriteRoutesBox.delete(routeId);
  } else {
    favoriteRoutesBox.put(routeId, _routes[index]);
  }
  // 刷新UI状态
  setState(() {});
}

3. 增加异步调用异常捕获

修改页面initState,对异步请求增加异常捕获,避免未处理异常直接崩溃:

@override
void initState() {
  super.initState();
  // 先初始化Hive和控制器
  favoriteRoutesBox = Hive.box(favoritesBox);
  _editingController = TextEditingController();
  // 确保ttId是有效值再发起请求
  if (widget.ttId != null) {
    service.getMarshrutWithStops(widget.ttId).then((value) {
      if (mounted) {
        setState(() {
          _routes.addAll(value);
        });
      }
    }).catchError((err) {
      // 按需处理异常,比如弹出提示
      debugPrint('加载路线失败: $err');
    });
  }
}

内容的提问来源于stack exchange,提问作者user16357470

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 23:45:08