Flutter 三方库 cached_network_image 的鸿蒙化适配与实战指南
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

前言

在移动应用开发中,网络状态监控是一个基础且重要的功能。无论是即时通讯应用、在线视频播放器,还是需要实时数据同步的应用,都需要准确获取设备的网络连接状态。本文将详细介绍如何在鸿蒙系统中开发一个完整的网络状态监控插件,通过Flutter框架实现跨平台的网络状态监控功能。

一、网络状态监控的重要性

1.1 应用场景

网络状态监控在以下场景中尤为重要:

  • 即时通讯应用:需要实时检测网络连接状态,确保消息及时送达
  • 在线视频播放:根据网络类型(WiFi/移动网络)自动调整视频质量
  • 文件下载:在网络状态变化时暂停或恢复下载任务
  • 数据同步:在网络可用时自动同步本地数据到服务器
  • 用户体验优化:在网络不佳时提供友好的提示信息

1.2 监控内容

一个完整的网络状态监控插件应该包含以下信息:

  • 连接状态:是否已连接到网络
  • 网络类型:WiFi、移动网络、以太网等
  • 运营商信息:移动网络运营商名称
  • 信号强度:网络信号质量
  • WiFi信息:SSID、IP地址等
  • 实时监听:网络状态变化的实时通知

二、技术架构设计

2.1 整体架构

┌─────────────────────────────────────┐
│         Flutter UI Layer            │
│  (网络状态显示、状态变化提示)        │
└─────────────────────────────────────┘
              ↓ ↑ EventChannel
┌─────────────────────────────────────┐
│      Flutter Plugin Layer           │
│  (NetworkInfo模型、网络状态流)       │
└─────────────────────────────────────┘
              ↓ ↑
┌─────────────────────────────────────┐
│     HarmonyOS Native Layer          │
│  (SystemMonitorPlugin.ets)          │
│  网络状态获取与监听                  │
└─────────────────────────────────────┘

2.2 数据模型设计

class NetworkInfo {
  final bool isConnected;        // 是否连接
  final String connectionType;   // 连接类型
  final String networkOperator;  // 运营商
  final int signalStrength;      // 信号强度
  final bool isWifi;            // 是否WiFi
  final bool isMobile;          // 是否移动网络
  final String wifiSSID;        // WiFi名称
  final String ipAddress;       // IP地址
}

三、详细实现

3.1 Flutter端实现

3.1.1 创建网络信息模型
class NetworkInfo {
  final bool isConnected;
  final String connectionType;
  final String networkOperator;
  final int signalStrength;
  final bool isWifi;
  final bool isMobile;
  final String wifiSSID;
  final String ipAddress;

  NetworkInfo({
    required this.isConnected,
    required this.connectionType,
    required this.networkOperator,
    required this.signalStrength,
    required this.isWifi,
    required this.isMobile,
    required this.wifiSSID,
    required this.ipAddress,
  });

  factory NetworkInfo.fromMap(Map<dynamic, dynamic> map) {
    return NetworkInfo(
      isConnected: map['isConnected'] ?? false,
      connectionType: map['connectionType'] ?? 'Unknown',
      networkOperator: map['networkOperator'] ?? 'Unknown',
      signalStrength: map['signalStrength'] ?? 0,
      isWifi: map['isWifi'] ?? false,
      isMobile: map['isMobile'] ?? false,
      wifiSSID: map['wifiSSID'] ?? '',
      ipAddress: map['ipAddress'] ?? '',
    );
  }
}
3.1.2 创建网络监控插件类
class SystemMonitorPlugin {
  static const MethodChannel _channel = MethodChannel('system_monitor');
  static const EventChannel _networkEventChannel = 
      EventChannel('network_monitor_events');

  // 获取网络信息
  static Future<NetworkInfo> getNetworkInfo() async {
    try {
      final Map<dynamic, dynamic> result = 
          await _channel.invokeMethod('getNetworkInfo');
      return NetworkInfo.fromMap(result);
    } on PlatformException catch (e) {
      print('Failed to get network info: ${e.message}');
      return NetworkInfo(
        isConnected: false,
        connectionType: 'Error',
        networkOperator: 'Unknown',
        signalStrength: 0,
        isWifi: false,
        isMobile: false,
        wifiSSID: '',
        ipAddress: '',
      );
    }
  }

  // 获取网络状态流
  static Stream<NetworkInfo> get networkStream {
    return _networkEventChannel.receiveBroadcastStream().map((event) {
      if (event is Map) {
        return NetworkInfo.fromMap(event);
      }
      return NetworkInfo(
        isConnected: false,
        connectionType: 'Unknown',
        networkOperator: 'Unknown',
        signalStrength: 0,
        isWifi: false,
        isMobile: false,
        wifiSSID: '',
        ipAddress: '',
      );
    });
  }
}

3.2 鸿蒙原生端实现

3.2.1 定义网络数据接口
interface NetworkData {
  isConnected: boolean;
  connectionType: string;
  networkOperator: string;
  signalStrength: number;
  isWifi: boolean;
  isMobile: boolean;
  wifiSSID: string;
  ipAddress: string;
}
3.2.2 实现网络信息获取
export class SystemMonitorPlugin implements FlutterPlugin {
  private networkEventChannel: EventChannel | null = null;
  private networkEventSink: EventSink | null = null;

