引言

在移动应用开发中,网络状态管理是一个看似简单却极易出错的环节。用户可能在 Wi-Fi 和蜂窝网络之间切换,可能进入飞行模式,也可能连接到按流量计费的热点。一个健壮的应用需要感知这些变化并做出合理响应——在网络恢复时自动重试请求,在按流量计费时降低图片质量,在完全断网时展示友好的离线提示。

HarmonyOS NEXT 通过 @ohos.net.connection 模块提供了完整的网络管理能力。它不仅能查询当前的网络连接状态和属性,还能通过事件监听机制实时感知网络变化。本文将构建一个网络诊断中心 Demo,从静态查询到动态监听,全面展示 connection 模块的核心用法。

读完本文,你将掌握:

  • 获取默认网络getDefaultNetSync() 获取当前活跃网络句柄
  • 查询网络能力getNetCapabilitiesSync() 了解带宽、计费模式、接入类型
  • 读取连接属性getConnectionPropertiesSync() 获取 IP 地址、DNS、网卡名称
  • DNS 域名解析getAddressesByName() 将域名解析为 IP 地址
  • 实时网络监听NetConnection.on() 注册 6 种网络事件的回调
  • 所有网络枚举getAllNetsSync() 查看系统中所有可用网络

环境与权限

@ohos.net.connection 属于 NetworkKit 工具包,自 API 8 开始提供。本文 Demo 基于 API 24 编写,使用同步 API 版本(xxxSync)。

需要申请的权限(在 module.json5 中配置):

"requestPermissions": [
  { "name": "ohos.permission.GET_NETWORK_INFO" },  // 获取网络信息
  { "name": "ohos.permission.INTERNET" }            // 访问互联网
]

注意:ohos.permission.GET_NETWORK_INFO 是 normal 级别权限,安装时自动授予;ohos.permission.INTERNET 同样是 normal 级别。这两个权限都不需要用户手动授权,但必须在配置文件中声明。

一、核心数据结构

在深入 API 之前,先了解几个关键的数据类型:

NetHandle — 网络句柄

interface NetHandle {
  netId: number;      // 网络ID,0 表示无默认网络,≥100 表示有效网络
  getAddressesByName(host: string): Promise<Array<NetAddress>>;  // DNS解析
}

NetHandle 是网络的"身份证",通过 getDefaultNetSync() 获取当前活跃网络的句柄,后续的能力查询和属性读取都依赖它。

NetCapabilities — 网络能力

interface NetCapabilities {
  linkUpBandwidthKbps?: number;     // 上行带宽 (Kbps)
  linkDownBandwidthKbps?: number;   // 下行带宽 (Kbps)
  networkCap?: Array<NetCap>;       // 网络能力标志集
  bearerTypes: Array<NetBearType>;  // 承载类型(WiFi/蜂窝/以太网等)
}

NetBearType — 网络承载类型

enum NetBearType {
  BEARER_CELLULAR = 0,   // 蜂窝网络 (4G/5G)
  BEARER_WIFI = 1,       // Wi-Fi
  BEARER_BLUETOOTH = 2,  // 蓝牙共享网络
  BEARER_ETHERNET = 3,   // 以太网
  BEARER_VPN = 4         // VPN
}

NetCap — 网络能力标志

enum NetCap {
  NET_CAPABILITY_MMS = 0,            // 可访问MMSC发送彩信
  NET_CAPABILITY_NOT_METERED = 11,   // 不限流量(非计费网络)
  NET_CAPABILITY_INTERNET = 12,      // 可访问互联网
  NET_CAPABILITY_NOT_VPN = 15,       // 非VPN网络
  NET_CAPABILITY_VALIDATED = 16,     // 网络已验证
  NET_CAPABILITY_PORTAL = 17,        // Portal认证网络
  NET_CAPABILITY_NOT_RESTRICTED = 20,// 不受限制
  NET_CAPABILITY_NOT_CONGESTED = 21  // 不拥塞
}

ConnectionProperties — 连接属性

interface ConnectionProperties {
  interfaceName: string;            // 网卡名称 (如 "wlan0")
  domains: string;                  // 域名搜索域
  linkAddresses: Array<LinkAddress>;// IP地址列表
  dnses: Array<NetAddress>;         // DNS 服务器列表
}

