面试题答案
一键面试网络配置
- 权限配置
- Android:在
AndroidManifest.xml
中添加网络权限,如:
<uses - permission android:name="android.permission.INTERNET" /> <uses - permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- iOS:在
Info.plist
中添加NSAppTransportSecurity
配置,若要支持HTTP请求,可设置:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true /> </dict>
- Android:在
- 网络监听
- 使用
connectivity_plus
插件监听网络变化。在pubspec.yaml
中添加依赖:
connectivity_plus: ^3.0.6
- 示例代码:
import 'package:connectivity_plus/connectivity_plus.dart'; final Connectivity _connectivity = Connectivity(); late StreamSubscription<ConnectivityResult> _connectivitySubscription; void initConnectivity() async { ConnectivityResult result = await _connectivity.checkConnectivity(); _connectivitySubscription = _connectivity.onConnectivityChanged.listen((ConnectivityResult result) { // 根据result判断网络类型,如WiFi、4G、5G等并处理 if (result == ConnectivityResult.wifi) { // WiFi网络处理逻辑 } else if (result == ConnectivityResult.mobile) { // 移动网络处理逻辑 } }); }
- 使用
框架选择
- Dio
- 优势:功能强大,支持并发请求、拦截器、断点续传等功能。在
pubspec.yaml
中添加依赖:
dio: ^4.0.0
- 并发请求:使用
Dio
的Future.wait
方法实现并发请求,示例代码:
import 'package:dio/dio.dart'; final Dio dio = Dio(); Future<void> concurrentRequests() async { List<Future> requests = [ dio.get('https://example.com/api1'), dio.get('https://example.com/api2') ]; List<Response> responses = await Future.wait(requests); // 处理responses }
- 断点续传:利用
Dio
的DownloadOptions
实现断点续传,示例代码:
Future<void> downloadFile(String url, String savePath) async { try { await dio.download(url, savePath, onReceiveProgress: (received, total) { if (total != -1) { print((received / total * 100).toStringAsFixed(0) + '%'); } }, options: Options( followRedirects: false, receiveTimeout: 0 ), cancelToken: CancelToken()); } catch (e) { print(e); } }
- 优势:功能强大,支持并发请求、拦截器、断点续传等功能。在
代码实现
- 平台适配
- HTTP/HTTPS 协议:在不同平台上,确保协议支持,对于iOS,从iOS 9开始默认使用HTTPS,对于Android,根据网络环境和安全需求配置协议。
- 系统版本适配:在代码中使用条件判断,例如:
import 'package:flutter/foundation.dart'; if (kIsWeb) { // Web平台处理 } else if (defaultTargetPlatform == TargetPlatform.iOS) { if (Theme.of(context).platform == TargetPlatform.iOS) { // iOS 12及以上处理 } } else if (defaultTargetPlatform == TargetPlatform.android) { if (Theme.of(context).platform == TargetPlatform.android) { // Android 8.0及以上处理 } }
- 错误处理
- 网络请求失败:在
Dio
的catchError
中捕获错误,示例代码:
try { Response response = await dio.get('https://example.com/api'); } catch (e) { if (e is DioError) { if (e.type == DioErrorType.connectTimeout) { // 连接超时处理 } else if (e.type == DioErrorType.receiveTimeout) { // 接收超时处理 } else if (e.type == DioErrorType.sendTimeout) { // 发送超时处理 } else if (e.type == DioErrorType.response) { // 响应错误处理 } else if (e.type == DioErrorType.cancel) { // 请求取消处理 } else { // 其他错误处理 } } }
- 网络请求失败:在
可能遇到的坑点及解决方案
- 证书问题(iOS)
- 坑点:iOS 9之后默认使用HTTPS,若服务器证书配置不正确,会导致网络请求失败。
- 解决方案:确保服务器证书正确配置,若使用自签名证书,可在
Info.plist
中配置NSAppTransportSecurity
的NSExceptionDomains
,例如:
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>example.com</key> <dict> <key>NSIncludesSubdomains</key> <true /> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true /> <key>NSExceptionRequiresForwardSecrecy</key> <false /> </dict> </dict> </dict>
- 网络切换问题
- 坑点:在网络切换时,如从WiFi切换到4G,可能导致正在进行的网络请求失败。
- 解决方案:结合
connectivity_plus
插件,在网络切换时,重新发起必要的网络请求,或使用Dio
的CancelToken
取消当前请求并重新发起。
- 并发请求资源消耗
- 坑点:过多的并发请求可能导致设备资源消耗过大,影响应用性能。
- 解决方案:合理控制并发请求数量,例如使用
Dio
的DioExecutor
进行请求队列管理,设置最大并发数。示例代码:
final dio = Dio(BaseOptions()) ..httpClientAdapter = DefaultHttpClientAdapter() ..dioExecutor = DioExecutor( dio: dio, maxConcurrentRequests: 3 // 设置最大并发数为3 );