Flutter网络请求进阶:基于Dio的封装实践指南
2026.02.09 14:54浏览量:0简介:本文详细讲解如何在Flutter项目中通过Dio库封装高性能网络工具,包含基础请求实现、自定义配置管理、拦截器机制等核心模块。通过标准化封装提升代码复用性,降低维护成本,特别适合需要统一管理网络请求的中大型项目开发场景。
一、Dio基础能力解析
Dio作为Flutter生态中最流行的HTTP客户端库,其核心优势在于支持多种请求类型、拦截器机制和全局配置管理。在开始封装前,我们需要掌握其基础用法:
1.1 环境配置与依赖管理
在pubspec.yaml中添加依赖时,建议锁定次要版本号以确保稳定性:
dependencies:dio: ^5.3.2 # 推荐使用稳定版本
1.2 基础请求实现
GET请求示例
Future<void> fetchData() async {try {final dio = Dio();final response = await dio.get('https://api.example.com/posts/1',options: Options(receiveTimeout: Duration(seconds: 5),),);print('Response: ${response.data}');} catch (e) {if (e is DioException) {print('Error type: ${e.type}');print('Error message: ${e.message}');}}}
POST请求示例
Future<void> postData() async {try {final dio = Dio();final data = {'title': 'Flutter Guide','body': 'Dio封装实践','userId': 1001};final response = await dio.post('https://api.example.com/posts',data: data,options: Options(contentType: Headers.formUrlEncodedContentType,),);print('Created ID: ${response.data['id']}');} catch (e) {// 错误处理逻辑}}
二、核心封装策略
2.1 请求配置标准化
通过自定义RequestOptions实现配置集中管理:
enum RequestMethod { get, post, put, delete }class NetworkConfig {static const String baseUrl = 'https://api.example.com';static const Duration connectTimeout = Duration(seconds: 10);static const Duration receiveTimeout = Duration(seconds: 8);static Map<String, String> defaultHeaders = {'Accept': 'application/json','Content-Type': 'application/json',};}class CustomRequestOptions {final RequestMethod method;final String endpoint;final Map<String, dynamic>? queryParams;final Map<String, dynamic>? bodyParams;final Map<String, String>? customHeaders;CustomRequestOptions({this.method = RequestMethod.get,required this.endpoint,this.queryParams,this.bodyParams,this.customHeaders,});String get fullUrl => '${NetworkConfig.baseUrl}$endpoint';}
2.2 Dio实例封装
创建可复用的Dio实例工厂:
class DioClient {final Dio _dio;DioClient._internal() : _dio = _createDioInstance();static final DioClient _instance = DioClient._internal();factory DioClient() => _instance;static Dio _createDioInstance() {final dio = Dio(BaseOptions(baseUrl: NetworkConfig.baseUrl,connectTimeout: NetworkConfig.connectTimeout,receiveTimeout: NetworkConfig.receiveTimeout,headers: NetworkConfig.defaultHeaders,));// 添加拦截器dio.interceptors.addAll([LogInterceptor(responseBody: true), // 开发环境日志ErrorInterceptor(), // 统一错误处理RetryInterceptor(), // 自动重试机制]);return dio;}Future<Response<T>> request<T>(CustomRequestOptions options) async {try {final requestOptions = _buildRequestOptions(options);Response response;switch (options.method) {case RequestMethod.get:response = await _dio.get(options.endpoint, queryParameters: options.queryParams);break;case RequestMethod.post:response = await _dio.post(options.endpoint, data: options.bodyParams);break;// 其他方法实现...default:throw UnsupportedError('Unsupported request method');}return _handleResponse(response);} catch (e) {_handleError(e);rethrow;}}// 其他辅助方法...}
2.3 拦截器实现
日志拦截器
class LogInterceptor extends Interceptor {final bool responseBody;LogInterceptor({this.responseBody = false});@overridevoid onRequest(RequestOptions options, RequestInterceptorHandler handler) {print('--> ${options.method} ${options.uri}');print('Headers: ${options.headers}');print('Body: ${options.data}');super.onRequest(options, handler);}@overridevoid onResponse(Response response, ResponseInterceptorHandler handler) {print('<-- ${response.statusCode} ${response.requestOptions?.uri}');if (responseBody) {print('Body: ${response.data}');}super.onResponse(response, handler);}}
错误处理拦截器
class ErrorInterceptor extends Interceptor {@overridevoid onError(DioException err, ErrorInterceptorHandler handler) {final errorMessage = _parseError(err);print('Network Error: $errorMessage');// 根据错误类型返回特定状态码switch (err.type) {case DioExceptionType.connectionTimeout:case DioExceptionType.receiveTimeout:// 处理超时错误break;case DioExceptionType.badResponse:// 处理服务器错误break;default:// 处理其他错误break;}super.onError(err, handler);}String _parseError(DioException err) {if (err.response != null) {return '${err.response?.statusCode}: ${err.response?.data}';}return err.message ?? 'Unknown error';}}
三、高级功能扩展
3.1 自动重试机制
class RetryInterceptor extends Interceptor {static const int maxRetries = 3;static const Duration retryDelay = Duration(milliseconds: 500);@overridevoid onError(DioException err, ErrorInterceptorHandler handler) async {if (shouldRetry(err)) {int retryCount = 0;while (retryCount < maxRetries) {try {await Future.delayed(retryDelay * (retryCount + 1));final response = await err.requestOptions?.followUp(err.response);if (response != null) {return handler.resolve(response);}} catch (e) {retryCount++;}}}handler.next(err);}bool shouldRetry(DioException err) {return err.type == DioExceptionType.connectionTimeout ||err.type == DioExceptionType.receiveTimeout ||(err.response?.statusCode == 502 ||err.response?.statusCode == 503 ||err.response?.statusCode == 504);}}
3.2 请求缓存策略
class CacheInterceptor extends Interceptor {final Map<String, Response> _cache = {};final Duration maxCacheAge;CacheInterceptor({this.maxCacheAge = const Duration(minutes: 5)});@overridevoid onRequest(RequestOptions options, RequestInterceptorHandler handler) {final cacheKey = options.uri.toString();final cachedResponse = _cache[cacheKey];if (cachedResponse != null) {final isExpired = DateTime.now().difference(cachedResponse.extra?['cachedAt'] ?? DateTime(0)).compareTo(maxCacheAge) > 0;if (!isExpired) {handler.resolve(cachedResponse);return;}}super.onRequest(options, handler);}@overridevoid onResponse(Response response, ResponseInterceptorHandler handler) {final cacheKey = response.requestOptions?.uri.toString();if (response.requestOptions?.extra?['cache'] == true) {_cache[cacheKey] = response.copyWith(extra: {...response.extra,'cachedAt': DateTime.now(),},);}super.onResponse(response, handler);}}
四、最佳实践建议
- 环境区分配置:通过
BuildConfig区分开发/测试/生产环境配置 - 统一错误处理:建立全局错误码映射表,规范错误提示
- 性能监控:集成网络请求耗时统计和成功率监控
- Mock数据支持:开发阶段通过拦截器返回本地JSON文件
- 取消请求管理:使用
CancelToken管理页面卸载时的请求取消
完整封装后的网络工具应具备以下特性:
- 类型安全的请求方法定义
- 统一的错误处理机制
- 灵活的配置覆盖能力
- 可扩展的拦截器体系
- 完善的日志记录系统
这种封装方式在多个中大型项目中验证有效,可显著提升网络请求模块的可维护性,特别适合需要统一管理API调用的业务场景。实际开发中可根据项目需求进一步扩展功能模块,如添加JWT认证、请求频率限制等特性。

发表评论
登录后可评论,请前往 登录 或 注册