Flutter网络请求实战:Retrofit+Dio完美解决方案

Flutter网络请求:Retrofit使用指南

Retrofit是Android平台上广受欢迎的HTTP客户端库,在Flutter中可以通过retrofit包实现类似的网络请求功能。下面是完整的使用指南:

1. 添加依赖

首先在pubspec.yaml中添加所需依赖:

yaml 复制代码
dependencies:
  retrofit: ^4.0.1
  dio: ^5.3.2
  json_annotation: ^4.8.1

dev_dependencies:
  retrofit_generator: ^4.0.1
  build_runner: ^2.4.4

2. 创建API接口

定义一个抽象类来描述你的API接口:

dart 复制代码
import 'package:retrofit/retrofit.dart';
import 'package:dio/dio.dart';
import 'package:json_annotation/json_annotation.dart';

part 'api_service.g.dart';

@RestApi(baseUrl: "https://jsonplaceholder.typicode.com/")
abstract class ApiService {
  factory ApiService(Dio dio, {String baseUrl}) = _ApiService;

  @GET("/posts")
  Future<List<Post>> getPosts();

  @GET("/posts/{id}")
  Future<Post> getPost(@Path("id") int id);

  @POST("/posts")
  Future<Post> createPost(@Body() Post post);
}

@JsonSerializable()
class Post {
  final int id;
  final String title;
  final String body;
  final int userId;

  Post({
    required this.id,
    required this.title,
    required this.body,
    required this.userId,
  });

  factory Post.fromJson(Map<String, dynamic> json) => _$PostFromJson(json);
  Map<String, dynamic> toJson() => _$PostToJson(this);
}

3. 生成代码

运行以下命令生成实现代码:

bash 复制代码
flutter pub run build_runner build

这会生成api_service.g.dart文件。

4. 使用API服务

dart 复制代码
void main() async {
  final dio = Dio();
  final apiService = ApiService(dio);

  try {
    // 获取所有帖子
    final posts = await apiService.getPosts();
    print(posts);

    // 获取单个帖子
    final post = await apiService.getPost(1);
    print(post);

    // 创建新帖子
    final newPost = await apiService.createPost(
      Post(id: 101, title: 'New Post', body: 'Content', userId: 1),
    );
    print(newPost);
  } catch (e) {
    print(e);
  }
}

5. 高级功能

添加请求头

dart 复制代码
@GET("/posts")
@Headers({'Content-Type': 'application/json'})
Future<List<Post>> getPosts();

查询参数

dart 复制代码
@GET("/posts")
Future<List<Post>> getPostsByUser(@Query("userId") int userId);

表单数据

dart 复制代码
@POST("/login")
@FormUrlEncoded()
Future<User> login(
  @Field("username") String username,
  @Field("password") String password,
);

拦截器

dart 复制代码
final dio = Dio()
  ..interceptors.add(
    InterceptorsWrapper(
      onRequest: (options, handler) {
        // 添加认证token
        options.headers['Authorization'] = 'Bearer token';
        return handler.next(options);
      },
      onError: (DioError e, handler) {
        // 错误处理
        return handler.next(e);
      },
    ),
  );

6. 完整配置示例

dart 复制代码
import 'package:dio/dio.dart';
import 'package:retrofit/retrofit.dart';

part 'api_service.g.dart';

@RestApi(baseUrl: "https://api.example.com/v1/")
abstract class ApiService {
  factory ApiService(Dio dio, {String baseUrl}) {
    dio.options = BaseOptions(
      receiveTimeout: const Duration(seconds: 30),
      connectTimeout: const Duration(seconds: 30),
    );
    
    return _ApiService(dio, baseUrl: baseUrl);
  }

  @GET("users")
  Future<List<User>> getUsers();

  @GET("users/{id}")
  Future<User> getUser(@Path("id") String id);

  @POST("users")
  Future<User> createUser(@Body() User user);

  @PUT("users/{id}")
  Future<User> updateUser(@Path("id") String id, @Body() User user);

  @DELETE("users/{id}")
  Future<void> deleteUser(@Path("id") String id);
}

7. 错误处理

dart 复制代码
try {
  final response = await apiService.getUser('123');
} on DioError catch (e) {
  if (e.response != null) {
    print(e.response?.statusCode);
    print(e.response?.data);
  } else {
    print(e.message);
  }
}

8. 测试API服务

dart 复制代码
test('getPosts returns List<Post>', () async {
  final dio = DioAdapterMock();
  final apiService = ApiService(dio);

  when(dio.get('/posts')).thenAnswer((_) async => Response(
    data: [
      {'id': 1, 'title': 'Test', 'body': 'Content', 'userId': 1}
    ],
    statusCode: 200,
    requestOptions: RequestOptions(path: '/posts'),
  ));

  final posts = await apiService.getPosts();
  expect(posts, isA<List<Post>>());
  expect(posts.first.title, 'Test');
});

Retrofit为Flutter提供了类型安全的HTTP客户端实现,通过代码生成简化了网络请求的编写,同时保持了Dio的强大功能。

相关推荐
tangweiguo030519879 小时前
Dart 面试核心考点全解析
flutter
SoaringHeart11 小时前
Flutter组件封装:验证码倒计时按钮 TimerButton
前端·flutter
lqj_本人12 小时前
Flutter 适配鸿蒙桌面快捷入口完整指南
flutter·华为·harmonyos
kirk_wang13 小时前
Flutter 三方库鸿蒙适配实践:以 Firebase Messaging 为例实现跨平台推送集成
flutter·移动开发·跨平台·arkts·鸿蒙
赵财猫._.14 小时前
【Flutter x 鸿蒙】第一篇:环境搭建与第一个鸿蒙Flutter应用运行
flutter·华为·harmonyos
恋猫de小郭14 小时前
Android Studio Otter 2 Feature 发布,最值得更新的 Android Studio
android·前端·flutter
走在路上的菜鸟15 小时前
Android学Dart学习笔记第十二节 函数
android·笔记·学习·flutter
sunly_16 小时前
Flutter:高德定位,获取经纬度,详细地址信息
flutter
解局易否结局16 小时前
Flutter 跨平台开发进阶:从 Widget 思想到全栈集成
flutter
Bryce李小白17 小时前
理解InheritedWidget概念
flutter