网络状态监听:NetworkUtil实现鸿蒙应用智能网络感知

【免费下载链接】harmony-utils harmony-utils 一款功能丰富且极易上手的HarmonyOS工具库,借助众多实用工具类,致力于助力开发者迅速构建鸿蒙应用。其封装的工具涵盖了APP、设备、屏幕、授权、通知、线程间通信、弹框、吐司、生物认证、用户首选项、拍照、相册、扫码、文件、日志,异常捕获、字符、字符串、数字、集合、日期、随机、base64、加密、解密、JSON等一系列的功能和操作,能够满足各种不同的开发需求。 【免费下载链接】harmony-utils 项目地址: https://gitcode.com/tongzhanglao/harmony-utils

引言:网络感知的痛点与挑战

在移动应用开发中,网络状态管理一直是开发者面临的核心挑战。你是否遇到过这些场景:

  • 用户从Wi-Fi切换到移动数据时,应用没有及时感知,导致视频卡顿或数据流量消耗
  • 网络断开时应用没有友好提示,用户操作无响应却不知原因
  • 需要根据网络类型智能调整数据加载策略,但缺乏准确的网络类型判断
  • 多SIM卡设备下无法准确获取当前使用的网络信息

鸿蒙系统的harmony-utils工具库中的NetworkUtil类正是为解决这些痛点而生,它提供了全面、精准的网络状态监听和管理能力。

NetworkUtil核心功能全景图

mermaid

快速入门:基础网络状态检测

环境配置与权限申请

首先在module.json5中配置所需权限:

{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.GET_NETWORK_INFO",
        "reason": "获取网络状态信息"
      },
      {
        "name": "ohos.permission.GET_WIFI_INFO", 
        "reason": "获取Wi-Fi连接信息"
      }
    ]
  }
}

基础网络状态检查

import { NetworkUtil } from '@pura/harmony-utils'

// 检查网络是否可用
const isAvailable = NetworkUtil.isNetworkAvailable()
console.log(`网络可用: ${isAvailable}`)

// 检查具体网络类型
const hasWifi = NetworkUtil.hasNetWiFi()
const hasMobile = NetworkUtil.hasNetMobile() 
const hasEthernet = NetworkUtil.hasNetEthernet()
const hasPrivate = NetworkUtil.hasNetPrivate()

console.log(`Wi-Fi: ${hasWifi}, 移动网络: ${hasMobile}, 以太网: ${hasEthernet}, 专用网络: ${hasPrivate}`)

// 获取详细网络类型
const networkType = await NetworkUtil.getNetworkTypeStr()
console.log(`当前网络类型: ${networkType}`) // 输出: Wi-Fi、2G、3G、4G、5G

深度解析:实时网络状态监听

网络事件监听机制

mermaid

完整监听示例代码

import { NetworkUtil } from '@pura/harmony-utils'
import { connection } from '@kit.NetworkKit'

class NetworkManager {
  private isMonitoring = false

  // 开始网络状态监听
  startNetworkMonitoring() {
    if (this.isMonitoring) return

    NetworkUtil.register(
      // 网络可用回调
      (netHandle: connection.NetHandle) => {
        console.log('网络已连接', netHandle)
        this.onNetworkAvailable()
      },
      // 网络不可用回调  
      () => {
        console.log('网络已断开')
        this.onNetworkUnavailable()
      },
      // 网络能力变化回调
      (capabilityInfo: connection.NetCapabilityInfo) => {
        console.log('网络能力发生变化', capabilityInfo)
        this.onNetworkCapabilityChange(capabilityInfo)
      },
      // 网络连接属性变化回调
      (propertyInfo: connection.NetConnectionPropertyInfo) => {
        console.log('网络连接属性变化', propertyInfo)
        this.onConnectionPropertyChange(propertyInfo)
      }
    )

    this.isMonitoring = true
  }

  // 停止监听
  stopNetworkMonitoring() {
    if (!this.isMonitoring) return
    NetworkUtil.unregister()
    this.isMonitoring = false
  }

  private onNetworkAvailable() {
    // 网络恢复后的处理逻辑
    this.resumeNetworkOperations()
    this.showNetworkStatus('网络已恢复')
  }

  private onNetworkUnavailable() {
    // 网络断开处理
    this.pauseNetworkOperations()
    this.showNetworkStatus('网络连接已断开')
  }

  private onNetworkCapabilityChange(info: connection.NetCapabilityInfo) {
    // 网络类型切换处理
    const networkType = this.getNetworkTypeFromCapabilities(info.netCapabilities)
    this.adjustStrategyBasedOnNetwork(networkType)
  }

