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

Flutter地震查询应用报错:The method 'Cast' was called on null及资源问题

解决Flutter地震查询应用的两个关键错误:Cast调用空值与资源释放失败

一、修复"The method 'Cast' was called on null"错误

问题根源

EarthquakeModel.fromJson方法中,直接对json['bbox']调用cast<double>(),但当JSON数据中不存在bbox字段或其值为null时,json['bbox']返回null,此时调用cast方法会触发空值调用错误。

修复代码

给bbox的解析逻辑添加空值判断,仅当字段存在且非空时执行类型转换:

class EarthquakeModel {
  String? type;
  Metadata? metadata;
  List<Features>? features;
  List<double>? bbox;

  EarthquakeModel({this.type, this.metadata, this.features, this.bbox});

  EarthquakeModel.fromJson(Map<String, dynamic> json) {
    type = json['type'];
    metadata = json['metadata'] != null
        ? new Metadata.fromJson(json['metadata'])
        : null;
    if (json['features'] != null) {
      features = <Features>[];
      json['features'].forEach((v) {
        features!.add(new Features.fromJson(v));
      });
    }
    // 新增空值判断,避免null调用cast
    bbox = json['bbox'] != null ? json['bbox'].cast<double>() : null;
  }
}

二、修复"a resource failed to call release error"错误

问题根源

  1. 状态隔离混乱:主页面与BuildGoogleMap组件各自维护独立的Marker列表和Map控制器实例,导致资源无法同步释放,控制器重复创建引发冲突。
  2. 嵌套setState滥用:FloatingActionButton点击事件中嵌套两层setState,触发不必要的重复刷新,干扰资源生命周期管理。
  3. 无状态组件误用:BuildGoogleMap无需维护自身状态,却使用有状态组件,增加了资源管理复杂度。

修复方案

1. 将地图组件改为无状态组件,通过外部参数传递依赖

class BuildGoogleMap extends StatelessWidget {
  final Completer<GoogleMapController> controller;
  final Set<Marker> markers;

  const BuildGoogleMap({Key? key, required this.controller, required this.markers}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: MediaQuery.of(context).size.width,
      height: MediaQuery.of(context).size.height,
      child: GoogleMap(
        initialCameraPosition: const CameraPosition(
            target: LatLng(36.1083333, 117.8608333),
            zoom: 3
        ),
        mapType: MapType.normal,
        onMapCreated: (GoogleMapController controller){
          this.controller.complete(controller);
        },
        markers: markers,
      ),
    );
  }
}

2. 优化主页面状态管理与事件逻辑

  • 移除嵌套setState,在Future回调内统一触发状态刷新
  • 共享Map控制器和Marker列表给地图组件,确保资源统一管理
class QuakeApp extends StatefulWidget {
  const QuakeApp({Key? key}) : super(key: key);

  @override
  State<QuakeApp> createState() => _QuakeAppState();
}

class _QuakeAppState extends State<QuakeApp> {
  late Future<EarthquakeModel> quakeData;
  final Completer<GoogleMapController> _controller = Completer();
  final List<Marker> _markerList = <Marker>[];

  @override
  void initState() {
    super.initState();
    quakeData = Network().getEarthquake();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          BuildGoogleMap(controller: _controller, markers: Set<Marker>.of(_markerList)),
        ],
      ),
      floatingActionButton: FloatingActionButton.extended(
        onPressed: (){
          _markerList.clear();
          quakeData.then((quake) {
            quake.features?.forEach((element) {
              _markerList.add(Marker(
                markerId: MarkerId(element.id ?? ''),    
                infoWindow: InfoWindow(
                  title: element.properties?.mag?.toString(),
                ),
                icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueMagenta),
                position: LatLng(element.geometry?.coordinates?[1] ?? 0, element.geometry?.coordinates?[0] ?? 0),
                onTap: (){}
              ));
            });
            // 统一在数据加载完成后刷新状态
            setState(() {});
          });
        },
        label: const Text('Find Quakes')
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 05:54:09