在 Flutter 中,通过封装 Dio 网络请求,可以将请求、响应处理和错误处理的逻辑集中在一起,减少代码重复并提升代码的可维护性。我们将在 RequestClient
类中创建一个通用的请求方法,支持 GET 和 POST 请求,并结合 EasyLoading 和 Lottie 动画,实现更好的用户体验。
RequestConfig
基础配置类首先定义请求的基本配置。RequestConfig
类负责存放 API 的 baseUrl
、连接超时时间 connectTimeout
和请求的成功状态码 successCode
等配置项。这样便于在项目中统一管理和调整这些参数。
class RequestConfig {
static const String baseUrl = "https://example.com/api"; // API 根地址
static const int connectTimeout = 5000; // 请求超时时间(毫秒)
static const int successCode = 200; // API 成功返回的状态码
}
创建一个 RequestClient
类用于封装 Dio 的实例。这个类的构造函数中,我们会为 Dio 设置基础选项(如 baseUrl
和 connectTimeout
),并添加 pretty_dio_logger
插件,用于在控制台输出请求和响应的详细信息,方便调试。
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,
));
}
}
在 RequestClient
类中创建一个 request
方法,该方法支持通用请求(GET 或 POST),接收请求路径、参数、以及是否显示加载动画等参数。方法的基本流程如下:
以下是代码示例和逐步分析:
Future request(
String url, {
String method = "GET", // 请求方法,默认为 GET
Map? 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(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
,调用默认错误处理。_handleResponse
方法用于处理 API 返回的数据,解析并返回特定数据类型(如 JSON 或 Model)。
T _handleResponse(Response response) {
if (response.statusCode == RequestConfig.successCode) {
// 假设返回的数据直接是 JSON,可根据实际情况解析
return response.data;
} else {
throw ApiException('Error: ${response.statusCode}');
}
}
注意:这里根据 successCode
判断响应是否成功,并解析响应数据。如果返回的数据结构复杂,可在此方法中进一步解析。
在 RequestClient
中添加 handleException
方法,用于捕获和处理错误,包括显示错误提示或执行自定义逻辑。
void handleException(ApiException e) {
Loading().showErrorLoading(e.message); // 显示错误信息
}
Loading().showErrorLoading()
显示错误信息。request
方法的 catch
块中调用 handleException
,确保所有异常被捕获并处理。将 Loading
类中的 showLoading
方法改为使用 Lottie 动画展示,给用户更友好的加载体验。
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();
}
}
通过以上步骤,我们实现了一个带有加载动画和错误处理的通用网络请求封装。在实际应用中,可以针对不同的业务需求和错误状态码进一步定制。
EasyLoading.init()
未初始化
main.dart
的 runApp
之前调用 EasyLoading.init()
。请求超时或连接失败
connectTimeout
或添加 retry
机制,提升请求稳定性。Lottie 动画无法加载
通过本文的讲解,你可以在 Flutter 项目中轻松实现网络请求的封装,并为用户提供更好的加载体验和错误提示。希望这篇文章对你有所帮助!
代码地址:https://github.com/Larryzhang-S/flutter_request