dio插件
- 优点:
- 功能丰富:支持取消请求、设置请求和响应拦截器,便于进行通用的网络处理,如添加公共请求头、统一处理响应错误等。
- 性能较好:内部对网络请求进行了优化,在连接管理等方面有不错的表现,能高效处理网络请求。
- 支持多种请求类型:不仅支持常见的GET、POST等,还支持上传下载等复杂操作,且对上传下载进度的监听很方便。
- 缺点:
- 相对复杂:对于简单的网络请求场景,引入dio可能会显得过于复杂,增加项目的学习成本和代码量。
- 依赖较多:相比一些轻量级的网络请求插件,dio依赖的库和资源更多。
http插件
- 优点:
- 轻量级:是Flutter官方提供的基础网络请求库,轻量级且易于使用,对于简单的网络请求,上手快,代码简洁。
- 稳定性好:基于官方维护,与Flutter框架的兼容性较好,稳定性有保障。
- 缺点:
- 功能有限:相较于dio,缺少如请求取消、拦截器等高级功能,在复杂的网络场景下,需要开发者自行实现相关功能。
- 性能优化有限:在处理复杂网络请求和大量并发请求时,没有像dio那样进行较多的性能优化。
根据项目需求选择插件与async/await配合
- 简单项目:如果项目只是简单的获取数据,对功能要求不高,优先选择http插件。配合async/await使用时,通过
http.get
等方法发起请求,await
等待请求完成并处理响应数据,例如:
import 'package:http/http.dart' as http;
Future<String> fetchData() async {
var response = await http.get(Uri.parse('https://example.com/api/data'));
if (response.statusCode == 200) {
return response.body;
} else {
throw Exception('Failed to load data');
}
}
- 复杂项目:若项目对功能特性要求较高,如需要拦截器、请求取消等功能,选择dio插件。使用async/await时,类似如下代码:
import 'package:dio/dio.dart';
Future<String> fetchData() async {
Dio dio = Dio();
try {
var response = await dio.get('https://example.com/api/data');
return response.data.toString();
} catch (e) {
throw Exception('Failed to load data: $e');
}
}
对网络请求并发控制有较高要求时网络请求模块的设计
- 使用Dio的队列功能:dio可以通过创建
Dio
实例的方式,并利用Dio
的Interceptors
实现请求队列。在拦截器中,控制请求的发送频率,达到并发控制的目的。例如:
import 'package:dio/dio.dart';
class RequestThrottle {
int maxConcurrent = 2;
int currentCount = 0;
Queue<RequestOptions> requestQueue = Queue<RequestOptions>();
void enqueue(RequestOptions options) {
requestQueue.add(options);
_processQueue();
}
void _processQueue() {
if (currentCount < maxConcurrent && requestQueue.isNotEmpty) {
currentCount++;
var options = requestQueue.removeFirst();
Dio().fetch(options).then((response) {
currentCount--;
_processQueue();
}).catchError((e) {
currentCount--;
_processQueue();
});
}
}
}
- 使用
Future.wait
结合计数器:通过Future.wait
将多个网络请求放入列表中,同时使用一个计数器来控制并发数量。例如:
import 'package:http/http.dart' as http;
Future<List<http.Response>> fetchDataList(List<Uri> urls) async {
int maxConcurrent = 2;
List<Future<http.Response>> futures = [];
List<http.Response> responses = [];
int currentIndex = 0;
void _processNext() {
while (futures.length < maxConcurrent && currentIndex < urls.length) {
futures.add(http.get(urls[currentIndex]));
currentIndex++;
}
Future.wait(futures).then((result) {
responses.addAll(result);
futures.clear();
if (currentIndex < urls.length) {
_processNext();
}
});
}
_processNext();
return responses;
}