下面是一篇关于 Flutter 使用 Dio 封装网络请求 的教程文章,包括完整的封装类、使用示例和最佳实践,适合构建中大型项目时复用。
在实际开发中,直接在每个页面使用 Dio 发请求既冗余又不易维护,因此我们需要进行统一封装,提升代码复用性和可维护性。
在 pubspec.yaml
中添加:
dependencies:
dio: ^5.4.0
flutter:
sdk: flutter
然后运行:
flutter pub get
创建一个文件:lib/net/http_service.dart
import 'package:dio/dio.dart';
class HttpService {
static final HttpService _instance = HttpService._internal();
factory HttpService() => _instance;
late Dio _dio;
HttpService._internal() {
BaseOptions options = BaseOptions(
baseUrl: "https://api.example.com", // 替换为你的后端地址
connectTimeout: const Duration(seconds: 10),
receiveTimeout: const Duration(seconds: 10),
headers: {
'Content-Type': 'application/json',
},
);
_dio = Dio(options);
// 添加拦截器(可选)
_dio.interceptors.add(InterceptorsWrapper(
onRequest: (options, handler) {
// 比如添加token
// options.headers["Authorization"] = "Bearer xxx";
return handler.next(options);
},
onResponse: (response, handler) {
return handler.next(response);
},
onError: (DioException e, handler) {
print("请求错误: ${e.message}");
return handler.next(e);
},
));
}
// GET请求
Future<Response> get(String path, {Map<String, dynamic>? queryParameters}) async {
try {
return await _dio.get(path, queryParameters: queryParameters);
} catch (e) {
rethrow;
}
}
// POST请求
Future<Response> post(String path, {dynamic data, Map<String, dynamic>? queryParameters}) async {
try {
return await _dio.post(path, data: data, queryParameters: queryParameters);
} catch (e) {
rethrow;
}
}
// 其他请求可按需添加(put、delete等)
}
在页面或业务逻辑层调用:
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:your_app/net/http_service.dart';
class TestApiPage extends StatefulWidget {
const TestApiPage({Key? key}) : super(key: key);
@override
State<TestApiPage> createState() => _TestApiPageState();
}
class _TestApiPageState extends State<TestApiPage> {
String result = "请求中...";
@override
void initState() {
super.initState();
fetchData();
}
void fetchData() async {
try {
Response response = await HttpService().get("/test");
setState(() {
result = response.data.toString();
});
} catch (e) {
setState(() {
result = "出错了:$e";
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("API测试")),
body: Center(child: Text(result)),
);
}
}
你可以根据项目需要扩展以下内容:
dio_logger
插件)HttpService
单例。如果你需要支持上传文件、带Token认证、统一异常封装等高级功能,我也可以继续补充更完整的版本。需要吗?