Flutter中API GET请求阻塞问题求助
解决Flutter GET请求阻塞问题
1. 修复请求地址的协议与本地访问问题
你的请求地址localhost:8082/appointments存在两个关键问题:缺少http/https协议前缀,且在Flutter设备(模拟器/真机)中,localhost指向设备自身而非运行后端的电脑,直接导致请求无法到达本地服务。
修改方案:
- 强制添加协议前缀
http:// - 根据运行环境替换地址:
- Android模拟器:用
10.0.2.2代替localhost(Android模拟器专属映射地址,指向宿主机) - iOS模拟器:可直接使用
localhost - 真机/局域网测试:替换为电脑的局域网IP(如
192.168.1.100)
- Android模拟器:用
修改后的DoctorService代码:
class DoctorService { // 根据运行环境选择对应地址 final String appointmentURL = 'http://10.0.2.2:8082/appointments'; // Android模拟器 // final String appointmentURL = 'http://localhost:8082/appointments'; // iOS模拟器 // final String appointmentURL = 'http://192.168.1.100:8082/appointments'; // 真机/局域网 Future<List<Doctor>> getDoctors() async { print("TEST"); var res = await get(Uri.parse(appointmentURL)); print("TEST2"); if (res.statusCode == 200) { final obj = jsonDecode(res.body); // 补充Doctor模型的反序列化逻辑 List<Doctor> doctors = (obj as List).map((item) => Doctor.fromJson(item)).toList(); return doctors; } else { throw Exception("请求失败,状态码:${res.statusCode}"); } } }
2. 检查并添加网络权限
Android端
在android/app/src/main/AndroidManifest.xml中添加网络权限,放在<application>标签之前:
<uses-permission android:name="android.permission.INTERNET"/>
iOS端
若使用http协议(非https),需在ios/Runner/Info.plist中添加非安全域名允许配置:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
注意:上线版本建议改用https协议,移除该配置。
3. 优化FutureBuilder使用(避免重复请求)
当前在build方法中直接调用doctorService.getDoctors(),会导致组件每次重建都触发新请求,建议在initState中初始化Future:
class _DoctorSelectionScreen extends State<DoctorSelectionScreen> { DoctorService doctorService = DoctorService(); late Future<List<Doctor>> _doctorsFuture; @override void initState() { super.initState(); _doctorsFuture = doctorService.getDoctors(); // 仅初始化时请求一次 } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( drawer: const NavigationDrawerWidget(), appBar: AppBar(backgroundColor: Colors.green, title: const Text("Doctors")), body: FutureBuilder( future: _doctorsFuture, builder: (BuildContext context, AsyncSnapshot<List<Doctor>> snapshot) { if (snapshot.hasData) { List<Doctor>? doctors = snapshot.data; return Column(children: <Widget>[ for (var doctor in doctors!) buildDoctor(doctor) ]); } else if (snapshot.hasError) { return Center(child: Text("请求错误:${snapshot.error}")); // 显示错误信息便于排查 } else { return const Center(child: CircularProgressIndicator()); // 加载状态提示 } }), ), ); } }
4. 补充错误排查步骤
- 执行
flutter clean后重新构建项目,清除缓存问题 - 确认后端服务确实在
8082端口运行,且本地防火墙未拦截该端口 - 在
getDoctors中捕获异常并打印详细信息:
Future<List<Doctor>> getDoctors() async { print("TEST"); try { var res = await get(Uri.parse(appointmentURL)); print("TEST2"); print("响应状态码:${res.statusCode}"); if (res.statusCode == 200) { final obj = jsonDecode(res.body); List<Doctor> doctors = (obj as List).map((item) => Doctor.fromJson(item)).toList(); return doctors; } else { throw Exception("请求失败,状态码:${res.statusCode}"); } } catch (e) { print("请求异常:$e"); throw e; } }
内容的提问来源于stack exchange,提问作者lw00
相关产品推荐
相关产品推荐