interface LinkAddress {
  address: NetAddress;      // IP地址
  prefixLength: number;     // 前缀长度 (子网掩码)
}

interface NetAddress {
  address: string;          // 地址字符串 (如 "192.168.1.100" 或 "fe80::1")
}

二、静态查询:快照式网络诊断

2.1 获取默认网络

一切网络查询的起点是获取当前默认网络的 NetHandle

import connection from '@ohos.net.connection';

// 先检查是否有可用网络
if (connection.hasDefaultNetSync()) {
  let netHandle = connection.getDefaultNetSync();
  console.log('默认网络ID: ' + netHandle.netId); // 输出如 "100"
}

hasDefaultNetSync() 返回 booleangetDefaultNetSync() 返回 NetHandle。两者都是同步调用,立即返回,不需要回调。

2.2 查询网络能力

拿到 NetHandle 后,查询这个网络的传输能力:

let caps: connection.NetCapabilities =
  connection.getNetCapabilitiesSync(netHandle);

// 判断网络类型
for (let i = 0; i < caps.bearerTypes.length; i++) {
  let type = caps.bearerTypes[i];
  if (type === connection.NetBearType.BEARER_WIFI) {
    console.log('当前连接: Wi-Fi');
  } else if (type === connection.NetBearType.BEARER_CELLULAR) {
    console.log('当前连接: 蜂窝网络');
  }
}

// 判断计费模式
let isMetered = true;
if (caps.networkCap) {
  for (let i = 0; i < caps.networkCap.length; i++) {
    if (caps.networkCap[i] === connection.NetCap.NET_CAPABILITY_NOT_METERED) {
      isMetered = false;  // 找到"不限流量"标志
    }
  }
}
if (isMetered) {
  // 降级策略:降低图片质量、暂停后台同步
}

2.3 读取连接属性

获取 IP 地址、DNS 等网络配置:

let props: connection.ConnectionProperties =
  connection.getConnectionPropertiesSync(netHandle);

// 网卡名称
console.log('网卡: ' + props.interfaceName); // "wlan0"

// IP 地址 — LinkAddress.address.address 直接返回字符串
for (let i = 0; i < props.linkAddresses.length; i++) {
  let ip = props.linkAddresses[i].address.address;
  console.log('IP: ' + ip); // "192.168.1.100"
}

// DNS 服务器 — NetAddress.address 已是字符串
for (let i = 0; i < props.dnses.length; i++) {
  console.log('DNS: ' + props.dnses[i].address);
}

2.4 枚举所有网络

系统可能同时存在多个网络接口(如 Wi-Fi + 蜂窝数据同时开启)。getAllNetsSync() 返回所有网络句柄:

let allNets = connection.getAllNetsSync();
console.log('共找到 ' + allNets.length + ' 个网络');

for (let i = 0; i < allNets.length; i++) {
  let caps = connection.getNetCapabilitiesSync(allNets[i]);
  // 逐个检查每个网络的能力
}

在这里插入图片描述
在这里插入图片描述

三、动态监听:实时感知网络变化

静态查询只能获取当前快照,而 NetConnection 的监听机制可以实时感知网络事件。

3.1 创建监听器

let netConnection = connection.createNetConnection();

createNetConnection() 接受两个可选参数:

  • netSpecifier?: NetSpecifier — 指定要监听的网络类型(如只监听 Wi-Fi)
  • timeout?: number — 超时时间(毫秒),超时后触发 netUnavailable

3.2 注册 6 种事件回调

NetConnection 提供了 6 种事件类型:

// 1. netAvailable — 网络变得可用
netConnection.on('netAvailable', (netHandle: connection.NetHandle) => {
  console.log('网络可用, netId=' + netHandle.netId);
});

// 2. netCapabilitiesChange — 网络能力发生变化(如带宽变更)
netConnection.on('netCapabilitiesChange', (info: connection.NetCapabilityInfo) => {
  let types = info.netCap.bearerTypes;
  console.log('网络能力变更: ' + types.length + ' 个承载类型');
});

// 3. netConnectionPropertiesChange — 连接属性变更(如IP变更)
netConnection.on('netConnectionPropertiesChange',
  (info: connection.NetConnectionPropertyInfo) => {
    console.log('连接属性更新: ' + info.connectionProperties.interfaceName);
});

