简介

在鸿蒙项目开发中,网络管理扮演着举足轻重的角色。本文将基于API 11,深入剖析鸿蒙网络管理的核心技术,帮助开发者精准把握网络状态,打造流畅且用户友好的应用体验。

在鸿蒙应用中,实时监测网络状态是确保应用稳定性和用户体验的关键。网络状态的变化,如从Wi-Fi切换到移动数据,或从有网络状态变为无网络状态,都需要应用做出相应的调整。例如,应用可以暂停正在进行的操作,或向用户发出提醒,以确保应用在各种网络环境下都能稳定运行。

一、实时监测网络状态,智能响应变化

在鸿蒙项目中,构建一个高效的网络管理类是实现流畅应用体验的核心环节。这个管理类能够实时监控网络状态,并在状态发生变化时迅速响应。接下来,我们将深入讨论如何设计一个符合专业要求的网络管理类。

首先,我们定义了网络连接状态变化时的回调函数类型,以便在网络状态变化时能够灵活地执行相应的处理逻辑。

/**
 * 网络连接状态变化回调函数的类型定义
 */
export type NetworkStatusCallback = (status: NetworkType) => void;

接着,我们利用枚举类型来定义不同的网络状态,使得代码更加清晰、易读且易于维护。

/**
 * 枚举:网络类型
 * 用于标识当前的网络连接状态
 */
export enum NetworkType {
  STATE_NULL = 'NULL', // 表示未联网状态
  UNKNOWN = 'UNKNOWN', // 未知网络类型
  MOBILE = 'MOBILE',   // 移动网络
  WIFI = 'WIFI',       // Wi-Fi网络
  ETHERNET = 'ETHERNET' // 以太网网络(尽管移动设备通常不支持,但为完整性保留)
}

/**
 * 枚举:承载类型(内部使用)
 * 与具体平台的API对接,用于标识网络连接的承载类型
 */
enum BearerType {
  MOBILE = 0,
  WIFI = 1,
  // ... 其他可能的承载类型,根据平台API添加
  ETHERNET = 3
}

随后,我们定义了一些私有变量来存储网络管理类的内部状态信息,以及用于与外部交互的回调函数的集合。

class LibNetworkStatus {
  /**
   * LibNetworkStatus单例实例
   * 保证全局只有一个网络管理类实例
   */
  private static instance: LibNetworkStatus;

  /**
   * 当前网络状态
   * 存储当前的网络连接状态
   */
  private currentNetworkStatus: NetworkType = NetworkType.STATE_NULL;

  /**
   * 网络是否可用
   * 标识当前是否有可用的网络连接
   */
  private isNetworkAvailable: boolean = false;

  /**
   * 鸿蒙网络连接对象
   * 用于与鸿蒙系统的网络API进行交互
   */
  private networkConnection?: Connection;

  /**
   * 存储网络连接状态变化回调函数的集合
   * 当网络状态发生变化时,会遍历此集合并调用相应的回调函数
   */
  private callbacks: Set<NetworkStatusCallback> = new Set();

  // 类的构造函数、方法以及其他逻辑实现将在这里继续...
}

通过定义这些变量和回调方法类型,我们为网络管理类的实现奠定了坚实的基础。接下来,我们将进一步实现监听网络状态变化、更新网络状态以及调用回调函数通知应用等核心功能。这些功能的实现将确保我们的网络管理类能够实时、准确地掌握网络状态,并根据状态变化做出相应的处理,从而提升应用的稳定性和用户体验。

二、构建基础回调方法,实现精细化的回调管理

为了确保我们的网络管理系统能够高效且准确地通知应用关于网络状态的变化,我们需要构建一套完善的回调机制。这套机制将允许应用在网络状态变化时及时做出响应,从而提升用户体验。

/**
 * 添加回调方法,用于监听网络状态变化
 *
 * @param callback 监听网络状态变化的回调函数
 * @param isCallBackCurrentNetworkStatus 是否立即调用回调并返回当前网络状态
 */
addCallback(callback: NetworkStatusCallback, isCallBackCurrentNetworkStatus: boolean): void {
  if (!callback || !this.callbacks) {
    return;
  }

  // 确保回调方法未被重复添加
  if (this.callbacks.has(callback)) {
    return;
  }

  this.callbacks.add(callback);

  // 如果需要,立即调用回调并返回当前网络状态
  if (isCallBackCurrentNetworkStatus) {
    callback(this.currentNetworkStatus);
  }
}

/**
 * 移除指定的回调方法
 *
 * @param callback 需要移除的回调方法
 */
removeCallback(callback: NetworkStatusCallback): void {
  if (!callback || !this.callbacks || !this.callbacks.has(callback)) {
    return;
  }

  this.callbacks.delete(callback);
}

/**
 * 通知所有注册的回调方法当前的网络状态
 *
 * 当网络状态发生变化时,此方法将被调用,以通知所有注册的回调方法
 */
callbackNetworkStatus(): void {
  if (!this.callbacks || this.callbacks.size === 0) {
    return;
  }

  // 遍历所有注册的回调方法,并调用它们,传递当前网络状态
  this.callbacks.forEach(callback => {
    callback(this.currentNetworkStatus);
  });
}

代码分析

  • 回调方法添加与移除:我定义了两个方法addCallbackremoveCallback,用于添加和移除监听网络状态变化的回调方法。这确保了应用的灵活性和可扩展性,因为应用可以根据需要在运行时动态地添加或移除回调。
  • 回调方法管理:使用Set数据结构来管理回调方法,这确保了回调方法的唯一性,避免了重复调用和潜在的内存泄漏问题。
  • 立即回调机制:在addCallback方法中,我们提供了一个选项isCallBackCurrentNetworkStatus,允许在添加回调时立即调用该回调并返回当前的网络状态。这为那些需要立即知道当前网络状态的应用提供了方便。
  • 状态通知callbackNetworkStatus方法负责在网络状态发生变化时通知所有注册的回调方法。通过遍历Set中的每个回调方法并调用它们,我们确保了所有感兴趣的应用部分都能及时收到网络状态变化的通知。