  private onConnectionPropertyChange(info: connection.NetConnectionPropertyInfo) {
    // 连接属性变化处理
    console.log('连接属性变化:', info.connectionProperties)
  }
}

高级功能:移动网络深度管理

SIM卡与运营商信息

// 获取SIM卡信息
const simCount = NetworkUtil.getMaxSimCount()
console.log(`设备支持 ${simCount} 张SIM卡`)

// 获取主卡槽信息
const primarySlotId = await NetworkUtil.getPrimarySlotId()
const operatorName = await NetworkUtil.getOperatorName(primarySlotId)
const simState = await NetworkUtil.getSimState(primarySlotId)

console.log(`主卡槽: ${primarySlotId}, 运营商: ${operatorName}, SIM状态: ${simState}`)

// 检查所有SIM卡状态
for (let slotId = 0; slotId < simCount; slotId++) {
  const hasCard = await NetworkUtil.hasSimCard(slotId)
  const isActive = await NetworkUtil.isSimActive(slotId)
  
  if (hasCard && isActive) {
    const operator = await NetworkUtil.getOperatorName(slotId)
    console.log(`卡槽 ${slotId}: ${operator} - 已激活`)
  }
}

信号强度与网络质量监控

// 获取信号强度信息
async function monitorSignalStrength() {
  try {
    const signalInfo = await NetworkUtil.getSignalInformation()
    
    signalInfo.forEach(signal => {
      console.log(`信号类型: ${signal.signalType}, 电平值: ${signal.signalLevel}`)
      
      // 根据信号强度调整应用行为
      if (signal.signalLevel < -110) {
        this.reduceDataUsage() // 信号弱时减少数据使用
      } else if (signal.signalLevel > -80) {
        this.enableHighQuality() // 信号强时启用高质量模式
      }
    })
  } catch (error) {
    console.error('获取信号信息失败:', error)
  }
}

// 定时监控网络质量
setInterval(() => {
  this.monitorSignalStrength()
  this.checkNetworkPerformance()
}, 30000) // 每30秒检查一次

实战应用场景

场景一:智能数据加载策略

class SmartDataLoader {
  async loadData(url: string) {
    const networkType = await NetworkUtil.getNetworkTypeStr()
    
    switch(networkType) {
      case 'Wi-Fi':
        return this.loadHighQualityData(url) // WiFi下加载高质量数据
      case '5G':
        return this.loadStandardData(url)    // 5G下加载标准质量
      case '4G':
        return this.loadCompressedData(url)  // 4G下加载压缩数据
      case '3G':
      case '2G':
        return this.loadMinimalData(url)     // 2G/3G下加载最小数据
      default:
        return this.loadFallbackData(url)    // 未知网络下使用降级方案
    }
  }
}

场景二:离线模式智能切换

class OfflineManager {
  private wasOnline = true

  constructor() {
    this.setupNetworkListeners()
  }

  private setupNetworkListeners() {
    NetworkUtil.register(
      (netHandle) => {
        if (!this.wasOnline) {
          this.onReconnect(netHandle)
        }
        this.wasOnline = true
      },
      () => {
        this.wasOnline = false
        this.enableOfflineMode()
      }
    )
  }

  private onReconnect(netHandle: connection.NetHandle) {
    console.log('网络重新连接,同步离线数据')
    this.syncOfflineData()
    this.disableOfflineMode()
  }
}

场景三:网络诊断与用户体验优化

class NetworkDiagnostic {
  async performNetworkCheck() {
    const results = {
      hasNetwork: NetworkUtil.isNetworkAvailable(),
      networkType: await NetworkUtil.getNetworkTypeStr(),
      isMetered: await NetworkUtil.isDefaultNetMetered(),
      ipAddress: NetworkUtil.getIpAddress(),
      signalStrength: await this.getSignalQuality()
    }

    // 根据诊断结果给出优化建议
    this.provideOptimizationSuggestions(results)
    
    return results
  }

  private async getSignalQuality() {
    try {
      const signals = await NetworkUtil.getSignalInformation()
      return signals.map(s => ({
        type: s.signalType,
        level: s.signalLevel,
        quality: this.calculateQuality(s.signalLevel)
      }))
    } catch (error) {
      return []
    }
  }
}

性能优化与最佳实践

监听器管理策略

class OptimizedNetworkMonitor {
  private listeners = new Set<Function>()
  private isGlobalMonitoring = false

  // 按需注册监听,避免重复注册
  addListener(callback: Function) {
    this.listeners.add(callback)
    
    if (!this.isGlobalMonitoring && this.listeners.size > 0) {
      this.startGlobalMonitoring()
    }
    
    return () => this.removeListener(callback)
  }

