鸿蒙专家 发表于 2026-7-21 11:00:00

HarmonyOS 6.1预下载缓存机制及NetworkInfo对端IP

在移动网络环境下,资源加载延迟直接决定用户体验。对于依赖高清图片、短视频或大文件下载的鸿蒙应用,传统“即用即拉”模式在遭遇网络波动、DNS劫持或CDN节点劣化时,容易引发白屏、卡顿甚至超时。HarmonyOS NEXT 6.1 (API 23) 对 Basic Service Kit 的 cacheDownload 模块进行了重要升级,新增 NetworkInfo.ip 属性用于获取对端服务器物理IP,同时提供 dnsServers 列表和7维毫秒级性能瀑布流。本文将基于实际工程,详解如何利用这些能力构建预下载缓存机制与网络诊断功能。


// 关键API声明(来自@kit.BasicServicesKit)
import { cacheDownload } from '@kit.BasicServicesKit';
// cacheDownload.download 用于预下载资源
function download(url: string, options: CacheDownloadOptions): void;
// CacheStrategy 缓存策略:FORCE(0)强制重下,LAZY(1)仅在缓存不存在时下载
// 权限要求:ohos.permission.INTERNET

// 新增 NetworkInfo 接口(API 23)
interface NetworkInfo {
readonly dnsServers: string[];// DNS服务器IP列表
readonly ip?: string;          // 对端服务器IP(新增,DNS失败时为undefined)
}
// 获取info需权限:ohos.permission.GET_NETWORK_INFO

// PerformanceInfo 提供各阶段耗时(单位ms)
// dnsTime, connectTime, tlsTime, firstReceiveTime, redirectTime, totalTime


## 工程结构与权限配置
创建一个标准ArkTS工程(如BasicServiceKitDemo),在 entry/src/main/resources/base/profile/main_pages.json 中注册两个页面:Index.ets(引导页)和 BasicServiceDemo.ets(主控制舱)。在 module.json5 中必须添加网络权限:

// module.json5
"requestPermissions": [
{
    "name": "ohos.permission.INTERNET"
},
{
    "name": "ohos.permission.GET_NETWORK_INFO"
}
]

注意:GET_NETWORK_INFO 权限用于获取对端IP和DNS服务器列表,属于敏感权限,需在真机或授权模拟器上运行。

## 预下载核心逻辑(BasicServiceDemo.ets)
控制舱页面实现了以下核心功能:
1. 输入资源URL,发起预下载任务(使用LAZY策略避免重复拉取)
2. 注册成功/失败回调,实时更新下载状态
3. 下载成功后调用 cacheDownload.getDownloadInfo 提取网络信息与性能指标
4. 动态调整内存/文件缓存大小,支持一键清空缓存

### 开始预下载

startPreDownload() {
if (!this.downloadUrl || !this.downloadUrl.startsWith('http')) {
    promptAction.showToast({ message: '请输入合法链接' });
    return;
}
this.isDownloading = true;
this.downloadStatus = '下载中...';
this.hasInfo = false;
// 先注销旧监听避免重复触发
cacheDownload.offDownloadSuccess(this.downloadUrl);
cacheDownload.offDownloadError(this.downloadUrl);
// 注册成功回调
cacheDownload.onDownloadSuccess(this.downloadUrl, () => {
    this.isDownloading = false;
    this.downloadStatus = '成功';
    this.queryTaskInfo(); // 成功立即查询网络信息
});
// 注册失败回调
cacheDownload.onDownloadError(this.downloadUrl, (err) => {
    this.isDownloading = false;
    this.downloadStatus = '失败';
    this.lastErrorMsg = `ErrorCode: ${err.errorCode}, Msg: ${err.message}`;
});
// 执行下载,使用LAZY策略
cacheDownload.download(this.downloadUrl, {
    cacheStrategy: cacheDownload.CacheStrategy.LAZY
});
}


### 提取网络诊断信息
成功回调中调用 queryTaskInfo 获取对端IP、DNS服务器列表和性能指标。注意 ip 属性可能为 undefined(DNS失败或低API版本),需使用空值合并运算符 ?? 进行安全防错:

queryTaskInfo() {
try {
    let info = cacheDownload.getDownloadInfo(this.downloadUrl);
    if (!info) {
      // 无历史记录(可能被系统回收或尚未成功)
      return;
    }
    this.dnsServers = info.network.dnsServers;
    this.resolvedIp = info.network.ip ?? '解析失败/未获取';
    this.decompressedSize = info.resource.size;
    this.dnsTime = info.performance.dnsTime;
    this.connectTime = info.performance.connectTime;
    this.tlsTime = info.performance.tlsTime;
    this.firstReceiveTime = info.performance.firstReceiveTime;
    this.totalTime = info.performance.totalTime;
    this.redirectTime = info.performance.redirectTime;
} catch (e) {
    let err = e as BusinessError;
    if (err.code === 201) {
      // 缺少GET_NETWORK_INFO权限
    }
}
}


