鸿蒙 ArkTS 实战:从零实现网络质量检测与评分功能
在移动应用开发中,网络质量直接影响用户体验 —— 无论是视频播放、文件下载还是实时交互,都需要根据网络状况调整功能策略。鸿蒙系统(HarmonyOS)作为面向全场景的分布式操作系统,提供了完善的网络 API 支持,这篇文章我就分享一下如何从零开始,基于 ArkTS 实现一套可直接落地的网络质量检测方案,通过测速数据将网络状态量化为 “差、中、好” 三个等级,为应用进行优化提升。
一、核心原理与实现思路
网络质量检测的本质是通过 “状态判断 + 性能测试” 双维度评估网络状况:
状态判断:先通过鸿蒙网络 API 获取当前网络类型(WiFi / 移动数据 / 无网络),排除无网络场景;
性能测试:通过请求固定大小的测试资源,计算下载速度(单位:KB/s);
等级划分:根据实际应用场景设定速度阈值,将网络质量映射为 “差、中、好” 三个等级。
整个实现流程需经历 “权限申请→网络状态检测→测速逻辑实现→结果评分→UI 展示” 五个核心步骤,下文将逐一拆解每个环节的具体代码与注意事项。
二、前置准备:权限配置与依赖引入
大家注意哦,鸿蒙系统对敏感权限管控严格,网络检测需申请两个核心权限:INTERNET(网络访问权限)和GET_NETWORK_INFO(获取网络状态权限),需在配置文件中提前声明。
1. 配置 module.json5 权限
在 entry 模块的module.json5文件中,添加权限声明(路径:entry/src/main/module.json5):
{
"module": {
// 其他配置省略...
"requestPermissions": [
{
"name": "ohos.permission.INTERNET",
"reason": "需要访问网络以进行测速",
"usedScene": {
"ability": ["EntryAbility"],
"when": "always"
}
},
{
"name": "ohos.permission.GET_NETWORK_INFO",
"reason": "需要获取当前网络类型(WiFi/移动数据)",
"usedScene": {
"ability": ["EntryAbility"],
"when": "always"
}
}
]
}
}
注意:reason字段需明确说明权限用途,鸿蒙应用市场审核时会校验权限申请的合理性;usedScene指定权限生效的能力与时机,避免过度授权。
2. 引入核心 API 依赖
网络检测需用到鸿蒙的@ohos.net.network(网络状态)和@ohos.net.http(HTTP 请求)模块,在代码文件顶部引入:
import network from '@ohos.net.network';
import http from '@ohos.net.http';
import { BusinessError } from '@ohos.base';
三、核心功能实现:网络检测工具类
为提高代码复用性,我们封装一个NetworkQualityManager工具类,集中管理 “网络状态检测、测速、评分” 三大核心能力,避免业务代码与工具逻辑耦合。
1. 工具类整体结构
/**
* 网络质量检测工具类
* 功能:获取网络类型、检测网络速度、评定网络质量等级
*/
export class NetworkQualityManager {
// 测试资源地址(建议选择稳定的CDN资源,大小100KB左右)
private static TEST_RESOURCE_URL = 'https://example.com/test-resource-100kb.txt';
// 网络质量等级阈值(单位:KB/s,可根据业务调整)
private static QUALITY_THRESHOLD = {
POOR: 50, // 差:低于50KB/s
MODERATE: 200 // 中:50-200KB/s;好:高于200KB/s
};
/**
* 1. 检查当前网络是否可用
* @returns Promise<boolean> 网络是否可用
*/
public static async isNetworkAvailable(): Promise<boolean> {
try {
// 获取默认网络的状态
const networkStatus = await network.getCurrentNetworkStatus();
return networkStatus.isAvailable;
} catch (error) {
const err = error as BusinessError;
console.error(`检查网络可用性失败:${err.code} - ${err.message}`);
return false;
}
}
/**
* 2. 获取当前网络类型
* @returns Promise<string> 网络类型(如:WiFi、移动数据、无网络)
*/
public static async getNetworkType(): Promise<string> {
if (!await this.isNetworkAvailable()) {
return '无网络';
}
try {
const networkType = await network.getNetworkType();
switch (networkType) {
case network.NetworkType.NETWORK_TYPE_WIFI:
return 'WiFi';
case network.NetworkType.NETWORK_TYPE_MOBILE:
return '移动数据(4G/5G)';
case network.NetworkType.NETWORK_TYPE_ETHERNET:
return '以太网';
default:
return '未知网络';
}
} catch (error) {
const err = error as BusinessError;
console.error(`获取网络类型失败:${err.code} - ${err.message}`);
return '获取失败';
}
}
/**
* 3. 核心:检测网络下载速度
* 原理:请求固定大小的测试资源,计算耗时与速度
* @returns Promise<number> 下载速度(单位:KB/s)
*/
public static async testDownloadSpeed(): Promise<number> {
if (!await this.isNetworkAvailable()) {
throw new Error('当前无可用网络,无法测速');
}
const httpRequest = http.createHttp();
let startTime: number, endTime: number;
try {
// 记录开始时间(毫秒级)
startTime = Date.now();
// 发送GET请求获取测试资源(禁用缓存,确保真实测速)
const response = await httpRequest.request(this.TEST_RESOURCE_URL, {
method: http.RequestMethod.GET,
header: {
'Cache-Control': 'no-cache' // 禁用缓存,避免本地缓存影响测速结果
},
readTimeout: 5000, // 读取超时:5秒
connectTimeout: 3000 // 连接超时:3秒
});
// 校验请求结果
if (response.responseCode !== 200) {
throw new Error(`请求测试资源失败,状态码:${response.responseCode}`);
}
// 记录结束时间
endTime = Date.now();
// 计算耗时(秒):(结束时间-开始时间)/1000
const costTime = (endTime - startTime) / 1000;
// 计算下载速度(KB/s):资源大小(字节)/ 1024 / 耗时(秒)
// 注:response.result为ArrayBuffer类型,byteLength获取字节数
const resourceSize = (response.result as ArrayBuffer).byteLength;
const speed = (resourceSize / 1024) / costTime;
return Math.round(speed); // 四舍五入取整,简化展示
} catch (error) {
const err = error as BusinessError;
console.error(`测速失败:${err.message || err.code}`);
throw new Error(`测速失败:${err.message || '未知错误'}`);
} finally {
// 销毁HTTP请求,避免内存泄漏
httpRequest.destroy();
}
}
/**
* 4. 根据速度评定网络质量等级
* @param speed 下载速度(KB/s)
* @returns {level: string, color: string} 等级与对应颜色(用于UI展示)
*/
public static getQualityLevel(speed: number): { level: string; color: string } {
if (speed < this.QUALITY_THRESHOLD.POOR) {
return { level: '差', color: '#FF4444' }; // 红色:差
} else if (speed <= this.QUALITY_THRESHOLD.MODERATE) {
return { level: '中', color: '#FFCC00' }; // 黄色:中
} else {
return { level: '好', color: '#00CC66' }; // 绿色:好
}
}
/**
* 对外暴露:一键获取完整网络质量信息
* @returns 包含网络类型、速度、等级的完整数据
*/
public static async getNetworkQuality(): Promise<{
type: string;
speed: number;
level: string;
color: string;
}> {
const type = await this.getNetworkType();
if (type === '无网络') {
return { type, speed: 0, level: '无', color: '#999999' };
}
const speed = await this.testDownloadSpeed();
const { level, color } = this.getQualityLevel(speed);
return { type, speed, level, color };
}
}
2. 关键细节说明
- 测试资源选择:TEST_RESOURCE_URL建议选择大小 100KB-1MB 的静态资源(如 txt、图片),过小会导致测速误差大,过大则耗时久;推荐使用阿里云、腾讯云等 CDN 节点,确保资源稳定性。
- 超时控制:readTimeout和connectTimeout分别设置为 5 秒和 3 秒,避免弱网环境下长时间阻塞;
- 缓存处理:通过Cache-Control: no-cache禁用 HTTP 缓存,防止本地缓存的资源影响真实测速结果;
- 异常处理:每个异步方法都包含错误捕获,确保单点故障不影响整体功能,同时输出详细错误日志便于调试。
四、UI 层集成:可视化展示网络质量
工具类实现后,需在 UI 页面中调用接口并展示结果。以下是基于 ArkTS 声明式 UI 的示例,包含 “网络类型、速度、质量等级” 展示,以及 “重新检测” 按钮。
1. 页面代码实现
import { NetworkQualityManager } from '../utils/NetworkQualityManager';
import { useState, useEffect } from '@ohos/base';
@Entry
@Component
struct NetworkQualityPage {
// 状态管理:网络质量数据、加载状态、错误信息
@State networkQuality = {
type: '检测中...',
speed: 0,
level: '待检测',
color: '#999999'
};
@State isLoading: boolean = false;
@State errorMsg: string = '';
/**
* 页面加载时自动检测一次网络质量
*/
useEffect(() => {
this.detectNetworkQuality();
}, []);
/**
* 调用工具类检测网络质量
*/
private async detectNetworkQuality() {
this.isLoading = true;
this.errorMsg = '';
try {
const result = await NetworkQualityManager.getNetworkQuality();
this.networkQuality = result;
} catch (error) {
this.errorMsg = (error as Error).message;
// 错误状态下重置展示数据
this.networkQuality = {
type: '获取失败',
speed: 0,
level: '无',
color: '#999999'
};
} finally {
this.isLoading = false;
}
}
build() {
Column({ space: 20 }) {
// 页面标题
Text('当前网络质量')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ top: 50 });
// 加载状态提示
if (this.isLoading) {
Progress({ value: 50, type: ProgressType.Circular })
.width(40)
.height(40);
Text('正在测速中...')
.fontSize(16)
.color('#666666');
} else {
// 网络类型展示
Text(`网络类型:${this.networkQuality.type}`)
.fontSize(18)
.color('#333333');
// 网络速度展示
Text(`下载速度:${this.networkQuality.speed} KB/s`)
.fontSize(18)
.color('#333333');
// 网络质量等级(带颜色标识)
Text(`网络质量:${this.networkQuality.level}`)
.fontSize(20)
.fontWeight(FontWeight.Bold)
.color(this.networkQuality.color);
// 错误信息展示
if (this.errorMsg) {
Text(`错误:${this.errorMsg}`)
.fontSize(16)
.color('#FF4444')
.margin({ top: 10 });
}
}
// 重新检测按钮
Button('重新检测网络')
.width(200)
.height(45)
.fontSize(16)
.backgroundColor('#007AFF')
.margin({ top: 30 })
.onClick(() => {
this.detectNetworkQuality();
});
}
.width('100%')
.padding(20)
}
}
2. UI 交互设计要点
- 加载状态反馈:测速过程中显示圆形进度条,避免用户误以为页面无响应;
- 颜色可视化:用 “红、黄、绿” 三色区分网络质量,符合用户认知习惯;
- 错误友好提示:当测速失败时(如网络断开、资源不可用),显示具体错误信息,便于用户排查问题;
- 手动触发机制:提供 “重新检测” 按钮,支持用户主动更新网络质量数据。
五、功能优化与扩展建议
基础版本实现后,可根据业务需求进行以下优化,提升功能实用性与稳定性:
1. 动态调整测试资源
不同场景下对测速精度要求不同:
- 弱网场景:选择 50KB 小资源,减少测速耗时;
- 高速网络(如 5G/WiFi):选择 1MB 大资源,避免因资源过小导致速度计算误差。
可在工具类中添加资源切换逻辑:
// 根据网络类型动态选择测试资源
private static getTestResourceUrl(networkType: string): string {
if (networkType.includes('移动数据')) {
return 'https://example.com/test-resource-50kb.txt'; // 移动数据用小资源
} else {
return 'https://example.com/test-resource-1mb.txt'; // WiFi用大资源
}
}
2. 多次测速取平均值
单次测速易受网络波动影响,可增加 “多次测试取平均” 逻辑,提升结果准确性:
/**
* 多次测速取平均值(默认3次)
*/
public static async testSpeedWithAverage(count: number = 3): Promise<number> {
if (count < 1) count = 1;
let totalSpeed = 0;
let validCount = 0;
for (let i = 0; i < count; i++) {
try {
const speed = await this.testDownloadSpeed();
totalSpeed += speed;
validCount++;
} catch (error) {
console.warn(`第${i+1}次测速失败,跳过:${(error as Error).message}`);
}
}
if (validCount === 0) throw new Error('所有测速尝试均失败');
return Math.round(totalSpeed / validCount);
}
3. 适配分布式场景
鸿蒙系统支持多设备协同,可扩展功能实现 “跨设备网络质量检测”,例如:
- 在手机端检测当前网络,同步到平板端;
- 根据不同设备的网络状况,推荐最优设备执行高带宽任务(如下载)。
六、常见问题与解决方案
权限申请被拒绝:需在代码中检查权限授予状态,若被拒绝则引导用户前往设置页开启:
import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
// 检查权限是否授予
public static async checkPermission(permission: string): Promise<boolean> {
const atManager = abilityAccessCtrl.createAtManager();
const result = await atManager.checkAccessToken(abilityAccessCtrl.createTokenID(), permission);
return result === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
}
测试资源不可用:建议配置多个备用测试资源地址,当一个地址请求失败时自动切换到下一个:
private static TEST_RESOURCE_URLS = [
'https://example1.com/test.txt',
'https://example2.com/test.txt'
];
弱网下测速超时:可动态调整超时时间,弱网场景下适当延长readTimeout(如 10 秒)。
总结
这里分享了基于鸿蒙 ArkTS 实现了一套完整的网络质量检测方案,核心是通过 “状态判断 + 速度测试” 实现量化评分,并通过工具类封装提高代码复用性。该方案可直接应用于视频、下载、社交等需要网络质量感知的场景,帮助开发者根据网络状况优化功能策略(如弱网下降低视频清晰度、暂停自动下载等),最终提升用户体验。后续可结合鸿蒙的分布式能力与场景化需求,进一步扩展功能,例如添加上传速度检测、网络延迟测试(ping)等,构建更全面的网络质量评估体系。
希望文章对大家有所帮助。