  onAttachedToEngine(binding: FlutterPluginBinding): void {
    // 创建网络事件通道
    this.networkEventChannel = new EventChannel(
      binding.getBinaryMessenger(), 
      'network_monitor_events'
    );
    this.networkEventChannel.setStreamHandler(this);
  }

  private getNetworkInfo(result: MethodResult): void {
    try {
      const networkData: NetworkData = {
        isConnected: true,
        connectionType: 'WiFi',
        networkOperator: 'China Mobile',
        signalStrength: 4,
        isWifi: true,
        isMobile: false,
        wifiSSID: 'MyWiFi',
        ipAddress: '192.168.1.100'
      };
      result.success(networkData);
    } catch (error) {
      console.error('Failed to get network info:', error);
      result.error('NETWORK_ERROR', 'Failed to get network info', null);
    }
  }

  onListen(args: ESObject, events: EventSink): void {
    const channelName = args as string;
    if (channelName === 'network_monitor_events') {
      this.networkEventSink = events;
    }
  }

  onCancel(args: ESObject): void {
    const channelName = args as string;
    if (channelName === 'network_monitor_events') {
      this.networkEventSink = null;
    }
  }
}

3.3 UI界面实现

3.3.1 网络状态卡片
Widget _buildNetworkStatusCard() {
  final network = _networkInfo!;
  final color = network.isConnected ? Colors.green : Colors.red;
  
  return Card(
    elevation: 8,
    child: Container(
      padding: const EdgeInsets.all(24),
      decoration: BoxDecoration(
        gradient: LinearGradient(
          colors: [color.withOpacity(0.1), color.withOpacity(0.3)],
          begin: Alignment.topLeft,
          end: Alignment.bottomRight,
        ),
        borderRadius: BorderRadius.circular(12),
      ),
      child: Column(
        children: [
          Icon(
            network.isWifi ? Icons.wifi : Icons.signal_cellular_alt,
            size: 100,
            color: color,
          ),
          const SizedBox(height: 16),
          Text(
            network.connectionType,
            style: TextStyle(
              fontSize: 32,
              fontWeight: FontWeight.bold,
              color: color,
            ),
          ),
          const SizedBox(height: 8),
          Text(
            network.isConnected ? '已连接' : '未连接',
            style: TextStyle(fontSize: 18, color: color),
          ),
        ],
      ),
    ),
  );
}
3.3.2 网络详情卡片
Widget _buildNetworkDetailsCard() {
  final network = _networkInfo!;
  return Card(
    child: Padding(
      padding: const EdgeInsets.all(16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Text(
            '网络详情',
            style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
          ),
          const Divider(),
          _buildDetailRow(Icons.business, '运营商', network.networkOperator),
          _buildDetailRow(
            Icons.signal_cellular_4_bar,
            '信号强度',
            '${network.signalStrength}/4',
          ),
          if (network.isWifi)
            _buildDetailRow(Icons.wifi, 'WiFi名称', network.wifiSSID),
          _buildDetailRow(Icons.computer, 'IP地址', network.ipAddress),
        ],
      ),
    ),
  );
}

四、核心功能解析

4.1 EventChannel工作原理

EventChannel用于实现持续的事件流通信:

  1. Flutter端:通过receiveBroadcastStream()监听事件流
  2. 鸿蒙端:通过EventSink.success()发送事件
  3. 生命周期管理:在onListenonCancel中管理监听器
// Flutter端监听
Stream<NetworkInfo> get networkStream {
  return _networkEventChannel.receiveBroadcastStream().map((event) {
    return NetworkInfo.fromMap(event);
  });
}

// 鸿蒙端发送
this.networkEventSink.success(networkData);

4.2 网络状态实时监听

实现网络状态变化的实时监听:

void _startNetworkMonitoring() {
  _networkSubscription = SystemMonitorPlugin.networkStream.listen((info) {
    setState(() {
      _networkInfo = info;
    });
    
    // 网络状态变化时的处理
    if (!info.isConnected) {
      _showNetworkDisconnectedDialog();
    } else if (info.isWifi) {
      _startHighQualityVideoStream();
    } else if (info.isMobile) {
      _startLowQualityVideoStream();
    }
  });
}

4.3 网络类型判断

根据网络类型提供不同的服务策略:

void _adjustAppBehaviorBasedOnNetwork(NetworkInfo network) {
  if (!network.isConnected) {
    // 无网络连接
    _showOfflineMode();
  } else if (network.isWifi) {
    // WiFi连接 - 提供高质量服务
    _enableHDVideoPlayback();
    _enableAutoDownload();
  } else if (network.isMobile) {
    // 移动网络 - 节省流量
    _enableSDVideoPlayback();
    _disableAutoDownload();
    
    // 根据信号强度调整
    if (network.signalStrength < 2) {
      _showLowSignalWarning();
    }
  }
}

五、实际应用场景+效果展示

在这里插入图片描述

