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-...

相关推荐
大叔是90后大叔几秒前
vue3中查找字典列表中某个元素的值对应的列表索引值
开发语言·前端·javascript
Greg_Zhong3 分钟前
Angular 和 Vue2.0 对比
前端·angular·vue 2
Tttian62211 分钟前
Vue全栈开发旅游网项目(11)-用户管理前端接口联调
前端·vue.js·django
清尘沐歌17 分钟前
前端开发快速进行 Mock 数据的方法
前端·mock
kali-Myon18 分钟前
ctfshow-web入门-SSTI(web361-web368)上
前端·python·学习·安全·web安全·web
Mr.E520 分钟前
odoo17 owl 前端 顶部导航栏右侧添加自定义按钮
前端·odoo·odoo17·owl
小小靖大王1 小时前
js 基础语法 书写方式
开发语言·前端·javascript
Hacker_Oldv1 小时前
【网络工程】计算机硬件概述
前端·网络·安全·web安全
龙猫蓝图2 小时前
vue el-date-picker 日期选择 回显后成功后无法改变的解决办法
前端·javascript·vue.js