当前位置:网站首页>Flutter实战-请求封装(二)之dio
Flutter实战-请求封装(二)之dio
2022-07-29 04:23:00 【蓝面书生】

用了两年的flutter,有了一些心得,不虚头巴脑,只求实战有用,以供学习或使用flutter的小伙伴参考,学习尚浅,如有不正确的地方还望各路大神指正,以免误人子弟,在此拜谢~(原创不易,转发请标注来源和作者)
注意:无特殊说明,flutter版本为3.0+
上篇总结了api的组织结构,这一篇我们探讨一下Flutter 常用请求库Dio的使用和封装。
一.dio
一般http请求我们要关注的点有如下几个:
访问路径,请求方式,请求头部,请求参数,超时时间,返回结果,返回类型等。
注:(对http/https协议不太明白的,需要补课的童鞋可以去看下基础教程https://www.runoob.com/http/http-tutorial.html)
首先看下dio可配置的参数:
BaseOptions({
String? method,
int? connectTimeout,
int? receiveTimeout,
int? sendTimeout,
String baseUrl = '',
Map<String, dynamic>? queryParameters,
Map<String, dynamic>? extra,
Map<String, dynamic>? headers,
ResponseType? responseType = ResponseType.json,
String? contentType,
ValidateStatus? validateStatus,
bool? receiveDataWhenStatusError,
bool? followRedirects,
int? maxRedirects,
RequestEncoder? requestEncoder,
ResponseDecoder? responseDecoder,
ListFormat? listFormat,
this.setRequestContentTypeWhenNoPayload = false,
})
除了基础配置dio还提供了拦截器interceptors,适配器httpClientAdapter,请求方法get,post,delete,put,patch,download等基础的封装,方便我们使用。
二.Http 基础类
class Http {
///定义各类超时时间
static const int CONNECT_TIMEOUT = 10000; // 默认设置10s超时
static const int RECEIVE_TIMEOUT = 3000;
static const int SEND_TIMEOUT = 3000;
Dio? dio;
static Http _instance = Http._internal();
1._internal()获取Dio实例的方法,主要是配置适配器
Http._internal() {
dio = Dio();dio.httpClientAdapter = DefaultHttpClientAdapter()
..onHttpClientCreate = (HttpClient c,lient) {
client.idleTimeout = Duration(milliseconds: CONNECT_TIMEOUT);
};// 添加错误统一处理拦截器
dio!.interceptors.add(ErrorInterceptor());//添加日志拦截器
dio!.interceptors.add(DioLogInterceptor());
2.post方法源码示例
Future post(
String path, {
required String baseUrl,
Map<String, dynamic>? params,
Map<String, dynamic>? headers,
data,
Options? options,
CancelToken? cancelToken,
}) async {
Options requestOptions = options ?? Options();
//requestOptions.baseUrl = baseUrl;
Map<String, dynamic>? _authorization = headers ?? getAuthorizationHeader();
if (_authorization != null) {
requestOptions = requestOptions.copyWith(headers: _authorization);
}
dio!.options.baseUrl = baseUrl;
dio!.options.connectTimeout = CONNECT_TIMEOUT;
dio!.options.receiveTimeout = RECEIVE_TIMEOUT;
dio!.options.sendTimeout = SEND_TIMEOUT;
var response;
var timeout = Duration(milliseconds: dio!.options.connectTimeout);
cancelToken = CancelToken();
var t = Timer(timeout, () {
if (response == null) {
cancelToken!.cancel();
}
});
response =
await dio!.post(path, data: data, queryParameters: params, options: requestOptions, cancelToken: cancelToken);
t.cancel();
return response.data;
}
cancelToken 是dio提供的一个非常有用的东西,可以主动在返回超时时候,主动结束请求,并触发DioErrorType.cancel的错误事件。
三.httpUtils 加强封装
1.添加是否等待处理
还以post为例,我们定义一个方法调用http的基础类
static Future post(String path,{data,required String baseUrl,
Map<String, dynamic>? params,
Options? options,
CancelToken? cancelToken,
bool showLoading = false}
这里加了一个参数showLoading,在我们实际开发过程中,有一些操作要阻断用户操作,等待接口请求,一些是不需要用户感知的请求,我们可以在所有api中,默认添加该参数为false,有必要阻断用户的时候调用的时候将该参数设置成为true,举个例子如下:
/// 忘记密码
static Future<String> forgetPassword(dynamic param, { bool showLoading= false}) async {
var res = await HttpUtils.post(_forgetPassword, data: param, baseUrl: "xxx" showLoading: showLoading);
return res;
}
当判断需要loading 的时候
if (showLoading) {
showLoadingDialog();
}
作者使用的是flutter_smart_dialog: ^4.5.3+7,使用比较简单,你可以自己去封装所需要的loading样式。
2.定义统一返回类型
class ApiResponse<T> implements Exception {
String? errorMsg;
String? msg;
int? code;
T? data;
ApiResponse(this.msg);
ApiResponse.error(String msg) {
toastMsg(msg);
}
@override
String toString() {
return "Msg : $msg \n errorMsg : $errorMsg \n Data : $data";
}
ApiResponse.fromJson(Map<String, dynamic> json) {
msg = json['msg'];
errorMsg = json['errorMsg'];
code = json['code'];
data = json['data'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['msg'] = this.msg;
data['errorMsg'] = this.errorMsg;
data['code'] = this.code;
data['data'] = this.data;
return data;
}
}
3.返回处理
判断后台返回的正确code,则返回结果,完结后清除loading状态。
源码如下
class HttpUtils {
static Future post(String path,
{data,
required String baseUrl,
Map<String, dynamic>? params,
Options? options,
CancelToken? cancelToken,
bool showLoading = false,
bool canNull = false,
Function(Object?)? onError,
bool errorToast = true,
bool isolate = true}) async {
if (showLoading) {
showLoadingDialog(path: path);
}
return Http()
.post(
path,
baseUrl: baseUrl,
data: data,
params: params,
options: options,
cancelToken: cancelToken,
)
.then((value) {
var result = ApiResponse.fromJson(value is Map ? value : jsonDecode(value));
if (result.code == 2000) {
return result.data;
} else {
throw ApiResponse(result.msg!);
}
}).onError((error, stackTrace) {
if (onError != null) {
onError(error);
}
if (error is RemoteError) {
toastMsg("网络连接失败", displayType: SmartToastType.last);
} else if (error is ApiResponse) {
toastMsg(error.msg!);
} else {
toastMsg("未知错误");
}
throw Exception(error.toString());
}). whenComplete(() {
if (showLoading) {
SmartDialog.dismiss();
}
});}
边栏推荐
- Don't stick to it for 68 days. Baboons eat bananas
- 开课!看smardaten如何分解复杂业务场景
- Wechat applet parameter transfer
- Taobao product details interface (product details page data interface)
- Down sampling and up sampling
- C language: enumerating knowledge points summary
- 顺序表和链表
- Kotlin's list, map, set and other collection classes do not specify types
- Why do I delete the original record (OP d) and then add a new one in Kafka when I update MySQL data
- Not for 63 days. The biggest XOR
猜你喜欢

6. Pytest generates an allure Report

Visio draw grid

RMAN do not mark expired backups

Don't insist on 66 days. Weight generates random numbers

Why are there so many unknowns when opengauss starts?

论pyscript使用感想(实现office预览)

The third ACM program design competition of Wuhan University of Engineering

Deep learning training strategy -- warming up the learning rate

Realize the effect of univariate quadratic equation through JS. Enter the coefficients of a, B and C to calculate the values of X1 and x2

Back propagation process of manual BP neural network
随机推荐
Interview notes of a company
Fuzzy query of SQL
Jenkins 参数化构建中 各参数介绍与示例
不会就坚持67天吧 平方根
SQL time fuzzy query datediff() function
leetcode 686.重复叠加字符串 KMP方法(C语言实现)
Cad2020 introductory learning (2021.4.13)
小程序:区域滚动、下拉刷新、上拉加载更多
索引的最左前缀原理
Openfeign asynchronous call problem
Introduction and examples of parameters in Jenkins parametric construction
Won't you just stick to 69 days? Merge range
LeetCode_ Stack topics
通过js来实现一元二次方程的效果,输入a,b,c系数后可计算出x1和x2的值
不会就坚持62天吧 单词之和
数据库SQL语句实现数据分解的函数查询
C语言:浅谈各种复杂的声明
The function "postgis_version" cannot be found when installing PostGIS
从淘宝,天猫,1688,微店,京东,苏宁,淘特等其他平台一键复制商品到拼多多平台(批量上传宝贝详情接口教程)
Machine vision series 3:vs2019 opencv environment configuration