当前位置: 首页 > news >正文

Flutter 网络栈入门,Dio 与 Retrofit 全面指南

面向多年 iOS 开发者的零阻力上手


写在前面

你在 iOS 项目中也许习惯了 URLSessionAlamofireMoya
换到 Flutter 后,等价的「组合拳」就是 Dio + Retrofit
本文将带你一次吃透两套库的安装、核心 API、进阶技巧与最佳实践。


1. Dio:Flutter 里的「Alamofire」

特性作用iOS 类比
BaseOptions全局配置(超时、基址等)URLSessionConfiguration
Interceptors请求/响应拦截、重试、日志URLProtocol / RequestAdapter
CancelToken任务取消URLSessionTask.cancel()
FormData表单/文件上传multipart/form-data
download()断点续传downloadTask(withResumeData:)

1.1 安装

dependencies:dio: ^5.4.0   # 以实际最新版为准
flutter pub get

1.2 基础用法

final dio = Dio(BaseOptions(baseUrl: 'https://api.example.com',connectTimeout: const Duration(seconds: 10),receiveTimeout: const Duration(seconds: 15),headers: {'Accept': 'application/json'},),
);// GET
final res = await dio.get('/users/42');
print(res.data);// POST
await dio.post('/login',data: {'email': 'me@example.com', 'pwd': '123456'},
);

提示:默认 JSON ⇆ Map<String,dynamic>,无需手写解析。

1.3 拦截器 (Interceptors)

dio.interceptors.add(InterceptorsWrapper(onRequest: (options, handler) {options.headers['Authorization'] = 'Bearer $token';return handler.next(options); // 继续},onError: (e, handler) async {if (e.response?.statusCode == 401) {// 刷新 token 后重试final newToken = await _refreshToken();final request = e.requestOptions;request.headers['Authorization'] = 'Bearer $newToken';return handler.resolve(await dio.fetch(request));}return handler.next(e); // 继续抛出},),
);

1.4 取消 & 进度

final cancel = CancelToken();dio.download(url,savePath,cancelToken: cancel,onReceiveProgress: (recv, total) =>debugPrint('Progress ${(recv / total * 100).toStringAsFixed(0)}%'),
);// …在需要时
cancel.cancel('用户离开页面,停止下载');

2. Retrofit:类型安全的 REST 接口生成器

与 Android 同名库思路一致:用注解声明接口 ➜ 自动车生成实现 ➜ 调用即得强类型数据

2.1 安装

dependencies:retrofit: ^4.1.0dio: ^5.4.0json_annotation: ^4.9.0dev_dependencies:build_runner: ^2.4.10retrofit_generator: ^8.1.0json_serializable: ^6.8.0

2.2 声明接口(user_service.dart

part 'user_service.g.dart'; // 生成文件(baseUrl: 'https://api.example.com')
abstract class UserService {factory UserService(Dio dio, {String baseUrl}) = _UserService;('/users/{id}')Future<User> getUser(() int id);('/login')Future<AuthToken> login(() LoginPayload body);('/search')Future<List<User>> search(('keyword') String q,('X-Trace-Id') String traceId,);
}

2.3 生成代码

flutter pub run build_runner build -d

自动产出的 _UserService 文件包含所有实际的 Dio 调用与 JSON → 模型的序列化逻辑;你只和 接口 打交道。

2.4 调用

final dio = Dio()..interceptors.add(LogInterceptor());
final api = UserService(dio);final user = await api.getUser(42);
debugPrint(user.name);final token = await api.login(LoginPayload('me@example.com', '123456'));
await secureStorage.write(key: 'token', value: token.value);

3. Dio × Retrofit:组合最佳实践

  1. 复用同一 Dio 实例
    统一拦截器/超时/证书校验,防止重复配置。

  2. 自动刷新 Token
    在 Dio 拦截器里检测 401,完成刷新后 handler.resolve(...) 重放失败请求。

  3. 环境切换
    通过注入 baseUrlUserService(dio, baseUrl: kDebug ? dev : prod))即可。

  4. 响应泛型包装
    自定义 BaseResponse<T>,配合 json_serializable 解析:

    class BaseResponse<T> {final int code;final String msg;final T data;// …fromJson / toJson 省略
    }
    

4. 与 iOS 思维对照

概念Flutter (Dio / Retrofit)iOS 对应迁移 Tips
全局配置BaseOptionsURLSessionConfiguration把常用 Header、超时集中写
拦截器链InterceptorsWrapperURLProtocol / RequestInterceptor顺序执行,可短路
类型安全接口@GET, @POST 注解Moya TargetType / Swift ProtocolDart 代码生成替代手写
取消任务CancelTokenURLSessionTask页面销毁就 cancel
Mock 数据MockAdapterOHHTTPStubs / Mocker轻松写单元测试

5. 常见坑 & 进阶技巧

  1. HttpClientAdapter 自定义证书校验

    dio.httpClientAdapter = IOHttpClientAdapter()..onHttpClientCreate = (client) {client.badCertificateCallback = (_, __, ___) => true; // 仅示例return client;};
    
  2. 并发请求:使用 Future.wait([...])Isolate,避免阻塞 UI。

  3. 队列重试:配合 retry 包或自定义拦截器实现指数退避。

  4. 缓存dio_cache_interceptor 支持磁盘和内存双缓存策略。

  5. WebSocket:Dio 不负责,使用 web_socket_channel


6. 结语

Dio + Retrofit 为 Flutter 带来了与 iOS 熟悉的 网络层“三件套”

  1. 强大且可插拔的 HTTP 客户端
  2. 类型安全、零样板的接口定义
  3. 完善的拦截/重试/监控生态

只要把握「配置统一 → 模型生成 → 拦截链驱动」三步,就能迅速复制在 iOS 积累的工程经验,构建健壮、可测试、易维护的 Flutter 网络栈。

下一步:尝试将现有 Swift 服务层迁移为 Dart 接口,体验全端一致的开发流畅感吧!


相关文章:

  • <script setup> 语法糖
  • 基于 Spring Boot + Vue 3的现代化社区团购系统
  • MyBatis中的SQL理解
  • Dubbo服务调用全流程解析
  • matlab实现轮轨接触几何计算
  • 前置机、跳板机、堡垒机详细介绍及对比
  • 数字孪生技术为UI前端注入新活力:实现智能化交互新体验
  • vue将页面导出pdf,vue导出pdf ,使用html2canvas和jspdf组件
  • OpenCV CUDA模块设备层-----双曲正弦函数sinh()
  • 【linux】程序地址空间
  • AI聊天多分支对话的纯前端实现
  • 19、RocketMQ核⼼编程模型
  • Nestjs框架: nestjs-schedule模块中的三类定时任务
  • 同样是synthesis(综合) HLS和Vivado里面是有什么区别
  • 商品中心—15.库存分桶扣减的技术文档
  • Hyperledger Fabric 入门笔记(二十)Fabric V2.5 测试网络进阶之Tape性能测试
  • 3.Stable Diffusion WebUI本地部署和实践
  • 论分布式设计
  • 基于Redis分布式的限流
  • springboot整合微信App支付以及支付宝App支付