鸿蒙新特性实战:net.connection 网络诊断 — 状态监测、能力查询与实时监听
引言
在移动应用开发中,网络状态管理是一个看似简单却极易出错的环节。用户可能在 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() 返回 boolean,getDefaultNetSync() 返回 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 个交互点
-
刷新网络状态 — 调用
getDefaultNetSync()+getNetCapabilitiesSync()+getConnectionPropertiesSync(),一次性获取并展示当前网络的全部诊断信息 -
开启/停止网络监听 — 创建
NetConnection实例,注册 6 种事件回调,激活后每个网络事件都会在日志面板中实时显示 -
DNS 解析测试 — 输入域名,调用
getAddressesByName()进行解析,展示所有解析到的 IP 地址 -
查看事件日志 — 监听开启期间,所有
netAvailable、netLost、netCapabilitiesChange等事件都记录在日志列表中,可追溯网络变化历史
核心代码位置
完整代码在 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 应用提供了完善的网络管理能力:
- 静态快照 —
getDefaultNetSync()+getNetCapabilitiesSync()+getConnectionPropertiesSync()三步获取完整网络视图 - 网络类型判断 — 5 种
NetBearType(WiFi/蜂窝/蓝牙/以太网/VPN) - 计费感知 — 12 种
NetCap标志,精准判断流量计费 - 连接细节 — IP 地址、DNS 服务器、网卡名称、域名域
- DNS 解析 —
getAddressesByName()内置域名解析 - 实时监听 —
NetConnection+ 6 种事件回调 + register/unregister 生命周期管理 - 多网络枚举 —
getAllNetsSync()查看所有可用接口
这套能力让你能够构建网络感知型的应用架构——在网络波动时优雅降级,在恢复连接时自动重试,在计费网络下珍惜用户的每一 KB 流量。
更多推荐



所有评论(0)