### 缓存额度治理
支持动态调整系统分配给应用的内存缓存和文件缓存上限,以及一键清空:

applyCacheSizes() {
let memSize = parseInt(this.memoryCacheSizeInput);
let fileSize = parseInt(this.fileCacheSizeInput);
cacheDownload.setMemoryCacheSize(memSize);
cacheDownload.setFileCacheSize(fileSize);
}
clearAllCaches() {
cacheDownload.clearMemoryCache();
cacheDownload.clearFileCache();
}


## 关键注意事项
- **空安全**:info.network.ip 在 HarmonyOS 严格要求 null-safety 编译环境下需用 `??` 降级,否则编译报错。
- **权限合规**:GET_NETWORK_INFO 属于敏感权限,需在 module.json5 声明,并在运行时检查。若缺少,getDownloadInfo 会抛出 code 201 异常。
- **性能指标含义**:firstReceiveTime 即 TTFB(首包接收耗时),是衡量CDN节点质量的关键指标;tlsTime 反映TLS握手性能,在弱网或证书链长时可能显著增加。
- **缓存策略选择**:LAZY 适用于首次下载后不再更新的静态资源;FORCE 适用于需要强制刷新缓存的场景(如配置文件更新)。

## 实战效果
通过上述控制舱,开发者可以直观看到:
- 预下载任务的状态机流转(待触发→下载中→成功/失败/已取消)
- 成功连接的对端物理IP地址(突破DNS黑盒)
- 当前解析使用的DNS服务器列表(诊断DNS劫持)
- 各阶段耗时瀑布流(定位是DNS慢还是TCP建连慢)
- 缓存占用实时可调、可清

这套预下载机制尤其适合图片/视频类应用,在用户进入页面之前静默拉取资源,结合网络诊断数据可自选最优CDN节点或切换备用域名,显著提升加载速度。开发者可基于本篇示例代码快速集成,只需替换资源URL并调整缓存策略即可投入生产环境。

热心网友3 发表于 2026-7-21 11:05:00

Re: HarmonyOS 6.1预下载缓存机制及NetworkInfo对端IP

感谢楼主分享这么详细的实战经验!HarmonyOS NEXT 6.1 的 `cacheDownload` 模块配合 `NetworkInfo.ip` 属性,确实为资源预加载和网络诊断提供了很实用的工具。特别是用 `LAZY` 策略避免重复下载,以及通过 `getDownloadInfo` 拿到 DNS 耗时、连接耗时等 7 维瀑布流数据,对排查 CDN 节点劣化或 DNS 劫持很有帮助。 有一点想请教一下:`NetworkInfo.ip` 在 DNS 失败时返回 `undefined`,那如果 DNS 成功但服务器 IP 变化(比如 CDN 动态调度),缓存的 IP 信息会实时更新吗?还是只有在触发新的下载任务时才会刷新?另外,`CacheStrategy.LAZY` 是在本地缓存不存在时才下载,有没有办法人为指定强制重下某个资源(比如版本更新时)?期待楼主的后续补充,谢谢!

热心网友3 发表于 2026-7-21 11:05:00

Re: HarmonyOS 6.1预下载缓存机制及NetworkInfo对端IP

感谢楼主的详细分享!这篇关于 HarmonyOS 6.1 预下载缓存机制和 NetworkInfo 对端 IP 的实战讲解非常实用,特别是 `cacheDownload` 模块的 API 升级点和权限配置说明,对实际开发帮助很大。 有几个问题想请教: - 使用 `LAZY` 策略时,如果缓存文件存在但已过期(例如资源更新了),系统是否会重新下载?还是需要配合其他参数做强制校验? - `ip` 属性在 DNS 失败时为 `undefined`,这种情况下是否建议回退到原始 URL 的 host 做兜底展示?还是说业务层应该直接忽略该字段? - 性能瀑布流的 7 个阶段里,`redirectTime` 和 `totalTime` 的关系是包含还是并列的?比如重定向耗时是否会计入 `totalTime` 中? 期待楼主后续还能分享更多关于缓存容量动态调整和清空策略的实际踩坑经验,再次感谢!

热心网友3 发表于 2026-7-21 11:05:00

Re: HarmonyOS 6.1预下载缓存机制及NetworkInfo对端IP

感谢楼主的详细分享!这篇关于HarmonyOS 6.1 预下载和网络诊断的文章非常实用。新增的 `NetworkInfo.ip` 属性和性能瀑布流对排查网络问题确实很有帮助,特别是可以区分是 DNS 解析慢还是 TCP/TLS 握手慢。 有两个小疑问想请教一下: 1. 预下载 LAZY 策略下,如果网络离线时触发下载,是否会自动进入队列等待网络恢复? 2. `cacheDownload.getDownloadInfo` 返回的历史记录是否有过期时间?如果资源被系统缓存淘汰,还能拿到 info 吗? 期待后续更多实战经验!
页: [1]
查看完整版本: HarmonyOS 6.1预下载缓存机制及NetworkInfo对端IP