在Flutter中,Dio
是一个功能强大且易于使用的网络请求库,用于处理HTTP请求和响应。与 http
包相比,Dio
提供了更多高级功能,例如拦截器、文件上传/下载、请求取消等。结合 json_serializable
或手动解析 JSON 数据,可以轻松实现网络数据的获取与解析。
以下是一个完整的示例,展示如何使用 Dio
进行网络请求并解析 JSON 数据:
1. 添加依赖
在 pubspec.yaml
文件中添加以下依赖项:
dependencies:
flutter:
sdk: flutter
dio: ^5.0.0 # 确保使用最新版本
json_annotation: ^4.8.0
dev_dependencies:
build_runner: ^2.3.0
json_serializable: ^6.7.0
然后运行以下命令以安装依赖:
flutter pub get
2. 创建数据模型
为了更方便地解析 JSON 数据,我们可以创建一个数据模型类,并使用 json_serializable
自动生成序列化和反序列化代码。
定义模型类
创建一个文件 user_model.dart
:
import 'package:json_annotation/json_annotation.dart';
part 'user_model.g.dart'; // 自动生成的部分
()
class User {
final int id;
final String name;
final String email;
User({required this.id, required this.name, required this.email});
// 工厂方法用于从 JSON 转换为对象
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
// 方法用于将对象转换为 JSON
Map<String, dynamic> toJson() => _$UserToJson(this);
}
生成代码
运行以下命令以生成 user_model.g.dart
文件:
flutter pub run build_runner build
这会自动生成 _$UserFromJson
和 _$UserToJson
方法。
3. 使用 Dio 发起网络请求
接下来,我们使用 Dio
发起一个 GET 请求,并将返回的 JSON 数据解析为 User
对象。
示例代码
创建一个文件 dio_example.dart
:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'user_model.dart'; // 导入模型类
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Dio 网络请求示例')),
body: const Center(child: UserList()),
),
);
}
}
class UserList extends StatefulWidget {
const UserList({Key? key}) : super(key: key);
_UserListState createState() => _UserListState();
}
class _UserListState extends State<UserList> {
final Dio dio = Dio();
List<User> users = [];
Future<void> fetchUsers() async {
try {
// 示例 API 地址(假设返回 JSON 数据)
const url = 'https://jsonplaceholder.typicode.com/users';
// 发起 GET 请求
final response = await dio.get(url);
// 检查状态码是否成功
if (response.statusCode == 200) {
// 解析 JSON 数据
final jsonData = response.data as List<dynamic>;
// 将 JSON 数据转换为 User 对象列表
setState(() {
users = jsonData.map((json) => User.fromJson(json)).toList();
});
} else {
throw Exception('Failed to load users');
}
} catch (e) {
// 处理错误
print('Error: $e');
}
}
void initState() {
super.initState();
fetchUsers(); // 页面加载时自动发起请求
}
Widget build(BuildContext context) {
return ListView.builder(
itemCount: users.length,
itemBuilder: (context, index) {
final user = users[index];
return ListTile(
title: Text(user.name),
subtitle: Text(user.email),
);
},
);
}
}
4. 代码说明
Dio 初始化:
Dio
是一个强大的 HTTP 客户端,默认支持 GET、POST、PUT、DELETE 等 HTTP 方法。- 在示例中,我们通过
dio.get(url)
发起了一个 GET 请求。
JSON 数据解析:
- 假设 API 返回的 JSON 数据是数组形式(如
[{...}, {...}]
),我们将其解析为List<dynamic>
。 - 使用
map
方法将每个 JSON 对象转换为User
对象。
- 假设 API 返回的 JSON 数据是数组形式(如
错误处理:
- 使用
try-catch
捕获网络请求中的异常。 - 如果状态码不是
200
,抛出自定义异常。
- 使用
UI 更新:
- 使用
setState
更新users
列表,触发 UI 重新渲染。
- 使用
5. 测试与运行
运行项目后,应用会从 https://jsonplaceholder.typicode.com/users
获取用户数据,并将其显示在一个列表中。
6. 可选优化
- 拦截器:可以使用
Dio
的拦截器来统一处理请求头、日志记录等。 - 分页加载:如果数据量较大,可以实现分页加载功能。
- 缓存机制:结合本地数据库或内存缓存,减少重复请求。