// 4. netLost — 网络丢失
netConnection.on('netLost', (netHandle: connection.NetHandle) => {
  console.log('网络丢失, netId=' + netHandle.netId);
});

// 5. netUnavailable — 网络不可用(超时未找到合适网络)
netConnection.on('netUnavailable', () => {
  console.log('无可用网络');
});

// 6. netBlockStatusChange — 网络阻塞状态变化
netConnection.on('netBlockStatusChange', (info: connection.NetBlockStatusInfo) => {
  console.log('阻塞状态: ' + (info.blocked ? '已阻塞' : '已恢复'));
});

3.3 激活与注销监听

注册回调后,必须调用 register() 激活监听,不需要时调用 unregister() 释放资源:

// 激活监听
netConnection.register((err) => {
  if (err) {
    console.error('注册监听失败: ' + JSON.stringify(err));
  } else {
    console.log('网络监听已启动');
  }
});

// 停止监听
netConnection.unregister((err) => {
  if (err) {
    console.error('注销监听失败: ' + JSON.stringify(err));
  } else {
    console.log('网络监听已停止');
  }
});

四、DNS 域名解析

connection 模块还内置了 DNS 解析功能,通过 getAddressesByName() 将域名解析为 IP:

connection.getAddressesByName('www.example.com', (err, addresses) => {
  if (err) {
    console.error('DNS解析失败: ' + JSON.stringify(err));
    return;
  }
  for (let i = 0; i < addresses.length; i++) {
    console.log('解析结果: ' + addresses[i].address);
    // addresses[i].address 是字符串,如 "93.184.216.34"
  }
});

getAddressesByName() 是异步方法,使用回调返回结果。还有一个同步版本 getAddressesByNameWithOptions() 返回 Promise,支持 QueryOptions 参数控制超时和 DNS 服务器。

五、实战 Demo:网络诊断中心

页面结构

Demo 页面 NetDiagnosticPage.ets 整合了上述全部功能,提供可视化的网络诊断体验:

网络诊断中心
├── 状态栏 — 实时操作反馈
├── 网络概况
│   ├── 三列概览 — 网络类型 / 连接状态 / 可用网络数
│   ├── 刷新状态 按钮 — 重新拉取所有网络信息
│   └── 开启监听 按钮 — 启动/停止 NetConnection 事件监听
├── 连接属性 — 网卡名称 / IP地址 / DNS / 域名
├── 网络能力 — 承载类型 / 上下行带宽 / 计费模式 / 互联网访问
├── DNS解析测试 — 域名输入 + 解析按钮 + 结果展示
├── 网络事件日志 — 最近20条事件(含时间戳和事件类型)
└── 核心 API 参考 — 12 个关键 API

4 个交互点

  1. 刷新网络状态 — 调用 getDefaultNetSync() + getNetCapabilitiesSync() + getConnectionPropertiesSync(),一次性获取并展示当前网络的全部诊断信息

  2. 开启/停止网络监听 — 创建 NetConnection 实例,注册 6 种事件回调,激活后每个网络事件都会在日志面板中实时显示

  3. DNS 解析测试 — 输入域名,调用 getAddressesByName() 进行解析,展示所有解析到的 IP 地址

  4. 查看事件日志 — 监听开启期间,所有 netAvailablenetLostnetCapabilitiesChange 等事件都记录在日志列表中,可追溯网络变化历史

核心代码位置

完整代码在 dev/entry/src/main/ets/pages/NetDiagnosticPage.ets(约 390 行),路由已注册为 pages/NetDiagnosticPage

六、三种 API 调用模式的选择

connection 模块大部分操作同时支持 Callback 异步、Promise 异步和同步 Sync 三种模式。以 getNetCapabilities 为例:

// 方式1:Callback
connection.getNetCapabilities(netHandle, (err, caps) => {
  if (err) return;
  let types = caps.bearerTypes;
});

// 方式2:Promise
connection.getNetCapabilities(netHandle).then((caps) => {
  let types = caps.bearerTypes;
}).catch((err) => { console.error(err); });

