鸿蒙新特性:@ohos.request 上传下载实验室实战 —— 文件传输、进度监听与任务管理

📅 2026/7/23 16:29:59
鸿蒙新特性:@ohos.request 上传下载实验室实战 —— 文件传输、进度监听与任务管理
引言文件上传下载是移动应用中最常见的网络操作之一——从更新包的静默下载到头像图片的上传从离线内容包的获取到日志文件的回传。HarmonyOS NEXT 通过ohos.request模块将上传下载能力统一封装为任务对象提供完整的进度监听、暂停恢复和取消删除等生命周期管理。ohos.request属于kit.BasicServicesKit是系统级文件传输代理File Transfer Agent的统一入口。与 Android 的DownloadManagerHttpURLConnection分散在两个 API 中和 iOS 的URLSession后台会话配置复杂不同鸿蒙将上传和下载整合到一个模块中通过DownloadTask和UploadTask两个任务对象提供一致的 Promise on/off 事件回调模型。本文将深入讲解ohos.request的文件下载、进度监听、任务控制和文件上传四大核心能力并构建一个上传下载实验室Demo在一个页面中完成下载全流程操作。一、API 架构任务对象模型1.1 核心设计理念ohos.request的设计核心是任务对象模式。调用downloadFile()或uploadFile()不是直接开始传输而是返回一个任务对象DownloadTask或UploadTask。开发者持有这个任务对象可以注册on(progress)回调监听实时进度调用suspend()暂停传输调用restore()恢复传输调用delete()取消并删除任务调用getTaskInfo()查询任务详情importrequestfromohos.request;// 1. 创建下载任务consttaskawaitrequest.downloadFile(context,{url:https://example.com/file.zip,filePath:/data/storage/el2/base/file.zip});// 2. 监听进度task.on(progress,(receivedSize:number,totalSize:number){constpctMath.round((receivedSize/totalSize)*100);console.log(下载进度: pct.toString()%);});// 3. 控制任务awaittask.suspend();// 暂停awaittask.restore();// 恢复awaittask.delete();// 取消这种任务对象模型有三个优势生命周期完整创建 → 运行 → 暂停 → 恢复 → 完成/取消每个状态都有对应的 API事件驱动on/off模式注册和移除进度回调无需 Polling资源可控通过suspend/restore实现带宽管理WiFi 切换蜂窝网络时自动暂停1.2 downloadFile —— 创建下载任务downloadFile(context: BaseContext, config: DownloadConfig): PromiseDownloadTask创建一个下载任务并立即开始下载。需要两个参数context应用的BaseContext对象。在 ArkUI 组件中通过getContext(this)获取。这个参数用于系统服务绑定和沙箱路径解析。configDownloadConfig配置对象包含以下字段字段类型必填说明urlstring是资源下载地址https:// 开头最长 2048 字符filePathstring否文件保存路径。不指定时系统自动选择默认下载目录headerObject否HTTP 请求头用于认证、UA 自定义等enableMeteredboolean否是否允许在计量网络蜂窝数据下下载enableRoamingboolean否是否允许在漫游网络下下载constctxgetContext(this);constconfig:request.DownloadConfig{url:https://jsonplaceholder.typicode.com/posts/1,enableMetered:true,enableRoaming:true};request.downloadFile(ctx,config).then((task:request.DownloadTask){this.dlTasktask;// 注册进度回调task.on(progress,(received:number,total:number){this.dlDownloadedthis.formatSize(received);if(total0){this.dlProgressMath.round((received/total)*100);}});}).catch((e:Error){// 下载失败处理});关键设计细节filePath可选——不指定路径时系统会将文件保存到默认下载目录适合下载后用其他应用打开的场景enableMetered默认为 false意味着在蜂窝网络下不会自动开始下载。对于小文件如 JSON 响应建议设为 true返回的DownloadTask对象立即可用可以在 Promise resolve 之前就注册on(progress)——但最佳实践是 resolve 后再注册1.3 DownloadTask —— 进度监听与生命周期DownloadTask是下载操作的核心对象提供四个关键能力进度监听task.on(progress,(receivedSize:number,totalSize:number)void):void回调参数receivedSize已接收的字节数number 类型totalSize文件总大小number 类型。重要totalSize 可能为 0表示服务器未返回 Content-Length 响应头。在这种情况下progress 回调仍然触发但百分比无法计算。Demo 中对此做了防御性处理task.on(progress,(received:number,total:number){this.dlDownloadedthis.formatSize(received);if(total0){constpctMath.round((received/total)*100);this.dlProgresspct;this.dlProgressTextpct.toString()%;if(pct100){this.dlDownloadingfalse;task.off(progress);// 下载完成后移除监听}}else{// 无法获取总大小只显示已下载量this.dlProgressTextthis.formatSize(received);}});任务控制suspend(): Promiseboolean— 暂停下载。返回 true 表示暂停成功restore(): Promiseboolean— 恢复已暂停的下载。返回 true 表示恢复成功delete(): Promiseboolean— 取消下载并删除任务。返回 true 表示删除成功这三个方法全部返回 Promise不建议使用它们的同步变体文档中可能有 deprecated 标记。回调清理off(progress, callback?)— 移除进度回调。传入具体 callback 移除指定监听器不传则移除所有最佳实践是在下载完成后100%或取消下载时调用off(progress)防止内存泄漏。在组件销毁aboutToDisappear时也要做安全保障aboutToDisappear():void{if(this.dlTask!null){try{this.dlTask.off(progress);}catch(e){// 任务可能已结束忽略异常}}}二、文件上传2.1 uploadFile —— 创建上传任务uploadFile(context: BaseContext, config: UploadConfig): PromiseUploadTask创建一个文件上传任务。UploadConfig 配置对象字段类型必填说明urlstring是上传目标地址filePathstring是要上传的本地文件路径headerObject否HTTP 请求头与下载不同上传的filePath是必填项——必须指向本地实际存在的文件。UploadTask同样支持on(progress, callback)、suspend()、restore()和delete()API 与DownloadTask完全对称。constupConfig:request.UploadConfig{url:https://httpbin.org/post,filePath:/data/storage/el2/base/haps/entry/files/photo.jpg};request.uploadFile(ctx,upConfig).then((task:request.UploadTask){task.on(progress,(uploaded:number,total:number){console.log(已上传: uploaded.toString() / total.toString());});});三、实战 Demo上传下载实验室3.1 页面设计上传下载实验室页面分为四个功能区域文件下载面板URL 输入框 下载按钮。下方三个预设快捷按钮favicon.ico / JSON / HTML点击后自动填入 URL 并开始下载。进度面板大字显示下载百分比和已下载 / 总大小。Progress 线性进度条indigo 色 #4F46E5实时反映下载进度。任务控制区三个按钮——“暂停”黄色仅在下载中可用、“继续”绿色仅在暂停后可用、“取消”红色仅在任务存在时可用。每个按钮通过enabled属性控制可用状态。操作日志记录任务创建、进度变化、暂停/恢复/取消、错误等事件按类别着色。3.2 核心实现状态模型设计StatedlUrl:stringhttps://www.example.com/favicon.ico;StatedlProgress:number0;StatedlProgressText:string0%;StatedlDownloaded:string0 B;StatedlTotal:string--;StatedlDownloading:booleanfalse;StatedlTaskExists:booleanfalse;StatedlPaused:booleanfalse;privatedlTask:request.DownloadTask|nullnull;状态设计要点dlDownloading、dlTaskExists、dlPaused三个布尔状态精确描述当前任务的运行状态驱动按钮的enabled属性dlTask用private而非State声明——DownloadTask对象不是 UI 状态不需要触发重渲染dlProgress是数字0-100驱动 Progress 组件dlProgressText是显示用字符串“45%” 或 “2.5 KB”文件大小格式化privateformatSize(bytes:number):string{if(bytes1024)returnbytes.toString() B;if(bytes1024*1024)return(bytes/1024).toFixed(1) KB;return(bytes/(1024*1024)).toFixed(2) MB;}进度回调中同时展示格式化后的大小“1.5 KB”和原始百分比“45%”让用户对下载进度有定性和定量的双重感知。暂停/恢复/取消的三态联动// 按钮 enabled 条件// 暂停: dlDownloading !dlPaused → 正在下载且未暂停// 继续: dlPaused → 已暂停状态// 取消: dlTaskExists → 任务对象存在// 暂停privatepauseDownload():void{this.dlTask?.suspend().then((){this.dlPausedtrue;this.dlDownloadingfalse;});}// 恢复privateresumeDownload():void{this.dlTask?.restore().then((){this.dlPausedfalse;this.dlDownloadingtrue;});}// 取消privatecancelDownload():void{this.dlTask?.off(progress);// 先移除监听this.dlTask?.delete().then((){this.dlTasknull;this.dlDownloadingfalse;this.dlTaskExistsfalse;this.dlPausedfalse;this.dlProgress0;this.dlProgressText0%;});}取消操作的关键在于先off(progress)再delete()——如果顺序反了progress 回调可能在 delete 过程中触发导致状态异常。3.3 交互方式Demo 提供三个核心交互点输入 URL 下载在 TextInput 中输入下载地址或点击预设快捷按钮点击下载按钮开始下载。下载过程中按钮变为灰色下载中并禁用防止重复创建任务。实时进度追踪Progress 组件配合百分比文字和已下载/总大小实时更新。对于有 Content-Length 的响应进度条从 0% 平滑增长到 100%对于无 Content-Length 的响应显示已下载的字节数。任务三态控制下载进行中可以暂停变为暂停状态按钮变为可继续暂停后可以继续恢复下载或取消删除任务。取消后所有状态重置为初始值。四、实际应用场景4.1 更新包下载器asyncfunctiondownloadUpdate(url:string,onProgress:(pct:number)void):Promisestring{consttaskawaitrequest.downloadFile(getContext(),{url:url,enableMetered:true,enableRoaming:false});returnnewPromise((resolve,reject){task.on(progress,(received,total){if(total0){onProgress(Math.round((received/total)*100));}if(receivedtotaltotal0){task.off(progress);resolve(download complete);}});});}4.2 WiFi 切换自动暂停// 伪代码配合 ohos.net.connection 检测网络变化functiononNetworkChanged(isWifi:boolean):void{if(isWifi){task?.restore();// WiFi 环境恢复下载}else{task?.suspend();// 蜂窝网络暂停大文件下载}}五、总结ohos.request是 HarmonyOS NEXT 中文件上传下载的统一模块。通过本文的学习你应该已经掌握任务对象模型downloadFile/uploadFile返回DownloadTask/UploadTaskPromise 创建 on/off 事件监听生命周期完整进度监听task.on(progress, (receivedSize, totalSize) void)totalSize 可能为 0 需要防御性处理下载完成或取消时必须off(progress)清理回调任务控制三态suspend()暂停、restore()恢复、delete()取消——三者驱动按钮联动状态机DownloadConfig 配置url必填、filePath可选、header、enableMetered、enableRoaming——支持认证请求头、计量网络控制和漫游限制context 获取在 ArkUI 组件中通过getContext(this)获取 BaseContext 传给downloadFile/uploadFileohos.request的最佳使用模式可以总结为创建任务 → 注册 progress 回调 → 根据 totalSize 计算百分比 → 100% 时 off(‘progress’) 清理 → 异常时显示错误。suspend/restore 实现带宽管理delete 处理用户取消。context 通过 getContext(this) 获取。文件传输是移动应用的核心网络能力之一。虽然 HTTP 也可以实现文件下载但ohos.request提供的系统级下载代理拥有后台传输、网络切换自动处理、通知栏进度显示等企业级特性——这些是ohos.net.http无法替代的。在 HarmonyOS 网络通信体系中ohos.request定位于大文件传输 任务管理与ohos.net.httpREST API 请求和ohos.net.connection网络状态检测形成完整的三级网络能力栈。ohos.request属于kit.BasicServicesKit是系统级文件传输代理。它的 API 设计遵循Promise 创建 事件驱动模式——一次downloadFile()调用返回一个长生命周期任务对象开发者持有该对象即可完成从创建到销毁的全部控制。