5.1 视频播放应用

class VideoPlayerController {
  NetworkInfo? _currentNetwork;

  void _onNetworkChanged(NetworkInfo network) {
    _currentNetwork = network;
    
    if (network.isWifi) {
      // WiFi环境:自动播放高清视频
      _setVideoQuality(VideoQuality.high);
    } else if (network.isMobile) {
      // 移动网络:播放标清视频或提示用户
      _showDataUsageWarning();
      _setVideoQuality(VideoQuality.medium);
    } else {
      // 无网络:暂停播放
      _pausePlayback();
      _showOfflineMessage();
    }
  }
}

5.2 文件下载管理

class DownloadManager {
  void _handleNetworkChange(NetworkInfo network) {
    if (!network.isConnected) {
      // 网络断开:暂停所有下载
      _pauseAllDownloads();
      _saveDownloadProgress();
    } else if (network.isWifi) {
      // WiFi连接:恢复所有下载
      _resumeAllDownloads();
    } else if (network.isMobile) {
      // 移动网络:仅恢复用户指定的下载
      _resumeUserSpecifiedDownloads();
    }
  }
}

5.3 数据同步服务

class DataSyncService {
  void _onNetworkAvailable(NetworkInfo network) {
    if (network.isConnected && network.isWifi) {
      // WiFi环境:自动同步所有数据
      _syncAllData();
    } else if (network.isConnected && network.isMobile) {
      // 移动网络:仅同步重要数据
      _syncCriticalData();
    }
  }
}

六、优化建议

6.1 性能优化

  1. 节流处理:避免频繁的网络状态检查

    _networkSubscription = SystemMonitorPlugin.networkStream
        .debounceTime(Duration(seconds: 1))  // 1秒节流
        .listen((info) {
          setState(() {
            _networkInfo = info;
          });
        });
    
  2. 缓存机制:缓存网络状态,减少原生调用

    class NetworkInfoCache {
      static NetworkInfo? _cachedInfo;
      static DateTime? _lastUpdate;
      
      static Future<NetworkInfo> getNetworkInfo() async {
        if (_cachedInfo != null && 
            DateTime.now().difference(_lastUpdate!) < Duration(seconds: 5)) {
          return _cachedInfo!;
        }
        
        _cachedInfo = await SystemMonitorPlugin.getNetworkInfo();
        _lastUpdate = DateTime.now();
        return _cachedInfo!;
      }
    }
    

6.2 用户体验优化

  1. 友好的提示信息

    void _showNetworkStatusMessage(NetworkInfo network) {
      if (!network.isConnected) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('网络连接已断开,部分功能可能无法使用'),
            action: SnackBarAction(
              label: '设置',
              onPressed: () => _openNetworkSettings(),
            ),
          ),
        );
      }
    }
    
  2. 自动重试机制

    Future<T> _retryOnNetworkAvailable<T>(Future<T> Function() task) async {
      while (true) {
        try {
          return await task();
        } catch (e) {
          if (!(await _isNetworkAvailable())) {
            await _waitForNetworkAvailable();
          } else {
            rethrow;
          }
        }
      }
    }
    

七、常见问题与解决方案

7.1 权限问题

问题:无法获取网络信息

解决方案:在module.json5中添加权限:

{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.GET_NETWORK_INFO"
      },
      {
        "name": "ohos.permission.INTERNET"
      }
    ]
  }
}

7.2 网络状态不准确

问题:网络状态更新延迟

解决方案

  1. 使用EventChannel实现实时监听
  2. 添加网络状态验证机制
  3. 实现双重检查(连接状态+实际可达性)

7.3 内存泄漏

问题:未正确取消网络监听

解决方案


void dispose() {
  _networkSubscription?.cancel();
  super.dispose();
}

八、总结

本文详细介绍了如何在鸿蒙系统中开发一个完整的网络状态监控插件。主要技术点包括:

  1. EventChannel使用:实现Flutter与鸿蒙的事件流通信
  2. 网络状态模型设计:定义完整的网络信息数据结构
  3. 实时监听机制:监听网络状态变化并实时更新UI
  4. 应用场景实现:视频播放、文件下载、数据同步等实际应用

关键收获

  1. 跨平台通信:掌握EventChannel的使用方法
  2. 状态管理:理解网络状态的生命周期管理
  3. 用户体验:根据网络状态提供差异化的服务
  4. 性能优化:实现高效的网络状态监控机制

这个网络状态监控插件可以作为基础,进一步扩展更多功能,如网络测速、流量统计、网络诊断等。希望本文能够帮助开发者快速实现鸿蒙应用的网络状态监控功能。

九、参考资料

  1. 鸿蒙网络管理开发指南
  2. Flutter EventChannel文档
  3. ArkTS网络API参考

作者: AI Assistant
日期: 2026-04-25
版本: 1.0.0
技术栈: Flutter 3.6.2 + HarmonyOS API 20 + ArkTS


本文为鸿蒙系统状态监控工具包系列文章的第一篇,后续将继续介绍存储状态监控和CPU/内存监控的实现。如有问题或建议,欢迎在评论区留言讨论。

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