// 方式3:Sync(Demo 推荐)
let caps = connection.getNetCapabilitiesSync(netHandle);
let types = caps.bearerTypes;

选择建议:

场景 推荐方式 原因
UI 初始化/手动刷新 同步 Sync 代码简洁直观,数据量小,无明显阻塞
后台定时轮询 Promise 异步 不阻塞主线程
大文件上传前的网络检查 Callback 异步 兼容旧版 API
事件监听 NetConnection.on() 原生异步事件驱动

七、常见问题

1. hasDefaultNetSync() 返回 false

这意味着设备当前没有活跃的数据网络:

  • 检查 Wi-Fi 是否已连接
  • 检查蜂窝数据是否开启
  • 是否处于飞行模式
  • 模拟器默认网络连接通常正常

2. 获取到的 linkAddresses 为空数组

设备的网络接口可能尚未完成 DHCP 地址分配。在 netAvailable 事件触发后稍等片刻再查,或使用 netConnectionPropertiesChange 回调来接收 IP 分配完成的通知。

3. NetBearType 数组包含多个值

这是正常的。例如设备可能同时通过 Wi-Fi (BEARER_WIFI=1) 和 VPN (BEARER_VPN=4) 传输数据。bearerTypes 数组的第一元素通常是主要网络类型。

4. register() 回调报错

确保:

  • module.json5 中声明了 ohos.permission.GET_NETWORK_INFO
  • 没有重复注册同一个 NetConnection 实例(需先 unregister 再重新 register
  • 页面销毁前调用 unregister() 释放资源

八、与 zlib/cryptoFramework 的 API 设计对比

connection 模块延续了 HarmonyOS 系统 API 的统一设计哲学:

模式 zlib cryptoFramework connection
同步查询 statSync() (file.fs) digestSync() getDefaultNetSync()
异步操作 compressFile() (Promise) digest() (Promise/Callback) getAddressesByName() (Callback)
事件监听 NetConnection.on()
资源管理 无(无状态) 无(无状态) register() / unregister()

connection 模块特有的 事件监听模式 使其区别于纯函数式的 zlib 和 cryptoFramework——它不仅是"工具",更是"服务",需要在生命周期内管理注册与注销。

九、最佳实践:网络感知的应用架构

基于 connection 模块,可以构建一个应用级的网络感知层:

// NetworkManager.ets — 全局单例
export class NetworkManager {
  private static instance: NetworkManager;
  private conn: connection.NetConnection;
  public isOnline: boolean = false;
  public isMetered: boolean = false;
  public netType: string = 'unknown';

  static getInstance(): NetworkManager { /* 单例实现 */ }

  startListen(): void {
    this.conn = connection.createNetConnection();
    this.conn.on('netAvailable', (h) => { this.isOnline = true; });
    this.conn.on('netLost', () => { this.isOnline = false; });
    this.conn.on('netCapabilitiesChange', (info) => {
      this.isMetered = this.checkMetered(info.netCap);
      this.netType = this.getTypeName(info.netCap);
    });
    this.conn.register((err) => { if (!err) console.log('NetworkManager ready'); });
  }

  destroy(): void {
    this.conn?.unregister(() => {});
  }
}

各页面在使用网络前检查 NetworkManager.getInstance().isOnline,在计费网络下降低流量消耗,实现优雅的全态网络体验。

十、总结

@ohos.net.connection 为 HarmonyOS NEXT 应用提供了完善的网络管理能力:

  1. 静态快照getDefaultNetSync() + getNetCapabilitiesSync() + getConnectionPropertiesSync() 三步获取完整网络视图
  2. 网络类型判断 — 5 种 NetBearType(WiFi/蜂窝/蓝牙/以太网/VPN)
  3. 计费感知 — 12 种 NetCap 标志,精准判断流量计费
  4. 连接细节 — IP 地址、DNS 服务器、网卡名称、域名域
  5. DNS 解析getAddressesByName() 内置域名解析
  6. 实时监听NetConnection + 6 种事件回调 + register/unregister 生命周期管理
  7. 多网络枚举getAllNetsSync() 查看所有可用接口

这套能力让你能够构建网络感知型的应用架构——在网络波动时优雅降级,在恢复连接时自动重试,在计费网络下珍惜用户的每一 KB 流量。


Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