Flutter网络请求与数据处理1. 前言在现代移动应用中网络请求和数据处理是核心功能之一。Flutter提供了多种方式来处理网络请求本文将深入探讨Flutter中的网络请求与数据处理技巧帮助你创建更加可靠、高效的网络应用。2. 基础网络请求2.1 使用http包dependencies: flutter: sdk: flutter http: ^0.13.5import dart:convert; import package:http/http.dart as http; Futurevoid fetchData() async { final response await http.get(Uri.parse(https://api.example.com/data)); if (response.statusCode 200) { final data jsonDecode(response.body); print(data); } else { print(Request failed with status: ${response.statusCode}); } }2.2 发送POST请求Futurevoid postData() async { final response await http.post( Uri.parse(https://api.example.com/data), headers: { Content-Type: application/json, }, body: jsonEncode({ name: John Doe, email: johnexample.com, }), ); if (response.statusCode 201) { final data jsonDecode(response.body); print(data); } else { print(Request failed with status: ${response.statusCode}); } }3. 高级网络请求3.1 使用dio包dependencies: flutter: sdk: flutter dio: ^4.0.6import package:dio/dio.dart; final dio Dio(); Futurevoid fetchDataWithDio() async { try { final response await dio.get(https://api.example.com/data); print(response.data); } catch (e) { print(Error: $e); } } Futurevoid postDataWithDio() async { try { final response await dio.post(https://api.example.com/data, data: { name: John Doe, email: johnexample.com, }); print(response.data); } catch (e) { print(Error: $e); } }3.2 拦截器class LogInterceptor extends Interceptor { override void onRequest(RequestOptions options, RequestInterceptorHandler handler) { print(Request: ${options.uri}); print(Method: ${options.method}); print(Headers: ${options.headers}); print(Data: ${options.data}); super.onRequest(options, handler); } override void onResponse(Response response, ResponseInterceptorHandler handler) { print(Response: ${response.statusCode}); print(Data: ${response.data}); super.onResponse(response, handler); } override void onError(DioError err, ErrorInterceptorHandler handler) { print(Error: ${err.message}); super.onError(err, handler); } } // 添加拦截器 dio.interceptors.add(LogInterceptor());3.3 请求配置final dio Dio(BaseOptions( baseUrl: https://api.example.com, connectTimeout: Duration(seconds: 5), receiveTimeout: Duration(seconds: 3), headers: { Content-Type: application/json, Authorization: Bearer token, }, ));4. 数据模型4.1 创建数据模型class User { final int id; final String name; final String email; User({ required this.id, required this.name, required this.email, }); factory User.fromJson(MapString, dynamic json) { return User( id: json[id], name: json[name], email: json[email], ); } MapString, dynamic toJson() { return { id: id, name: name, email: email, }; } }4.2 使用json_serializabledependencies: flutter: sdk: flutter json_annotation: ^4.6.0 dev_dependencies: build_runner: ^2.1.11 json_serializable: ^6.2.0import package:json_annotation/json_annotation.dart; part user.g.dart; JsonSerializable() class User { final int id; final String name; final String email; User({ required this.id, required this.name, required this.email, }); factory User.fromJson(MapString, dynamic json) _$UserFromJson(json); MapString, dynamic toJson() _$UserToJson(this); }运行命令生成代码flutter pub run build_runner build5. 状态管理与网络请求5.1 使用Providerdependencies: flutter: sdk: flutter provider: ^6.0.5 http: ^0.13.5class UserProvider extends ChangeNotifier { ListUser _users []; bool _isLoading false; String? _error; ListUser get users _users; bool get isLoading _isLoading; String? get error _error; Futurevoid fetchUsers() async { _isLoading true; _error null; notifyListeners(); try { final response await http.get(Uri.parse(https://api.example.com/users)); if (response.statusCode 200) { final Listdynamic data jsonDecode(response.body); _users data.map((json) User.fromJson(json)).toList(); } else { _error Failed to fetch users; } } catch (e) { _error Error: $e; } finally { _isLoading false; notifyListeners(); } } }5.2 使用Riverpoddependencies: flutter: sdk: flutter riverpod: ^2.0.2 http: ^0.13.5final userProvider FutureProviderListUser((ref) async { final response await http.get(Uri.parse(https://api.example.com/users)); if (response.statusCode 200) { final Listdynamic data jsonDecode(response.body); return data.map((json) User.fromJson(json)).toList(); } else { throw Exception(Failed to fetch users); } }); // 使用 class UserList extends ConsumerWidget { override Widget build(BuildContext context, WidgetRef ref) { final users ref.watch(userProvider); return users.when( data: (users) { return ListView.builder( itemCount: users.length, itemBuilder: (context, index) { return ListTile( title: Text(users[index].name), subtitle: Text(users[index].email), ); }, ); }, loading: () CircularProgressIndicator(), error: (error, stack) Text(Error: $error), ); } }6. 错误处理6.1 网络错误处理Futurevoid fetchData() async { try { final response await http.get(Uri.parse(https://api.example.com/data)); if (response.statusCode 200) { final data jsonDecode(response.body); print(data); } else { print(Request failed with status: ${response.statusCode}); // 处理不同的状态码 switch (response.statusCode) { case 400: print(Bad request); break; case 401: print(Unauthorized); break; case 403: print(Forbidden); break; case 404: print(Not found); break; case 500: print(Internal server error); break; default: print(Unknown error); } } } catch (e) { print(Error: $e); // 处理网络错误 if (e is SocketException) { print(No internet connection); } else if (e is TimeoutException) { print(Request timeout); } else { print(Unknown error); } } }6.2 重试机制FutureResponse fetchWithRetry(String url, {int retries 3}) async { int attempts 0; while (attempts retries) { try { final response await http.get(Uri.parse(url)); if (response.statusCode 200) { return response; } else { attempts; if (attempts retries) { throw Exception(Failed after $retries attempts); } await Future.delayed(Duration(seconds: 1)); } } catch (e) { attempts; if (attempts retries) { rethrow; } await Future.delayed(Duration(seconds: 1)); } } throw Exception(Failed to fetch data); }7. 缓存策略7.1 内存缓存class MemoryCache { static final MapString, dynamic _cache {}; static void set(String key, dynamic value) { _cache[key] value; } static dynamic get(String key) { return _cache[key]; } static void remove(String key) { _cache.remove(key); } static void clear() { _cache.clear(); } } // 使用 Futurevoid fetchData() async { final cacheKey users; final cachedData MemoryCache.get(cacheKey); if (cachedData ! null) { print(Using cached data); return; } final response await http.get(Uri.parse(https://api.example.com/users)); if (response.statusCode 200) { final data jsonDecode(response.body); MemoryCache.set(cacheKey, data); print(data); } }7.2 本地存储缓存dependencies: flutter: sdk: flutter shared_preferences: ^2.0.15import package:shared_preferences/shared_preferences.dart; class CacheService { static Futurevoid saveData(String key, dynamic data) async { final prefs await SharedPreferences.getInstance(); await prefs.setString(key, jsonEncode(data)); } static Futuredynamic getData(String key) async { final prefs await SharedPreferences.getInstance(); final data prefs.getString(key); return data ! null ? jsonDecode(data) : null; } static Futurevoid removeData(String key) async { final prefs await SharedPreferences.getInstance(); await prefs.remove(key); } } // 使用 Futurevoid fetchData() async { final cacheKey users; final cachedData await CacheService.getData(cacheKey); if (cachedData ! null) { print(Using cached data); return; } final response await http.get(Uri.parse(https://api.example.com/users)); if (response.statusCode 200) { final data jsonDecode(response.body); await CacheService.saveData(cacheKey, data); print(data); } }8. 实际应用案例8.1 登录功能class AuthService { static FutureUser login(String email, String password) async { final response await http.post( Uri.parse(https://api.example.com/login), headers: { Content-Type: application/json, }, body: jsonEncode({ email: email, password: password, }), ); if (response.statusCode 200) { final data jsonDecode(response.body); final user User.fromJson(data[user]); final token data[token]; // 保存token await CacheService.saveData(token, token); await CacheService.saveData(user, user.toJson()); return user; } else { throw Exception(Login failed); } } static Futurevoid logout() async { await CacheService.removeData(token); await CacheService.removeData(user); } static FutureUser? getCurrentUser() async { final userData await CacheService.getData(user); return userData ! null ? User.fromJson(userData) : null; } static FutureString? getToken() async { return await CacheService.getData(token); } }8.2 数据列表class UserListScreen extends StatefulWidget { override _UserListScreenState createState() _UserListScreenState(); } class _UserListScreenState extends StateUserListScreen { ListUser _users []; bool _isLoading false; String? _error; override void initState() { super.initState(); _fetchUsers(); } Futurevoid _fetchUsers() async { setState(() { _isLoading true; _error null; }); try { final response await http.get(Uri.parse(https://api.example.com/users)); if (response.statusCode 200) { final Listdynamic data jsonDecode(response.body); setState(() { _users data.map((json) User.fromJson(json)).toList(); }); } else { setState(() { _error Failed to fetch users; }); } } catch (e) { setState(() { _error Error: $e; }); } finally { setState(() { _isLoading false; }); } } override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(Users), ), body: _isLoading ? Center(child: CircularProgressIndicator()) : _error ! null ? Center(child: Text(_error!)) : ListView.builder( itemCount: _users.length, itemBuilder: (context, index) { final user _users[index]; return ListTile( title: Text(user.name), subtitle: Text(user.email), ); }, ), floatingActionButton: FloatingActionButton( onPressed: _fetchUsers, child: Icon(Icons.refresh), ), ); } }8.3 文件上传Futurevoid uploadFile(File file) async { final uri Uri.parse(https://api.example.com/upload); final request http.MultipartRequest(POST, uri); request.files.add(await http.MultipartFile.fromPath(file, file.path)); final response await request.send(); if (response.statusCode 200) { final responseData await response.stream.toBytes(); final responseString String.fromCharCodes(responseData); print(responseString); } else { print(Upload failed with status: ${response.statusCode}); } }9. 性能优化9.1 并发请求Futurevoid fetchMultipleData() async { final futures [ http.get(Uri.parse(https://api.example.com/users)), http.get(Uri.parse(https://api.example.com/posts)), http.get(Uri.parse(https://api.example.com/comments)), ]; final responses await Future.wait(futures); final users jsonDecode(responses[0].body); final posts jsonDecode(responses[1].body); final comments jsonDecode(responses[2].body); print(Users: $users); print(Posts: $posts); print(Comments: $comments); }9.2 取消请求final cancelToken CancelToken(); try { final response await dio.get( https://api.example.com/data, cancelToken: cancelToken, ); print(response.data); } catch (e) { if (e is DioError e.type DioErrorType.cancel) { print(Request cancelled); } else { print(Error: $e); } } // 取消请求 cancelToken.cancel();9.3 超时设置final response await http.get( Uri.parse(https://api.example.com/data), headers: { Content-Type: application/json, }, ).timeout(Duration(seconds: 5), onTimeout: () { throw TimeoutException(Request timed out); });10. 常见问题与解决方案10.1 网络请求失败问题网络请求失败解决方案检查网络连接使用重试机制处理不同的错误类型10.2 数据解析错误问题JSON解析失败解决方案确保API返回正确的JSON格式使用try-catch捕获解析错误10.3 性能问题问题网络请求导致应用卡顿解决方案使用异步请求避免在UI线程中执行网络操作11. 总结Flutter提供了多种方式来处理网络请求从基本的http包到高级的dio包从简单的GET请求到复杂的文件上传Flutter都能满足你的需求。通过本文介绍的技巧你可以创建更加可靠、高效的网络应用。记住好的网络请求处理应该包括错误处理、缓存策略、性能优化等方面。希望本文对你有所帮助祝你在Flutter网络请求的世界中创造出更加精彩的应用