Flutter中使用HttpClient跟踪未关闭的连接/请求方法
在Flutter中跟踪HttpClient的活跃请求并显示加载指示器
要实现跟踪未关闭的HttpClient连接/请求,并根据状态显示加载指示器,核心思路是封装HttpClient并维护活跃请求计数器,再通过状态监听触发UI更新。以下是具体实现方案:
1. 封装带请求跟踪的HttpClient
创建一个包装类,对原始HttpClient的请求方法进行封装,在请求发起和完成时更新计数器:
import 'dart:io'; import 'package:flutter/foundation.dart'; class TrackedHttpClient { final HttpClient _client = HttpClient(); final ValueNotifier<int> activeRequests = ValueNotifier(0); // 封装GET请求 Future<HttpClientResponse> get(Uri url, {Map<String, String>? headers}) async { activeRequests.value++; try { final request = await _client.getUrl(url); headers?.forEach((key, value) => request.headers.add(key, value)); return await request.close(); } finally { // 无论请求成功/失败/取消,都减少计数 activeRequests.value--; } } // 封装POST请求(同理可扩展put、delete等方法) Future<HttpClientResponse> post(Uri url, {Map<String, String>? headers, List<int>? body}) async { activeRequests.value++; try { final request = await _client.postUrl(url); headers?.forEach((key, value) => request.headers.add(key, value)); if (body != null) { await request.add(body); } return await request.close(); } finally { activeRequests.value--; } } // 关闭原始HttpClient,释放资源 void close() => _client.close(); }
2. 在UI中监听状态并显示加载指示器
可以通过ValueListenableBuilder直接监听计数器变化,或者结合状态管理库(如Provider、Riverpod)。下面是基于ValueListenableBuilder的简单示例:
import 'package:flutter/material.dart'; class RequestTrackingPage extends StatefulWidget { const RequestTrackingPage({super.key}); @override State<RequestTrackingPage> createState() => _RequestTrackingPageState(); } class _RequestTrackingPageState extends State<RequestTrackingPage> { final TrackedHttpClient _trackedClient = TrackedHttpClient(); // 示例发起请求的方法 Future<void> fetchSampleData() async { try { final response = await _trackedClient.get(Uri.parse('https://example.com')); if (response.statusCode == 200) { // 处理响应数据 } } catch (e) { // 捕获并处理请求错误 } } @override void dispose() { _trackedClient.close(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('请求跟踪示例')), body: Stack( children: [ Center( child: ElevatedButton( onPressed: fetchSampleData, child: const Text('发起请求'), ), ), // 监听活跃请求数,大于0时显示加载指示器 ValueListenableBuilder<int>( valueListenable: _trackedClient.activeRequests, builder: (context, count, child) { return count > 0 ? const Center(child: CircularProgressIndicator()) : const SizedBox.shrink(); }, ), ], ), ); } }
3. 关键注意事项
- 请求取消处理:如果需要支持请求取消(比如结合
CancelToken),要确保取消时同步减少计数器,避免计数异常。 - 全局状态共享:若多页面需要共用请求状态,可将
TrackedHttpClient设为全局单例,或通过状态管理库注入,避免重复实例化。 - 资源释放:务必在页面销毁或不再使用时调用
close()方法,关闭原始HttpClient以释放系统资源。
内容的提问来源于stack exchange,提问作者Dario Digregorio
相关产品推荐
相关产品推荐

