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

Flutter异步函数取数及IP接口调用类型转换错误求助

问题解决:IP获取错误与Flutter异步数据获取指南

错误原因分析

你遇到的type 'null' is not a subtype of type 'Map<String, dynamic>' in type cast错误,根源在这行代码:

data = data.isNotEmpty ? data : ModalRoute.of(context)!.settings.arguments as Map<String, dynamic>;

因为你没有通过路由传递arguments,ModalRoute.of(context)!.settings.arguments实际为null,强制转为Map就会抛出类型转换错误。另外getIp函数里的data是局部变量,没有更新组件状态,导致UI无法显示获取到的IP。

修复后的完整代码

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart';

void main() => runApp(const MaterialApp(home: IP()));

class IP extends StatefulWidget {
  const IP({Key? key}) : super(key: key);

  @override
  State<IP> createState() => _IPState();
}

class _IPState extends State<IP> {
  Map<String, dynamic> data = {};
  bool isLoading = true;
  String? errorMessage;

  void getIp() async {
    try {
      Response response = await get(Uri.parse('https://api.ipify.org/?format=json'));
      if (response.statusCode == 200) {
        final responseData = jsonDecode(response.body);
        if (responseData is Map<String, dynamic>) {
          setState(() {
            data = responseData;
            isLoading = false;
          });
          print(data['ip']);
        } else {
          throw Exception('解析数据格式错误');
        }
      } else {
        throw Exception('请求失败,状态码:${response.statusCode}');
      }
    } catch (e) {
      setState(() {
        errorMessage = e.toString();
        isLoading = false;
      });
    }
  }

  @override
  void initState() {
    super.initState();
    getIp();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('My IP address is'),
        centerTitle: true,
        elevation: 0.0,
        backgroundColor: Colors.cyan,
      ),
      body: Center(
        child: isLoading
            ? const CircularProgressIndicator()
            : errorMessage != null
                ? Text('获取失败:$errorMessage')
                : Text('${data['ip'] ?? '未获取到IP'}'),
      ),
    );
  }
}

关键修复点说明

  • 移除ModalRoute相关错误代码:你没有通过路由传参,这部分逻辑完全多余。
  • 用setState更新状态:异步获取数据后,必须调用setState通知Flutter框架重建UI,才能显示最新数据。
  • 添加错误处理:捕获网络请求、数据解析过程中的异常,避免崩溃,同时给用户反馈。
  • 增加加载状态:请求过程中显示加载指示器,提升用户体验。

Flutter异步获取数据核心要点

  • async/await语法:简化异步代码,把异步操作写成同步风格,await必须在async标记的函数内使用。
  • 状态更新:异步操作完成后,通过setState更新组件状态触发UI重建;复杂场景可使用Provider、Riverpod等状态管理库。
  • 异常处理:网络请求、数据解析都可能出错,用try-catch捕获异常,避免应用崩溃并展示错误信息。
  • 生命周期调用:在initState中触发异步请求是常见做法,但initState本身不能是async,需在内部调用异步函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 14:01:13