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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 17:57:12