三、网络相关的核心方法

1、获取网络状态信息

在构建网络管理类时,提供一套准确且高效的网络状态获取方法至关重要。这些方法允许我们实时地监控网络情况,并根据不同的网络状态做出相应的处理。接下来,我们将详细介绍这些核心方法。

/**
 * 检查当前网络是否可用
 *
 * @returns 返回一个布尔值,指示当前网络是否可用
 */
isNetworkAvailable(): boolean {
  return this.isNetworkAvailable;
}

/**
 * 获取当前的网络状态
 *
 * @returns 返回当前的网络状态码
 */
getCurrentNetworkStatus(): NetworkType {
  return this.currentNetworkStatus;
}

2、精准检测并获取当前网络类型

/**
 * 获取当前的网络类型
 *
 * 此方法通过调用系统API获取当前网络状态,并根据承载类型确定网络类型。
 * 通过精准的判断逻辑,确保获取到的网络类型准确无误。
 */

getDefaultNetSync () {
  //获得当前网络状态
  let netHandle = connection.getDefaultNetSync()
  if (netHandle) {
    let capabilities = connection.getNetCapabilitiesSync(netHandle)
    LibLogManager.getLogger().debug(TAG,'getNetCapabilitiesSync:' + JSON.stringify(capabilities))
    if (capabilities && capabilities.bearerTypes && capabilities.bearerTypes.length > 0) {

      // 获取第一个承载类型
      const bearerType = capabilities.bearerTypes[0];
      // 根据承载类型判断网络类型
      switch (bearerType) {
        case BearerType.MOBILE.valueOf():
        // 蜂窝网络
          
          this.currentNetworkStatus =  NetworkType.MOBILE;
              break;
        case BearerType.WIFI.valueOf():
        // Wi-Fi网络
          
          this.currentNetworkStatus =  NetworkType.WIFI;
          break;
        case BearerType.ETHERNET.valueOf():
        // 以太网网络(通常移动设备不支持,但为完整性保留)
          
          this.currentNetworkStatus =  NetworkType.ETHERNET;
          break;
        default:
        // 未知网络类型
         
          this.currentNetworkStatus =  NetworkType.UNKNOWN;
          break;
      }

    }
  }
}

代码分析:

  • 使用getNetCapabilitiesSync方法获取网络能力信息,包括承载类型列表。

3、注册监听手机网络状态变化

首先,我们需要理解网络状态变化的几种主要类型:从无网络到有网络、从有网络到无网络、以及从一种网络类型切换到另一种网络类型(如从Wi-Fi切换到蜂窝数据)。这些状态变化都需要应用进行相应的处理,比如重新加载数据、暂停某些操作或者提示用户当前的网络状态。

/**
 * 注册网络状态监听:
 * 设备从无网络到有网络会触发"netAvailable"、"netCapabilitiesChange"、"netConnectionPropertiesChange"事件;
 * 设备从有网络到无网络会触发"netLost"事件
 * 设备从wifi到蜂窝网络会触发"netLost"事件(wifi不可用)、之后触发"netAvailable"事件(蜂窝可用)
 */
registerNetConnectListener () {
  if (this.networkConnectio) {
    console.debug(TAG,'已订阅网络事件,无需再次订阅')
    return
  }

  //创建NetConnection对象
  this.networkConnectio = connection.createNetConnection()

  //判断默认网络状态
  let hasDefaultNet = connection.hasDefaultNetSync()
  if (hasDefaultNet) {
    console.debug(TAG,'hasDefaultNetSync  ' + hasDefaultNet)
    this.isAvailable = true
    //获得默认网络类型
    this.getDefaultNetSync()
  }

  //注册
  this.networkConnectio.register((error) => {
    if (error) {
      console.debug(TAG,'networkConnectio.register failure: ' + JSON.stringify(error))
    } else {
      console.debug(TAG,' networkConnectio.register success')
    }
  })

  //订阅网络可用事件
  console.debug(TAG,'订阅网络可用事件-->')
  this.networkConnectio.on('netAvailable', (data: connection.NetHandle) => {
    LibLogManager.getLogger().debug(TAG,'netAvailable:' + JSON.stringify(data))
    this.isAvailable = true

    //获得默认网络类型
    this.getDefaultNetSync()

    //回调网络状态
    this.callbackNetworkStatus()
  })

  //订阅网络丢失事件
  console.debug(TAG,'订阅网络丢失事件-->')
  this.networkConnectio.on('netLost', (data: connection.NetHandle) => {
    console.debug(TAG,'netLost:' + JSON.stringify(data))
    this.isAvailable = false
    this.currentNetworkStatus = NetworkType.STATE_NULL

    //回调网络状态
    this.callbackNetworkStatus()
  })

  //订阅网络不可用事件
  console.debug(TAG,'订阅网络不可用事件-->')
  this.networkConnectio.on('netUnavailable', () => {
    LibLogManager.getLogger().debug(TAG,'netUnavailable')
    this.isAvailable = false
    this.currentNetworkStatus = NetworkType.STATE_NULL

    //回调网络状态
    this.callbackNetworkStatus()
  })
}

综上所述,鸿蒙网络管理功能为开发者提供了强大的支持,帮助我们精准把握网络状态,打造流畅且用户友好的应用体验。通过深入了解鸿蒙网络管理的核心技术,我们可以更好地应对各种网络环境下的挑战,为用户带来更好的使用体验。