Flutter开发:如何将HTTP请求改为同步调用以实现正确路由?
Flutter根据API响应跳转页面的正确姿势
别折腾同步请求了,Flutter的UI线程是单线程的,同步网络请求会直接卡死界面,而且sync_http在Flutter环境里本身就有兼容性问题,官方也不推荐这种用法。正确的做法是用异步请求+async/await等待响应返回后再处理路由。
用官方http包实现异步请求+路由跳转
1. 添加依赖
先在pubspec.yaml里添加官方的http包:
dependencies: http: ^1.1.0
2. 编写异步请求+路由逻辑
写一个带async标记的函数,用await等待请求完成,再根据响应结果跳转页面:
import 'package:http/http.dart' as http; import 'package:flutter/material.dart'; import 'dart:convert'; // 假设你有对应的目标页面 class TargetPage1 extends StatelessWidget { const TargetPage1({super.key}); @override Widget build(BuildContext context) => Scaffold(appBar: AppBar(title: Text('成功页面'))); } class ErrorPage extends StatelessWidget { const ErrorPage({super.key}); @override Widget build(BuildContext context) => Scaffold(appBar: AppBar(title: Text('错误页面'))); } class NetworkErrorPage extends StatelessWidget { const NetworkErrorPage({super.key}); @override Widget build(BuildContext context) => Scaffold(appBar: AppBar(title: Text('网络错误'))); } Future<void> fetchAndNavigate(BuildContext context, String param1, String param2) async { final requestUrl = Uri.parse('http://{serveraddress}:{port}/{apiname}/$param1/$param2'); try { // 等待请求完成 final response = await http.post(requestUrl); if (response.statusCode == 200) { // 解析响应内容,根据业务逻辑判断跳转 final responseData = json.decode(response.body); if (responseData['code'] == 0) { Navigator.push(context, MaterialPageRoute(builder: (_) => TargetPage1())); } else { Navigator.push(context, MaterialPageRoute(builder: (_) => ErrorPage())); } } else { // 非200状态码跳转到错误页面 Navigator.push(context, MaterialPageRoute(builder: (_) => ErrorPage())); } } catch (e) { // 捕获网络异常,跳转到网络错误页面 Navigator.push(context, MaterialPageRoute(builder: (_) => NetworkErrorPage())); } }
3. 在UI中调用函数
比如在按钮点击事件里触发请求:
ElevatedButton( onPressed: () { // 传入context和参数即可 fetchAndNavigate(context, '你的参数1', '你的参数2'); }, child: Text('发起请求并跳转'), )
优化:添加loading状态
为了避免用户重复点击,还可以加上loading状态,让请求过程中显示加载动画:
class MyPage extends StatefulWidget { const MyPage({super.key}); @override State<MyPage> createState() => _MyPageState(); } class _MyPageState extends State<MyPage> { bool _isLoading = false; Future<void> _handleRequest() async { setState(() { _isLoading = true; }); try { await fetchAndNavigate(context, '参数1', '参数2'); } finally { setState(() { _isLoading = false; }); } } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: _isLoading ? CircularProgressIndicator() : ElevatedButton( onPressed: _handleRequest, child: Text('发起请求'), ), ), ); } }
为什么不能用同步请求?
Flutter的UI渲染和业务逻辑都在同一个主线程,同步网络请求会阻塞这个线程,导致界面完全无响应,甚至被系统判定为"未响应"应用。而且sync_http这类包的设计初衷不是针对Flutter环境的,底层实现和Flutter的异步模型冲突,所以大概率跑不起来。
内容的提问来源于stack exchange,提问作者Saurabh Goyal
相关产品推荐
相关产品推荐

