Flutter 中封装 Dio 网络请求的详细步骤

在 Flutter 中,通过封装 Dio 网络请求,可以将请求、响应处理和错误处理的逻辑集中在一起,减少代码重复并提升代码的可维护性。我们将在 RequestClient 类中创建一个通用的请求方法,支持 GET 和 POST 请求,并结合 EasyLoading 和 Lottie 动画,实现更好的用户体验。

步骤 1:创建 RequestConfig 基础配置类

首先定义请求的基本配置。RequestConfig 类负责存放 API 的 baseUrl、连接超时时间 connectTimeout 和请求的成功状态码 successCode 等配置项。这样便于在项目中统一管理和调整这些参数。

arduino 复制代码
class RequestConfig {
  static const String baseUrl = "https://example.com/api"; // API 根地址
  static const int connectTimeout = 5000; // 请求超时时间(毫秒)
  static const int successCode = 200; // API 成功返回的状态码
}

步骤 2:初始化 Dio 实例

创建一个 RequestClient 类用于封装 Dio 的实例。这个类的构造函数中,我们会为 Dio 设置基础选项(如 baseUrlconnectTimeout),并添加 pretty_dio_logger 插件,用于在控制台输出请求和响应的详细信息,方便调试。

kotlin 复制代码
import 'package:dio/dio.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';

class RequestClient {
  late Dio _dio;

  // 构造函数,配置 Dio 实例
  RequestClient() {
    _dio = Dio(
      BaseOptions(
        baseUrl: RequestConfig.baseUrl, // 请求的基础路径
        connectTimeout: RequestConfig.connectTimeout, // 超时时间
      ),
    );
    // 添加日志拦截器,方便调试
    _dio.interceptors.add(PrettyDioLogger(
      requestHeader: true,
      requestBody: true,
      responseHeader: true,
    ));
  }
}

步骤 3:封装通用的请求方法

RequestClient 类中创建一个 request 方法,该方法支持通用请求(GET 或 POST),接收请求路径、参数、以及是否显示加载动画等参数。方法的基本流程如下:

  1. 显示加载动画(可选)
  2. 发送请求并处理响应
  3. 捕获异常并调用错误处理函数
  4. 隐藏加载动画

以下是代码示例和逐步分析:

dart 复制代码
Future<T?> request<T>(
  String url, {
    String method = "GET", // 请求方法,默认为 GET
    Map<String, dynamic>? queryParameters, // 请求参数
    data, // 请求数据(POST 时使用)
    bool showLoading = true, // 是否显示加载动画
    bool Function(ApiException)? onError, // 错误回调函数
    Function()? onRequestComplete, // 请求完成后的回调函数
  }) async {
    // 1. 如果需要,显示加载动画
    if (showLoading) {
      Loading().showLoading();
    }
    
    try {
      // 2. 发送请求
      Response response = await _dio.request(
        url,
        queryParameters: queryParameters,
        data: data,
        options: Options(method: method),
      );

      // 3. 处理响应数据,返回给调用方
      T? result = _handleResponse<T>(response); 
      onRequestComplete?.call(); // 调用请求完成后的回调
      return result;

    } catch (e) {
      // 4. 捕获异常,处理错误
      if (onError?.call(ApiException.from(e)) != true) {
        handleException(ApiException.from(e));
      }
    } finally {
      // 5. 隐藏加载动画
      if (showLoading) {
        Loading().dismissLoading();
      }
    }
    return null;
  }
  • 参数说明:

    • url:请求的路径。
    • method:请求方法("GET" 或 "POST")。
    • queryParameters:GET 请求的查询参数。
    • data:POST 请求的数据。
    • showLoading:是否显示加载动画。
    • onError:自定义的错误处理函数。
    • onRequestComplete:请求完成时的回调。
  • 逻辑说明:

    • 调用 _dio.request() 发送请求,GET 请求使用 queryParameters,POST 请求则使用 data
    • 如果请求成功,调用 _handleResponse 来解析响应。
    • 请求失败时,将异常传递给自定义 onError 函数,如果未定义 onError,调用默认错误处理。

步骤 4:处理响应数据

_handleResponse 方法用于处理 API 返回的数据,解析并返回特定数据类型(如 JSON 或 Model)。

kotlin 复制代码
T _handleResponse<T>(Response response) {
  if (response.statusCode == RequestConfig.successCode) {
    // 假设返回的数据直接是 JSON,可根据实际情况解析
    return response.data;
  } else {
    throw ApiException('Error: ${response.statusCode}');
  }
}

注意 :这里根据 successCode 判断响应是否成功,并解析响应数据。如果返回的数据结构复杂,可在此方法中进一步解析。

步骤 5:错误处理

RequestClient 中添加 handleException 方法,用于捕获和处理错误,包括显示错误提示或执行自定义逻辑。

scss 复制代码
void handleException(ApiException e) {
  Loading().showErrorLoading(e.message); // 显示错误信息
}
  • 错误提示 :使用 Loading().showErrorLoading() 显示错误信息。
  • 异常捕获 :在 request 方法的 catch 块中调用 handleException,确保所有异常被捕获并处理。

步骤 6:加载动画与 Lottie 动画集成

Loading 类中的 showLoading 方法改为使用 Lottie 动画展示,给用户更友好的加载体验。

javascript 复制代码
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:lottie/lottie.dart';

class Loading {
  void showLoading() {
    EasyLoading.show(
      indicator: Lottie.asset('assets/loading_animation.json'),
      status: "加载中...",
    );
  }

  void showErrorLoading(String message) {
    EasyLoading.showError(message);
  }

  void dismissLoading() {
    EasyLoading.dismiss();
  }
}

总结与常见问题

通过以上步骤,我们实现了一个带有加载动画和错误处理的通用网络请求封装。在实际应用中,可以针对不同的业务需求和错误状态码进一步定制。

常见问题

  1. EasyLoading.init() 未初始化

    • 确保在 main.dartrunApp 之前调用 EasyLoading.init()
  2. 请求超时或连接失败

    • 调整 connectTimeout 或添加 retry 机制,提升请求稳定性。
  3. Lottie 动画无法加载

    • 检查动画文件路径是否正确,确保文件已经在项目中。

通过本文的讲解,你可以在 Flutter 项目中轻松实现网络请求的封装,并为用户提供更好的加载体验和错误提示。希望这篇文章对你有所帮助!

​代码地址:github.com/Larryzhang-...

相关推荐
迷雾漫步者39 分钟前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-1 小时前
验证码机制
前端·后端
燃先生._.2 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖3 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
m0_748235243 小时前
前端实现获取后端返回的文件流并下载
前端·状态模式
m0_748240254 小时前
前端如何检测用户登录状态是否过期
前端
black^sugar4 小时前
纯前端实现更新检测
开发语言·前端·javascript
寻找沙漠的人5 小时前
前端知识补充—CSS
前端·css
GISer_Jing5 小时前
2025前端面试热门题目——计算机网络篇
前端·计算机网络·面试