使用Dio三方库实现Flutter强大网络请求
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net在Flutter开发中,Dio是最受欢迎的HTTP客户端库之一。它提供了强大的功能,包括拦截器全局配置文件上传下载请求取消超时控制等。本文将详细介绍如何使用Dio三方库进行Flutter网络开发。提示:Dio支持全局配置、拦截器、FormData、请求取消、文件上传下载、超时控制、自定义适

前言
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
在Flutter开发中,Dio是最受欢迎的HTTP客户端库之一。它提供了强大的功能,包括拦截器、全局配置、文件上传下载、请求取消、超时控制等。本文将详细介绍如何使用Dio三方库进行Flutter网络开发。
提示:Dio支持全局配置、拦截器、FormData、请求取消、文件上传下载、超时控制、自定义适配器等强大功能。
一、Dio三方库简介
1.1 什么是Dio
Dio是一个强大的Dart/Flutter HTTP网络库,由中国Flutter社区(CFUG)维护。它提供了简洁的API和丰富的功能,是Flutter开发中最常用的网络请求库。
| 特性 | 说明 | 优势 |
|---|---|---|
| 全局配置 | 统一管理baseUrl、超时等 | 减少重复配置 |
| 拦截器 | 请求/响应拦截处理 | 统一认证、日志 |
| 文件操作 | 上传下载文件 | 支持进度监听 |
| 请求取消 | 取消正在进行的请求 | 避免资源浪费 |
| 错误处理 | 统一的异常处理机制 | 简化错误处理 |
| 转换器 | 自定义数据转换 | 灵活处理数据 |
官方文档:https://pub.dev/packages/dio
GitHub仓库:https://github.com/cfug/dio
1.2 Dio核心概念
Dio包含以下核心组件:
- Dio实例:HTTP客户端核心对象
- BaseOptions:全局配置选项
- Interceptor:拦截器(请求/响应/错误)
- Transformer:数据转换器
- HttpClientAdapter:HTTP客户端适配器
- CancelToken:请求取消令牌
提示:建议在项目中使用单例模式管理Dio实例,统一配置和管理网络请求。
1.3 Dio vs 其他HTTP库
| 库名 | 功能丰富度 | 易用性 | 性能 | 社区活跃度 |
|---|---|---|---|---|
| Dio | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Http | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| Chopper | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
二、环境配置与依赖安装
2.1 添加依赖
在pubspec.yaml文件中添加Dio依赖:
dependencies:
dio: ^5.4.0
2.2 安装依赖
执行以下命令安装依赖:
flutter pub get
相关资源链接:
- Dio Package:https://pub.dev/packages/dio
- 官方文档:https://pub.dev/documentation/dio/latest/
- GitHub仓库:https://github.com/cfug/dio
2.3 导入包
在Dart文件中导入Dio:
import 'package:dio/dio.dart';
三、基础使用
3.1 创建Dio实例
最简单的使用方式:
final dio = Dio();
void getHttp() async {
final response = await dio.get('https://dart.dev');
print(response.data);
}
3.2 配置BaseOptions
创建带配置的Dio实例:
final dio = Dio(
BaseOptions(
baseUrl: 'https://api.example.com',
connectTimeout: Duration(seconds: 5),
receiveTimeout: Duration(seconds: 3),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
),
);
BaseOptions配置项:
| 配置项 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| baseUrl | Uri | 基础URL | - |
| connectTimeout | Duration | 连接超时 | null |
| receiveTimeout | Duration | 接收超时 | null |
| sendTimeout | Duration | 发送超时 | null |
| headers | Map | 请求头 | {} |
| responseType | ResponseType | 响应类型 | json |
| contentType | String | 内容类型 | application/json |
3.3 修改配置
可以随时修改Dio实例的配置:
dio.options.baseUrl = 'https://api.example.com';
dio.options.connectTimeout = Duration(seconds: 5);
dio.options.receiveTimeout = Duration(seconds: 3);
四、发起请求
4.1 GET请求
基础GET请求:
// 方式1:直接传递查询参数
final response = await dio.get('/test?id=12&name=dio');
print(response.data);
// 方式2:使用queryParameters
final response = await dio.get(
'/test',
queryParameters: {'id': 12, 'name': 'dio'},
);
print(response.data);
4.2 POST请求
发送POST请求:
final response = await dio.post(
'/test',
data: {'id': 12, 'name': 'dio'},
);
print(response.data);
4.3 其他HTTP方法
Dio支持所有HTTP方法:
// PUT请求
await dio.put('/user/12', data: {'name': 'dio'});
// DELETE请求
await dio.delete('/user/12');
// PATCH请求
await dio.patch('/user/12', data: {'name': 'dio'});
// HEAD请求
await dio.head('/test');
4.4 并发请求
使用Future.wait执行多个并发请求:
final responses = await Future.wait([
dio.post('/info'),
dio.get('/token'),
dio.get('/user'),
]);
print(responses[0].data);
print(responses[1].data);
print(responses[2].data);
五、Response对象
5.1 Response属性
Response对象包含以下属性:
final response = await dio.get('https://api.example.com/data');
// 响应数据
print(response.data);
// 状态码
print(response.statusCode); // 200
// 状态消息
print(response.statusMessage); // OK
// 响应头
print(response.headers);
// 请求配置
print(response.requestOptions);
// 是否重定向
print(response.isRedirect);
// 重定向记录
print(response.redirects);
5.2 响应类型
Dio支持多种响应类型:
| 响应类型 | 说明 | 使用场景 |
|---|---|---|
| ResponseType.json | JSON数据 | API接口 |
| ResponseType.plain | 纯文本 | HTML页面 |
| ResponseType.bytes | 字节数组 | 图片、文件 |
| ResponseType.stream | 流式数据 | 大文件下载 |
// 获取字节数据
final rs = await dio.get<List<int>>(
url,
options: Options(responseType: ResponseType.bytes),
);
print(rs.data); // List<int>
// 获取流数据
final rs = await dio.get(
url,
options: Options(responseType: ResponseType.stream),
);
print(rs.data.stream); // Stream
5.3 泛型支持
使用泛型指定响应数据类型:
final response = await dio.get<Map<String, dynamic>>('/user');
final userData = response.data; // Map<String, dynamic>
final response = await dio.get<List<int>>(
'/image',
options: Options(responseType: ResponseType.bytes),
);
final imageBytes = response.data; // List<int>
六、拦截器详解
6.1 拦截器概念
拦截器可以在请求发送前、响应接收后、错误发生时进行拦截处理。
![拦截器工作流程占位图 - 展示请求、响应、错误三个拦截点]
拦截器执行顺序:
- 请求拦截器(onRequest)
- 发送HTTP请求
- 响应拦截器(onResponse)或错误拦截器(onError)
6.2 添加拦截器
使用InterceptorsWrapper添加拦截器:
dio.interceptors.add(
InterceptorsWrapper(
onRequest: (options, handler) {
// 请求前处理
print('REQUEST[${options.method}] => PATH: ${options.path}');
return handler.next(options);
},
onResponse: (response, handler) {
// 响应后处理
print('RESPONSE[${response.statusCode}] => DATA: ${response.data}');
return handler.next(response);
},
onError: (error, handler) {
// 错误处理
print('ERROR[${error.response?.statusCode}] => MESSAGE: ${error.message}');
return handler.next(error);
},
),
);
6.3 自定义拦截器
继承Interceptor类创建自定义拦截器:
class CustomInterceptor extends Interceptor {
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
print('REQUEST[${options.method}] => PATH: ${options.path}');
super.onRequest(options, handler);
}
void onResponse(Response response, ResponseInterceptorHandler handler) {
print('RESPONSE[${response.statusCode}] => PATH: ${response.requestOptions.path}');
super.onResponse(response, handler);
}
void onError(DioException err, ErrorInterceptorHandler handler) {
print('ERROR[${err.response?.statusCode}] => PATH: ${err.requestOptions.path}');
super.onError(err, handler);
}
}
// 使用自定义拦截器
dio.interceptors.add(CustomInterceptor());
6.4 认证拦截器
实现自动添加Token的拦截器:
class AuthInterceptor extends Interceptor {
final String token;
AuthInterceptor(this.token);
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
options.headers['Authorization'] = 'Bearer $token';
super.onRequest(options, handler);
}
}
dio.interceptors.add(AuthInterceptor('your_token_here'));
6.5 LogInterceptor
使用内置的日志拦截器:
dio.interceptors.add(
LogInterceptor(
request: true,
requestHeader: true,
requestBody: true,
responseHeader: true,
responseBody: true,
error: true,
logPrint: (o) => print(o),
),
);
6.6 QueuedInterceptor
顺序执行的拦截器(适用于需要异步操作的场景):
class TokenInterceptor extends QueuedInterceptor {
void onRequest(RequestOptions options, RequestInterceptorHandler handler) async {
// 异步获取token
final token = await getToken();
options.headers['Authorization'] = 'Bearer $token';
handler.next(options);
}
}
dio.interceptors.add(TokenInterceptor());
七、错误处理
7.1 DioException
Dio将所有错误包装为DioException:
try {
await dio.get('https://api.example.com/not-exist');
} on DioException catch (e) {
if (e.response != null) {
// 服务器返回错误响应
print('Status: ${e.response?.statusCode}');
print('Data: ${e.response?.data}');
print('Headers: ${e.response?.headers}');
} else {
// 请求发送失败
print('Error: ${e.message}');
}
}
7.2 DioExceptionType
DioException包含多种错误类型:
| 错误类型 | 说明 | 常见原因 |
|---|---|---|
| connectionTimeout | 连接超时 | 网络不稳定 |
| sendTimeout | 发送超时 | 上传大文件 |
| receiveTimeout | 接收超时 | 服务器响应慢 |
| badResponse | 错误响应 | 4xx/5xx状态码 |
| cancel | 请求取消 | 主动取消 |
| connectionError | 连接错误 | 无网络连接 |
| unknown | 未知错误 | 其他异常 |
try {
await dio.get('/test');
} on DioException catch (e) {
switch (e.type) {
case DioExceptionType.connectionTimeout:
print('连接超时');
break;
case DioExceptionType.sendTimeout:
print('发送超时');
break;
case DioExceptionType.receiveTimeout:
print('接收超时');
break;
case DioExceptionType.badResponse:
print('错误响应: ${e.response?.statusCode}');
break;
case DioExceptionType.cancel:
print('请求取消');
break;
case DioExceptionType.connectionError:
print('连接错误');
break;
case DioExceptionType.unknown:
print('未知错误: ${e.message}');
break;
}
}
7.3 统一错误处理
创建错误处理拦截器:
class ErrorInterceptor extends Interceptor {
void onError(DioException err, ErrorInterceptorHandler handler) {
switch (err.type) {
case DioExceptionType.connectionTimeout:
case DioExceptionType.sendTimeout:
case DioExceptionType.receiveTimeout:
// 显示超时提示
showToast('请求超时,请稍后重试');
break;
case DioExceptionType.badResponse:
// 根据状态码处理
handleStatusCode(err.response?.statusCode);
break;
case DioExceptionType.cancel:
// 请求取消,不做处理
break;
default:
showToast('网络错误,请检查网络连接');
}
super.onError(err, handler);
}
void handleStatusCode(int? statusCode) {
switch (statusCode) {
case 400:
showToast('请求参数错误');
break;
case 401:
showToast('未授权,请重新登录');
// 跳转到登录页
break;
case 403:
showToast('禁止访问');
break;
case 404:
showToast('请求的资源不存在');
break;
case 500:
showToast('服务器错误');
break;
default:
showToast('未知错误');
}
}
}
八、文件上传下载
8.1 FormData上传
使用FormData上传文件:
final formData = FormData.fromMap({
'name': 'dio',
'date': DateTime.now().toIso8601String(),
'file': await MultipartFile.fromFile(
'./text.txt',
filename: 'upload.txt',
),
});
final response = await dio.post('/upload', data: formData);
8.2 多文件上传
上传多个文件:
final formData = FormData.fromMap({
'name': 'dio',
'files': [
await MultipartFile.fromFile('./text1.txt', filename: 'text1.txt'),
await MultipartFile.fromFile('./text2.txt', filename: 'text2.txt'),
],
});
final response = await dio.post('/upload', data: formData);
8.3 上传进度监听
监听文件上传进度:
final response = await dio.post(
'/upload',
data: formData,
onSendProgress: (sent, total) {
final progress = (sent / total * 100).toStringAsFixed(0);
print('上传进度: $progress%');
},
);
8.4 文件下载
下载文件到本地:
await dio.download(
'https://example.com/file.zip',
'/path/to/save/file.zip',
onReceiveProgress: (received, total) {
if (total != -1) {
final progress = (received / total * 100).toStringAsFixed(0);
print('下载进度: $progress%');
}
},
);
8.5 断点续传
实现断点续传功能:
final savePath = '/path/to/save/file.zip';
final file = File(savePath);
int downloadedBytes = 0;
// 如果文件已存在,获取已下载的字节数
if (await file.exists()) {
downloadedBytes = await file.length();
}
await dio.download(
'https://example.com/file.zip',
savePath,
options: Options(
headers: {
'Range': 'bytes=$downloadedBytes-',
},
),
onReceiveProgress: (received, total) {
final progress = ((downloadedBytes + received) / total * 100).toStringAsFixed(0);
print('下载进度: $progress%');
},
);
九、请求取消
9.1 使用CancelToken
创建CancelToken取消请求:
final cancelToken = CancelToken();
// 发起请求
dio.get('/test', cancelToken: cancelToken).catchError((error) {
if (CancelToken.isCancel(error)) {
print('请求已取消: ${error.message}');
} else {
print('请求错误: $error');
}
});
// 取消请求
cancelToken.cancel('用户取消');
9.2 共享CancelToken
一个CancelToken可以用于多个请求:
final cancelToken = CancelToken();
// 多个请求共享同一个token
final request1 = dio.get('/api1', cancelToken: cancelToken);
final request2 = dio.get('/api2', cancelToken: cancelToken);
final request3 = dio.get('/api3', cancelToken: cancelToken);
// 取消所有请求
cancelToken.cancel('批量取消');
9.3 实际应用场景
在Flutter中取消页面销毁时的请求:
class MyPage extends StatefulWidget {
_MyPageState createState() => _MyPageState();
}
class _MyPageState extends State<MyPage> {
final cancelToken = CancelToken();
void initState() {
super.initState();
loadData();
}
void loadData() async {
try {
final response = await dio.get('/data', cancelToken: cancelToken);
// 处理数据
} on DioException catch (e) {
if (!CancelToken.isCancel(e)) {
// 处理错误
}
}
}
void dispose() {
cancelToken.cancel('页面已销毁');
super.dispose();
}
Widget build(BuildContext context) {
return Container();
}
}
十、Transformer数据转换
10.1 默认Transformer
Dio默认使用BackgroundTransformer,在响应数据大于50KB时会在isolate中解析JSON:
final dio = Dio();
// 默认已经配置了BackgroundTransformer
10.2 自定义Transformer
创建自定义Transformer:
class CustomTransformer extends BackgroundTransformer {
Future<String> transformRequest(RequestOptions options) async {
// 自定义请求数据转换
if (options.data is Map) {
return jsonEncode(options.data);
}
return super.transformRequest(options);
}
Future transformResponse(
RequestOptions options,
ResponseBody responseBody,
) async {
// 自定义响应数据转换
final data = await super.transformResponse(options, responseBody);
// 可以在这里添加数据解密、格式转换等逻辑
return data;
}
}
// 使用自定义Transformer
dio.transformer = CustomTransformer();
10.3 Transformer应用场景
常见应用场景:
- 数据加密/解密
- 数据格式转换
- 添加通用字段
- 数据校验
class EncryptTransformer extends BackgroundTransformer {
Future<String> transformRequest(RequestOptions options) async {
final data = await super.transformRequest(options);
// 加密请求数据
return encrypt(data);
}
Future transformResponse(
RequestOptions options,
ResponseBody responseBody,
) async {
final data = await super.transformResponse(options, responseBody);
// 解密响应数据
return decrypt(data);
}
}
十一、HttpClientAdapter适配器
11.1 默认适配器
Dio在不同平台使用不同的适配器:
- Native平台:IOHttpClientAdapter
- Web平台:BrowserHttpClientAdapter
import 'package:dio/io.dart';
dio.httpClientAdapter = IOHttpClientAdapter();
11.2 配置代理
使用IOHttpClientAdapter配置代理:
import 'package:dio/io.dart';
dio.httpClientAdapter = IOHttpClientAdapter(
createHttpClient: () {
final client = HttpClient();
client.findProxy = (uri) {
return 'PROXY localhost:8888';
};
return client;
},
);
11.3 HTTPS证书验证
配置HTTPS证书验证:
import 'dart:io';
import 'package:dio/io.dart';
dio.httpClientAdapter = IOHttpClientAdapter(
createHttpClient: () {
final client = HttpClient();
client.badCertificateCallback = (cert, host, port) {
// 验证证书
return cert.pem == expectedPEM;
};
return client;
},
);
11.4 自定义适配器
创建自定义适配器:
class CustomAdapter implements HttpClientAdapter {
Future<ResponseBody> fetch(
RequestOptions options,
Stream<Uint8List>? requestStream,
Future<void>? cancelFuture,
) async {
// 实现自定义的HTTP请求逻辑
// ...
}
void close({bool force = false}) {
// 关闭适配器
}
}
dio.httpClientAdapter = CustomAdapter();
十二、最佳实践
12.1 单例模式
使用单例模式管理Dio实例:
class DioClient {
static final DioClient _instance = DioClient._internal();
late final Dio dio;
factory DioClient() => _instance;
DioClient._internal() {
dio = Dio(
BaseOptions(
baseUrl: 'https://api.example.com',
connectTimeout: Duration(seconds: 5),
receiveTimeout: Duration(seconds: 3),
),
);
// 添加拦截器
dio.interceptors.add(LogInterceptor());
dio.interceptors.add(AuthInterceptor());
}
}
// 使用
final dio = DioClient().dio;
12.2 API封装
封装API请求方法:
class ApiService {
final Dio _dio = DioClient().dio;
Future<User> getUser(String id) async {
try {
final response = await _dio.get('/user/$id');
return User.fromJson(response.data);
} on DioException catch (e) {
throw _handleError(e);
}
}
Future<List<Post>> getPosts({int page = 1, int limit = 20}) async {
try {
final response = await _dio.get(
'/posts',
queryParameters: {'page': page, 'limit': limit},
);
return (response.data as List)
.map((json) => Post.fromJson(json))
.toList();
} on DioException catch (e) {
throw _handleError(e);
}
}
Exception _handleError(DioException error) {
switch (error.type) {
case DioExceptionType.connectionTimeout:
return TimeoutException('连接超时');
case DioExceptionType.badResponse:
return ServerException('服务器错误: ${error.response?.statusCode}');
default:
return NetworkException('网络错误');
}
}
}
12.3 项目结构
推荐的项目结构:
lib/
├── core/
│ ├── network/
│ │ ├── dio_client.dart
│ │ ├── api_service.dart
│ │ └── interceptors/
│ │ ├── auth_interceptor.dart
│ │ ├── error_interceptor.dart
│ │ └── log_interceptor.dart
│ └── constants/
│ └── api_constants.dart
├── models/
│ ├── user.dart
│ └── post.dart
└── main.dart
十三、性能优化(第二轮)
第二轮我们把“能用”升级到“好用、快、可观测”。在网络层里,性能优化通常围绕:减少请求次数、减少单次请求耗时、减少主线程阻塞、减少序列化开销。
13.1 建议先定义可量化指标
| 指标 | 含义 | 建议采集方式 |
|---|---|---|
| TTFB | 首字节时间 | 抓包/服务端日志/客户端打点 |
| totalTime | 请求总耗时 | Interceptor中打点 |
| payloadSize | 响应体大小 | content-length或字节长度 |
| errorRate | 错误率 | 统一错误上报/日志聚合 |

