第24章 HarmonyOs开发图解之 网络管理
HarmonyOS 学习系统 | 阶段四:专业精通期
学习目标
| 序号 | 能力 |
|---|---|
| 1 | 掌握 NetManager 和 NetHandle 的使用方法 |
| 2 | 能够在后台线程执行 HTTP 网络请求 |
| 3 | 能够使用 DataFlowStatistics 统计应用流量 |
核心图解

内容讲解
24.1 网络管理概述
NetManager 是 HarmonyOS 网络管理的总入口,负责检查网络可用性、获取网络句柄、打开 URL 连接等。DataFlowStatistics 则提供流量统计能力,可以查询应用和系统的上下行流量。
生活化类比:NetManager 就像"快递公司总调度"
你要寄快递(网络请求),先找总调度室(NetManager)看看有没有可用的快递员(默认网络)。总调度给你分配了一个快递员(NetHandle),这个快递员可以帮你送文件(openConnection 打开 URL 链接)或者建立专线(bindSocket 绑定 Socket)。DataFlowStatistics 则像财务部,记录每个快递员送了多少包裹(上行流量)和收了多少包裹(下行流量)。
24.2 HTTP 网络请求
网络请求必须在后台线程执行,否则会导致 ANR(应用无响应)。
java
// 注意:网络请求必须在后台线程执行
getGlobalTaskDispatcher(TaskPriority.DEFAULT).asyncDispatch(() -> {
NetManager netManager = NetManager.getInstance(context);
if (!netManager.hasDefaultNet()) {
HiLog.error(TAG, "无可用网络");
return;
}
NetHandle netHandle = netManager.getDefaultNet();
// 打开 URL 链接
HttpURLConnection conn = (HttpURLConnection)
netHandle.openConnection(new URL("https://example.com/api/data"));
conn.setRequestMethod("GET");
conn.setConnectTimeout(10000);
conn.setReadTimeout(10000);
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream is = conn.getInputStream();
// 读取响应数据...
String response = readStream(is);
// 回到 UI 线程更新界面
getUITaskDispatcher().syncDispatch(() -> {
textComponent.setText(response);
});
}
conn.disconnect();
});
24.3 Socket 网络通信
NetHandle 也支持将 Socket 绑定到指定网络进行通信:
java
NetHandle netHandle = netManager.getDefaultNet();
Socket socket = new Socket();
netHandle.bindSocket(socket); // 绑定到默认网络
socket.connect(new InetSocketAddress("example.com", 8080));
// 进行 Socket 通信...
24.4 流量统计
java
// 获取系统级流量统计
long rxBytes = DataFlowStatistics.getAllRxBytes(); // 所有网卡下行
long txBytes = DataFlowStatistics.getAllTxBytes(); // 所有网卡上行
HiLog.info(TAG, "系统下行: " + rxBytes + " bytes, 上行: " + txBytes + " bytes");
// 获取指定应用的流量
long appRx = DataFlowStatistics.getUidRxBytes(uid);
long appTx = DataFlowStatistics.getUidTxBytes(uid);
代码速查卡
| API | 功能 | 示例 |
|---|---|---|
NetManager.getInstance(context) |
获取网络管理实例 | NetManager.getInstance(context) |
hasDefaultNet() |
查询是否有可用网络 | netManager.hasDefaultNet() |
getDefaultNet() |
获取默认网络句柄 | netManager.getDefaultNet() |
netHandle.openConnection(url) |
打开 URL 链接 | netHandle.openConnection(new URL("...")) |
netHandle.bindSocket(socket) |
绑定 Socket 到网络 | netHandle.bindSocket(socket) |
getAllRxBytes() |
获取所有网卡下行流量 | DataFlowStatistics.getAllRxBytes() |
getAllTxBytes() |
获取所有网卡上行流量 | DataFlowStatistics.getAllTxBytes() |
getUidRxBytes(uid) |
获取指定应用下行流量 | DataFlowStatistics.getUidRxBytes(uid) |
与 Android/iOS 对比
| 特性 | HarmonyOS | Android | iOS |
|---|---|---|---|
| 网络管理 | NetManager | ConnectivityManager | NWPathMonitor |
| HTTP 请求 | NetHandle.openConnection() | HttpURLConnection / OkHttp | URLSession |
| Socket 绑定 | NetHandle.bindSocket() | Network.bindSocket() | NWConnection |
| 流量统计 | DataFlowStatistics | TrafficStats | 不提供公开 API |
| 网络状态监听 | NetStateCallback | NetworkCallback | NWPathMonitor |
⚠️ 踩坑回忆录
主线程网络请求导致 ANR
我刚开始学网络编程时,直接在按钮点击事件里调用了 openConnection(),结果 3 秒后系统弹出了 ANR 对话框。教训深刻------网络请求必须 在后台线程执行。使用 GlobalTaskDispatcher.asyncDispatch() 或 ParallelTaskDispatcher 把网络操作丢到后台。
还有,别忘了处理网络不可用的情况。没有网络时应该给用户友好的提示(如"网络已断开,请检查网络设置"),而不是让 App 卡死或显示空白页。
必做实操任务
| 序号 | 任务 | 难度 |
|---|---|---|
| 1 | 实现一个简单的 HTTP GET 请求,获取 JSON 数据并展示 | 中 |
| 2 | 实现 POST 请求,提交表单数据 | 中 |
| 3 | 实现网络状态检测,无网络时显示提示 | 低 |
| 4 | 实现流量统计面板,展示应用上下行流量 | 中 |
| 5 | 实现一个带加载进度条的网络图片加载器 | 高 |
学习检查清单
- 能使用 NetManager 检查网络可用性
- 能使用 NetHandle 在后台线程执行 HTTP 请求
- 能正确处理网络请求的结果和错误
- 知道为什么网络请求必须在后台线程执行
- 能使用 DataFlowStatistics 查询流量统计
- 能处理网络不可用的情况
- 理解 NetManager 和 NetHandle 的关系
- 能实现 Socket 网络通信
进阶方向
- 学习 JSON 解析库的使用,实现 API 数据对接
- 探索 HTTPS 证书校验和网络安全配置
- 实现网络请求的缓存策略和离线支持
可用的情况 - 理解 NetManager 和 NetHandle 的关系
- 能实现 Socket 网络通信
进阶方向
- 学习 JSON 解析库的使用,实现 API 数据对接
- 探索 HTTPS 证书校验和网络安全配置
- 实现网络请求的缓存策略和离线支持