Flutter 跨平台网络请求异常与适配问题解决指南

在 Flutter 跨平台开发中,网络请求异常通常涉及权限配置、平台差异、安全策略等核心问题。以下是常见踩坑点及解决方案:


1. 平台权限配置缺失

问题现象
Android/iOS 均出现 SocketExceptionHandshakeException

解决方案

  • Android
    android/app/src/main/AndroidManifest.xml 添加网络权限:
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    

  • iOS
    ios/Runner/Info.plist 添加:
    <key>NSAppTransportSecurity</key>
    <dict>
      <key>NSAllowsArbitraryLoads</key> 
      <true/>
    </dict>
    


2. HTTPS 证书校验失败

问题现象
HandshakeException: CERTIFICATE_VERIFY_FAILED

解决方案

  • 开发阶段
    dio 请求中关闭证书验证(仅限测试环境):
    final dio = Dio();
    (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = 
      (client) => client..badCertificateCallback = (cert, host, port) => true;
    

  • 生产环境
    使用权威 CA 证书,或通过 dio_certificate_pinning 插件实现证书锁定。

3. 平台差异导致超时异常

问题现象
iOS 正常但 Android 频繁超时。

解决方案

  • 统一超时配置
    封装网络请求时显式设置超时参数:
    Dio().options.connectTimeout = Duration(seconds: 15);
    Dio().options.receiveTimeout = Duration(seconds: 20);
    

  • Android 专属优化
    AndroidManifest.xml 中启用 android:usesCleartextTraffic="true" 允许 HTTP 明文传输。

4. 网络状态监听失效

问题现象
应用无法感知网络断开/重连。

解决方案

  • 使用 connectivity_plus 监听网络变化:
    final connectivity = Connectivity();
    connectivity.onConnectivityChanged.listen((status) {
      if (status == ConnectivityResult.none) {
        showToast("网络已断开");
      }
    });
    

  • 结合 dio 拦截器自动重试:
    dio.interceptors.add(RetryInterceptor(
      retryCount: 3,
      retryDelay: Duration(seconds: 2),
    ));
    


5. 多平台请求头差异

问题现象
服务端收到不一致的 User-Agent

解决方案

  • 动态设置平台专属请求头:
    String userAgent = Platform.isIOS 
        ? "Flutter-iOS/${AppVersion.version}" 
        : "Flutter-Android/${AppVersion.version}";
    
    dio.options.headers = {
      'User-Agent': userAgent,
      'Content-Type': 'application/json',
    };
    


最佳实践建议

  1. 统一网络库
    推荐使用 dio + dio_interceptor 组合,支持拦截器、缓存、重试等高级功能。
  2. 错误分层处理
    try {
      final response = await dio.get(url);
      return _parseResponse(response);
    } on DioError catch (e) {
      _handleError(e); // 分拣超时/404/500等错误
    } on FormatException {
      throw AppException("数据解析失败");
    }
    

  3. Mock 测试
    使用 http_mock_adapter 模拟网络异常场景:
    final dio = Dio();
    final adapter = DioAdapter();
    dio.httpClientAdapter = adapter;
    adapter.onGet("/test").reply(500); // 模拟服务端错误
    

通过权限配置、异常捕获、平台适配三管齐下,可显著提升 Flutter 跨平台网络请求的稳定性。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