13.2 通过拦截器做耗时打点(可复用)
class TimingInterceptor extends Interceptor {
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
options.extra['ts'] = DateTime.now().microsecondsSinceEpoch;
handler.next(options);
}
void onResponse(Response response, ResponseInterceptorHandler handler) {
final ts = response.requestOptions.extra['ts'] as int?;
if (ts != null) {
final costUs = DateTime.now().microsecondsSinceEpoch - ts;
print('DioTiming ${response.requestOptions.method} ${response.requestOptions.uri} cost=${costUs / 1000}ms');
}
handler.next(response);
}
void onError(DioException err, ErrorInterceptorHandler handler) {
final ts = err.requestOptions.extra['ts'] as int?;
if (ts != null) {
final costUs = DateTime.now().microsecondsSinceEpoch - ts;
print('DioTiming ERROR ${err.requestOptions.method} ${err.requestOptions.uri} cost=${costUs / 1000}ms');
}
handler.next(err);
}
}
13.3 并发与取消:减少无效请求
| 场景 | 建议 | 说明 |
|---|---|---|
| 页面切换频繁 | 取消旧请求 | CancelToken避免浪费 |
| 接口高频刷新 | 节流/合并请求 | 降低请求次数 |
| 多接口并发 | 控制并发上限 | 避免瞬时拥塞 |

