dio_client.dart 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import 'dart:io';
  2. import 'package:connectivity_plus/connectivity_plus.dart';
  3. import 'package:dio/dio.dart';
  4. import 'package:flutter/cupertino.dart';
  5. //import 'custom_interceptors.dart';
  6. class DioClient {
  7. static final DioClient _instance = DioClient._internal();
  8. late Dio _dio;
  9. factory DioClient() => _instance;
  10. DioClient._internal() {
  11. _dio = Dio(BaseOptions(
  12. baseUrl: 'https://api.example.com', // 你的API地址
  13. connectTimeout: 5000,
  14. receiveTimeout: 3000,
  15. ));
  16. // 添加拦截器
  17. _dio.interceptors.add(CustomInterceptors());
  18. }
  19. Dio get dio => _dio;
  20. }
  21. class CustomInterceptors extends Interceptor {
  22. int _retryCount = 0;
  23. final List<String> _backupUrls = ['备用地址1', '备用地址2'];
  24. Future<bool> isConnected() async {
  25. var connectivityResult = await (Connectivity().checkConnectivity());
  26. return connectivityResult != ConnectivityResult.none;
  27. }
  28. @override
  29. Future<void> onError(DioError err, ErrorInterceptorHandler handler) async {
  30. // 检查网络连接状态
  31. bool isConnectNetWork = await isConnected();
  32. if (!isConnectNetWork) {
  33. // 无网络连接,设置友好的错误消息
  34. err.error = AppException(message: "当前网络不可用,请检查您的网络");
  35. return handler.next(err);
  36. } else if (err.error is SocketException || err.type == DioErrorType.other) {
  37. if (_retryCount < _backupUrls.length) {
  38. // 有网络连接但请求失败,尝试使用备用地址
  39. err.requestOptions.baseUrl = _backupUrls[_retryCount];
  40. _retryCount++;
  41. try {
  42. final Dio dio = Dio();
  43. final Response response = await dio.request<dynamic>(
  44. err.requestOptions.path,
  45. cancelToken: err.requestOptions.cancelToken,
  46. data: err.requestOptions.data,
  47. onReceiveProgress: err.requestOptions.onReceiveProgress,
  48. onSendProgress: err.requestOptions.onSendProgress,
  49. queryParameters: err.requestOptions.queryParameters,
  50. options: Options(
  51. method: err.requestOptions.method,
  52. headers: err.requestOptions.headers,
  53. contentType: err.requestOptions.contentType,
  54. responseType: err.requestOptions.responseType,
  55. ),
  56. );
  57. return handler.resolve(response);
  58. } catch (e) {
  59. return handler.next(err);
  60. }
  61. }
  62. }
  63. // 其他错误,统一处理
  64. AppException appException = AppException.create(err);
  65. debugPrint('DioError===: ${appException.toString()}');
  66. err.error = appException;
  67. return handler.next(err);
  68. }
  69. }
  70. class AppException implements Exception {
  71. final String message;
  72. AppException({required this.message});
  73. static AppException create(DioError err) {
  74. switch (err.type) {
  75. case DioErrorType.cancel:
  76. return AppException(message: '请求被取消');
  77. case DioErrorType.connectTimeout:
  78. return AppException(message: '连接超时');
  79. case DioErrorType.sendTimeout:
  80. return AppException(message: '请求超时');
  81. case DioErrorType.receiveTimeout:
  82. return AppException(message: '响应超时');
  83. case DioErrorType.response:
  84. return AppException(
  85. message: '服务器返回异常,状态码:${err.response?.statusCode}',
  86. );
  87. case DioErrorType.other:
  88. return AppException(
  89. message: '未知错误: ${err.message}',
  90. );
  91. default:
  92. return AppException(
  93. message: err.message,
  94. );
  95. }
  96. }
  97. @override
  98. String toString() {
  99. return message;
  100. }
  101. }