MST

星途 面试题库

面试题:Flutter处理复杂场景下iOS与Android网络配置及适配

假设在一个Flutter应用中,需要在不同网络环境(如WiFi、4G、5G)且不同系统版本(iOS 12及以上,Android 8.0及以上)下进行复杂的网络请求操作,例如并发请求、断点续传等。请详细描述你会如何从网络配置、框架选择、代码实现等方面确保在iOS和Android平台上都能稳定、高效地完成这些网络操作,并说明可能遇到的坑点及解决方案。
12.7万 热度难度
前端开发Flutter

知识考点

AI 面试

面试题答案

一键面试

网络配置

  1. 权限配置
    • 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>
    
  2. 网络监听
    • 使用 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) {
                // 移动网络处理逻辑
            }
        });
    }
    

框架选择

  1. Dio
    • 优势:功能强大,支持并发请求、拦截器、断点续传等功能。在 pubspec.yaml 中添加依赖:
    dio: ^4.0.0
    
    • 并发请求:使用 DioFuture.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
    }
    
    • 断点续传:利用 DioDownloadOptions 实现断点续传,示例代码:
    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);
        }
    }
    

代码实现

  1. 平台适配
    • 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及以上处理
        }
    }
    
  2. 错误处理
    • 网络请求失败:在 DiocatchError 中捕获错误,示例代码:
    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 {
                // 其他错误处理
            }
        }
    }
    

可能遇到的坑点及解决方案

  1. 证书问题(iOS)
    • 坑点:iOS 9之后默认使用HTTPS,若服务器证书配置不正确,会导致网络请求失败。
    • 解决方案:确保服务器证书正确配置,若使用自签名证书,可在 Info.plist 中配置 NSAppTransportSecurityNSExceptionDomains,例如:
    <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>
    
  2. 网络切换问题
    • 坑点:在网络切换时,如从WiFi切换到4G,可能导致正在进行的网络请求失败。
    • 解决方案:结合 connectivity_plus 插件,在网络切换时,重新发起必要的网络请求,或使用 DioCancelToken 取消当前请求并重新发起。
  3. 并发请求资源消耗
    • 坑点:过多的并发请求可能导致设备资源消耗过大,影响应用性能。
    • 解决方案:合理控制并发请求数量,例如使用 DioDioExecutor 进行请求队列管理,设置最大并发数。示例代码:
    final dio = Dio(BaseOptions())
        ..httpClientAdapter = DefaultHttpClientAdapter()
        ..dioExecutor = DioExecutor(
            dio: dio,
            maxConcurrentRequests: 3 // 设置最大并发数为3
        );