十四、内存优化(第二轮)
网络层常见的内存问题集中在:大响应体驻留内存、bytes处理无上限、下载流未关闭、回调持有页面引用。
14.1 大响应体的处理建议
| 数据类型 | 建议 | 目的 |
|---|---|---|
| 大JSON列表 | 分页/增量加载 | 降低峰值内存 |
| 大文件下载 | ResponseType.stream |
避免一次性读入内存 |
| 图片bytes | 先落盘再展示 | 减少驻留 |
final rs = await dio.get(
url,
options: Options(responseType: ResponseType.stream),
);
final stream = rs.data.stream;
// TODO: 将stream写入File(示例略),写完及时close
14.2 页面销毁时取消请求,避免“回包更新已销毁页面”
class MyPageState extends State<MyPage> {
final cancelToken = CancelToken();
Future<void> load() async {
await dio.get('/data', cancelToken: cancelToken);
}
void dispose() {
cancelToken.cancel('disposed');
super.dispose();
}
}

十五、问题定位与排障(第二轮)
第二轮的目标是“出了问题能快速定位”:建议把定位过程标准化为 打点 -> 抓包 -> 对齐服务端日志 -> 复现与回归。
15.1 常见问题定位清单
| 现象 | 优先排查 | 常用手段 |
|---|---|---|
| 接口超时 | DNS/网络/服务端耗时 | 客户端耗时打点 + 抓包 |
| 4xx/5xx | 参数/鉴权/服务端 | 打印请求要素 + TraceId |
| 偶现错误 | 并发/重试/取消 | requestId贯穿 + 日志聚合 |
| 数据不一致 | 缓存/重试/多端 | 比对请求与响应版本 |
15.2 给每个请求加X-Request-Id
import 'dart:math';
String genRequestId() => '${DateTime.now().millisecondsSinceEpoch}_${Random().nextInt(1 << 20)}';
class TraceIdInterceptor extends Interceptor {
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
final rid = genRequestId();
options.extra['rid'] = rid;
options.headers['X-Request-Id'] = rid;
handler.next(options);
}
}
15.3 抓包与代理
- 客户端开启代理(
IOHttpClientAdapter) - 用抓包工具观察:URL、Header、Body、状态码、耗时
- 用
X-Request-Id对齐服务端日志

总结
本文详细介绍了Dio三方库的核心功能和使用方法,包括基础请求、拦截器、错误处理、文件上传下载、请求取消等。Dio是Flutter开发中最强大的HTTP客户端库,掌握它能大大提高开发效率。
Dio的主要优势:
- 功能强大且完善
- API简洁易用
- 性能优秀
- 社区活跃
下一篇文章将继续围绕“网络链路治理”的第二轮主题,结合http/retrofit/pretty_dio_logger/dio_cache_interceptor做性能、内存与定位的体系化对比,敬请期待!
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- Dio官方文档:https://pub.dev/packages/dio
- GitHub仓库:https://github.com/cfug/dio
- Pub.dev主页:https://pub.dev/packages/dio
- 中文文档:https://github.com/cfug/dio/blob/main/dio/README-ZH.md
- 开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
- 迁移指南:https://pub.dev/documentation/dio/latest/topics/Migration%20Guide-topic.html
- 插件列表:https://pub.dev/documentation/dio/latest/topics/Plugins-topic.html
- 示例代码:https://github.com/cfug/dio/tree/main/example_dart
更多推荐

所有评论(0)