  removeListener(callback: Function) {
    this.listeners.delete(callback)
    
    if (this.listeners.size === 0) {
      this.stopGlobalMonitoring()
    }
  }

  private startGlobalMonitoring() {
    NetworkUtil.register(
      (netHandle) => this.notifyAll('available', netHandle),
      () => this.notifyAll('unavailable'),
      (info) => this.notifyAll('capabilityChange', info)
    )
    this.isGlobalMonitoring = true
  }

  private notifyAll(event: string, ...args: any[]) {
    this.listeners.forEach(listener => {
      try {
        listener(event, ...args)
      } catch (error) {
        console.error('Listener error:', error)
      }
    })
  }
}

网络请求重试机制

class SmartRetryHandler {
  private retryConfig = {
    maxRetries: 3,
    baseDelay: 1000,
    maxDelay: 10000
  }

  async withRetry<T>(operation: () => Promise<T>): Promise<T> {
    let lastError: Error
    let attempt = 0

    while (attempt < this.retryConfig.maxRetries) {
      try {
        // 检查网络状态后再重试
        if (!NetworkUtil.isNetworkAvailable()) {
          await this.waitForNetwork()
          continue
        }

        return await operation()
      } catch (error) {
        lastError = error
        attempt++
        
        if (attempt < this.retryConfig.maxRetries) {
          const delay = this.calculateDelay(attempt)
          await this.delay(delay)
        }
      }
    }

    throw lastError!
  }

  private async waitForNetwork(): Promise<void> {
    return new Promise(resolve => {
      const unsubscribe = NetworkUtil.register(
        () => {
          unsubscribe()
          resolve()
        }
      )
      
      // 超时处理
      setTimeout(() => {
        unsubscribe()
        resolve()
      }, 30000)
    })
  }
}

常见问题与解决方案

权限申请失败处理

async function checkNetworkPermissions() {
  try {
    // 尝试网络操作
    const hasNet = NetworkUtil.hasDefaultNetSync()
    return true
  } catch (error) {
    if (error.code === 201) { // 权限错误代码
      console.warn('网络权限未授予,引导用户开启')
      this.guideToPermissionSettings()
      return false
    }
    throw error
  }
}

网络状态同步问题

// 解决网络状态获取的异步同步问题
class NetworkStateCache {
  private cache = {
    isOnline: false,
    networkType: 'UNKNOWN',
    lastUpdated: 0
  }

  async getNetworkState() {
    // 缓存有效期内使用缓存
    if (Date.now() - this.cache.lastUpdated < 5000) {
      return this.cache
    }

    // 更新缓存
    const [isOnline, networkType] = await Promise.all([
      NetworkUtil.isNetworkAvailable(),
      NetworkUtil.getNetworkTypeStr()
    ])

    this.cache = {
      isOnline,
      networkType,
      lastUpdated: Date.now()
    }

    return this.cache
  }
}

总结与展望

NetworkUtil作为harmony-utils工具库的核心组件,为鸿蒙应用开发者提供了强大而完善的网络状态管理能力。通过本文的详细介绍,你应该已经掌握:

  1. 基础网络检测 - 快速判断网络可用性和类型
  2. 实时状态监听 - 精准捕获网络变化事件
  3. 移动网络管理 - 深度获取SIM卡和信号信息
  4. 智能策略调整 - 根据网络条件优化应用行为
  5. 性能优化实践 - 高效管理监听器和网络请求

在实际项目中,合理运用NetworkUtil可以显著提升应用的网络感知能力和用户体验。随着鸿蒙生态的不断发展,网络状态管理将变得更加重要,NetworkUtil也会持续演进,为开发者提供更强大的网络编程能力。

记住:良好的网络感知不仅是技术实现,更是用户体验的重要组成部分。通过智能的网络状态管理,让你的应用在各种网络环境下都能提供流畅、稳定的服务。

【免费下载链接】harmony-utils harmony-utils 一款功能丰富且极易上手的HarmonyOS工具库,借助众多实用工具类,致力于助力开发者迅速构建鸿蒙应用。其封装的工具涵盖了APP、设备、屏幕、授权、通知、线程间通信、弹框、吐司、生物认证、用户首选项、拍照、相册、扫码、文件、日志,异常捕获、字符、字符串、数字、集合、日期、随机、base64、加密、解密、JSON等一系列的功能和操作,能够满足各种不同的开发需求。 【免费下载链接】harmony-utils 项目地址: https://gitcode.com/tongzhanglao/harmony-utils

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