HarmonyOS 7 + Request Kit + Background Tasks Kit 实战:多附件上传中心的断点续传、失败重试与队列调度【鸿蒙心迹】
这篇文章我不想只讲“上传功能怎么做出来”而是把我这次做多附件上传中心时真正踩到的工程边界梳理清楚为什么单个上传接口一旦遇到后台切换、网络抖动、超大文件就会很快失控以及我最后是怎么把断点续传、失败重试、并发队列和后台调度收成一套能上线的结构。一、最开始的问题不是上传失败而是上传逻辑太“直”了我最早做这个页面时想法其实特别直接用户选文件点上传Request Kit 发请求成功了就改状态失败了就弹提示。刚跑 Demo 的时候这套逻辑看起来没什么问题。可一旦把场景从“上传一个 3MB 图片”换成“连续上传 5 个附件其中还混着 1GB 的视频、几十 MB 的文档、网络中途断一下、用户切到后台再回来”问题马上就全出来了文件一多多个任务互相抢占某个大文件失败以后整个队列状态会被拖乱页面退出再回来任务状态不连续网络恢复以后不知道该从头传还是从上次分片继续某个任务一直失败会不会把剩下所有任务都卡住用户看到“失败”两个字但根本不知道失败在哪一段。也就是说表面看是“上传中心”本质上已经不是一个按钮功能了而是一套任务调度系统。二、我后来先把任务拆成了“状态机”页面才开始好维护如果上传任务只有“成功”和“失败”两个状态这种功能几乎一定会越写越乱。因为真实业务里一个上传任务至少会经历这些阶段WAITING已经入队等待执行UPLOADING正在上传PAUSED手动暂停或网络暂时不可用RETRYING发生异常进入自动重试FAILED超过重试上限正式失败SUCCESS上传完成。我后面把每个文件都抽成一条UploadTask里面除了文件信息还会记录当前状态当前进度已上传分片数失败次数最大重试次数最近错误信息本地断点位置。这样做最大的变化是页面不再凭感觉拼 UI而是完全跟着任务状态走。最基础的一版任务模型我最后收成了下面这种结构exportenumUploadStatus{WAITINGWAITING,UPLOADINGUPLOADING,PAUSEDPAUSED,RETRYINGRETRYING,FAILEDFAILED,SUCCESSSUCCESS}exportinterfaceUploadTask{id:stringfilePath:stringfileName:stringfileSize:numberchunkSize:numberuploadedChunk:numbertotalChunk:numberprogress:numberretryCount:numbermaxRetry:numberstatus:UploadStatus errorMessage?:string}这段代码看起来只是多了几个字段但它解决的是一个更底层的问题上传任务终于有了统一的生命周期。三、真正让我稳下来的不是接口而是“上传队列”一开始我也试过最省事的做法用户选了几个文件就起几个并发上传。结果非常快问题就来了。大文件占住带宽小文件一直排队网络一差多个任务同时重试页面上明明只坏了一项但用户看到的却像全部都卡住了。后来我就不再让页面直接发请求而是加了一层UploadManager。这层只做三件事维护任务队列控制最大并发数统一管理重试和状态回调。也就是说页面负责“发起上传”真正执行上传的是队列管理器。我最后保留的核心逻辑大概是这样classUploadManager{privatequeue:UploadTask[][]privaterunningCount:number0privatemaxConcurrent:number3addTask(task:UploadTask){this.queue.push(task)this.schedule()}privateschedule(){while(this.runningCountthis.maxConcurrent){constnextTaskthis.queue.find(itemitem.statusUploadStatus.WAITING)if(!nextTask){break}this.runningCount1nextTask.statusUploadStatus.UPLOADINGthis.uploadTask(nextTask).finally((){this.runningCount-1this.schedule()})}}}这里最关键的不是while这几行而是思路变了上传不是页面事件而是队列事件页面点击“上传”只是在往队列里塞任务调度权在管理器手里不在按钮手里。这一点想通以后很多以前很乱的问题一下就有了归宿。四、断点续传不是一个按钮而是一段“已上传分片”的记录真正让我觉得这个功能像样起来的是把断点续传补完整。用户看到的只是“继续上传”四个字但工程上它背后至少要回答三件事已经传到哪个分片了下次恢复时从哪里接着走失败后重试是重试当前分片还是重试整个文件。我最后没有做整文件一次性上传而是把大文件按分片处理。每个分片完成以后立即更新uploadedChunkprogresslastCallbackTime本地持久化断点位置这样做的好处非常直接如果第 385 个分片超时恢复时就不必从第 1 个分片重新开始而是从384的下一个位置继续。这也是为什么在上传详情页里我刻意把“总分片数”“断点位置”“重试次数”“最后回调时间”都显式展示出来。你看这张图其实就是在讲这套链路的几个关键证据红圈标出的“总分片数”和“断点位置”告诉我们恢复到底从哪一段开始“失败原因”不是一句泛泛提示而是具体到网络超时“重试次数”和“最后回调时间”能让排查不再停留在猜测层面。很多上传功能看起来也有失败页但如果没有这些字段开发者很难判断问题到底卡在哪一步。五、自动重试真正难的不是“重试一下”而是别把队列拖崩自动重试听起来像一句话真正落地时却很讲分寸。如果所有失败都立刻重试网络一抖整个队列会同时重试某个必然失败的任务会反复耗资源用户会觉得页面一直在转但又不知道什么时候结束。所以我最后给重试定了三条规则只对可恢复错误重试例如网络超时、瞬时连接失败限制最大重试次数超过上限进入FAILED重试前做延迟退避避免多个任务瞬间同时重试。比如第 1 次重试等 2 秒第 2 次等 4 秒第 3 次等 8 秒。这样一来网络刚刚恢复时队列不会一下子全部撞上去。页面上我也把这件事讲清楚了失败任务不是彻底结束而是会先进入“可重试”的状态再决定是系统自动兜底还是用户手动触发。这张图里红色标注圈出来的点其实刚好就是用户最关心、开发者也最该先排查的几个位置“并发 3” 对应的是队列调度能力“重试”按钮对应失败任务的人工接管入口“继续上传”对应断点续传能力。读者看一眼就能理解这不是一个简单的文件列表而是一套带调度、带恢复、带失败兜底的上传中心。六、后台切走以后还能继续是因为我把后台任务和上传链路接在了一起多附件上传真正的考题很多时候不是前台而是后台。因为用户上传视频、压缩包这类大文件时几乎不可能一直盯着页面看。他切出去回消息、查文档、锁屏都是很正常的操作。如果这时候上传能力完全依赖当前页面生命周期用户体验一定很差。所以我后面又补上了Background Tasks Kit的调度逻辑让上传任务在应用退到后台后仍然能维持可控执行。在工程结构上我没有把后台任务另写成一套上传逻辑而是只让后台能力负责“保活与调度”真正的任务状态还是统一落在UploadManager上。也就是说前台和后台不是两套上传系统它们共享同一套任务队列后台只是改变任务执行时机而不改变任务模型。这个收法很重要。否则很容易出现前台一个状态、后台一个状态、页面回来又对不上的情况。七、整个工程为什么能稳下来我觉得关键不是某个 API而是“证据可见”后面我回头看这次实战真正让我满意的不是“上传成功率提高了”而是整个系统开始有了可解释性。比如在 DevEco 的开发视角里我会同时看三块东西左边项目结构里页面、管理器、后台任务是不是分层清楚中间代码里队列状态、重试入口、后台调度是不是收口在少数几个方法里底部日志里任务回调、重试日志、队列状态是不是连续可追踪。这张图对我来说就很像这次工程的缩影红色箭头标注“队列状态”说明上传中心不再是散点逻辑“重试入口”说明错误恢复是有结构的“后台任务调度”说明页面生命周期之外任务还能被系统托住底部日志把“回调—重试—队列状态”串成了一条完整证据链。这也是我这次最强烈的体会上传功能一旦进入工程化阶段最值钱的不是单次成功而是状态可见、过程可追。八、本文小记如果让我用一句话总结这次实战我会写成多附件上传中心的难点不在“传”而在“调度”。真正决定体验的从来不是那个“选择文件”按钮而是队列是不是稳分片是不是能续失败是不是能判重试是不是有边界后台是不是还能接着跑。对我自己来说这次做完以后有几个判断基本算是固定下来了任务一定要先抽成状态机上传一定要收进队列管理器断点续传一定要落到可持久化的分片进度上自动重试一定要有错误类型和次数边界后台调度一定要和前台任务共用一套状态来源。如果你现在也在做 HarmonyOS 的文件上传类功能我的建议不是“先把上传接口接上”而是先想清楚你的上传中心究竟只是一个页面还是一套任务系统。想清楚这一点后面的工程结构会完全不一样。

相关新闻

第316篇_手机回收平台比价

第316篇_手机回收平台比价

【Python爬虫实战】第316篇:手机回收平台比价爬虫:爱回收与转转回收估价对比——实战项目 所属专栏:【Python爬虫实战】从零到企业级爬虫工程师(CSDN 付费专栏) 本篇篇目:第 316 篇(垂直行业爬虫 二手回收估价专题) 难度等级:中级,有 requests 基础即可上手 阅读时长…

2026/10/1 19:03:36 阅读更多 →
GPT-6 Luna (Batch) 批量处理性能与质量深度评测

GPT-6 Luna (Batch) 批量处理性能与质量深度评测

处理几十条指令时,一个循环往往就能完成任务。但当数据量增加到几千条、几万条,接口限流、长文本超时、结果错位和失败重跑的问题就会逐渐显现:任务看似一直在执行,真正完成并通过校验的结果却没有同步增加。 串行处理容易把时间…

2026/10/1 17:48:30 阅读更多 →
文献综述怎么筛掉不靠谱的来源

文献综述怎么筛掉不靠谱的来源

一篇综述引了八十条文献,答辩时被追问的往往不是数量,而是其中几条的来路。来源筛选真正难住人的地方在于:没有哪一条判据能单独证明"这条来源可信"——期刊名可以仿,DOI 格式可以套,条目也能凭印象拼出来。…

2026/10/1 19:44:51 阅读更多 →

最新新闻

Manjaro/Arch下Fcitx5搜狗输入法实战安装指南

Manjaro/Arch下Fcitx5搜狗输入法实战安装指南

1. 项目概述:为什么在 Manjaro/Arch Linux 上装搜狗输入法是个“高频痛点”Manjaro 和 Arch Linux 用户里,十有八九都卡在同一个地方:装完系统,打开浏览器想搜点东西,结果键盘敲出的全是英文字母——中文输入法没起来。…

2026/10/1 22:54:23 阅读更多 →
AI生成代码如何匹配团队风格与工程一致性

AI生成代码如何匹配团队风格与工程一致性

1. 这不是代码问题,是团队认知断层的显影 “AI写的代码一跑就通,但完全不像我们组写的”——这句话最近在好几个技术团队的茶水间、站会间隙、甚至代码评审会上反复出现。它听起来像一句调侃,但背后藏着一个正在快速扩大的现实裂口&#xff1…

2026/10/1 22:54:23 阅读更多 →
示波器核心参数与实战技巧:带宽、采样率、探头和触发全解析

示波器核心参数与实战技巧:带宽、采样率、探头和触发全解析

1. 示波器到底在“看”什么:从一堆波形说起我第一次拿起示波器的探头时,心里想的是“这不是个大号的万用表嘛”。后来被老师傅纠正了——万用表告诉你“现在是多少伏”,示波器告诉你“电压在过去这段时间里是怎么变的”。这一个“怎么变”的差…

2026/10/1 22:54:23 阅读更多 →
ESXi虚拟机导出导入的底层逻辑与OVF/OVA交付实战

ESXi虚拟机导出导入的底层逻辑与OVF/OVA交付实战

1. 为什么“导出导入虚拟机”不是点几下鼠标的事——ESXi环境下的真实交付瓶颈你有没有遇到过这样的场景:在Dell R730服务器上部署完ESXi 8.0,搭好vSphere环境,创建了一台CentOS 7 Hadoop 3.3 Spark 3.3伪分布式集群的虚拟机,测…

2026/10/1 22:54:23 阅读更多 →
LabVIEW活用ActiveX生成Excel报表:不装NI报表工具包也能搞定

LabVIEW活用ActiveX生成Excel报表:不装NI报表工具包也能搞定

如果我说,用LabVIEW生成Excel报表,不一定非要装NI Report Generation Toolkit,可能很多人第一反应是不信。毕竟网上90%的教程翻来覆去就是那套流程:拖出New Report.vi、Append Table To Report.vi,然后万事大吉。但这些…

2026/10/1 22:54:23 阅读更多 →
一个对话搞定数据开发治理?AI Agent实战与能力边界解析

一个对话搞定数据开发治理?AI Agent实战与能力边界解析

做数据开发这行,很多人这两年心里都悬着一块石头:AI这么猛,是不是哪天写SQL、调管道、对口径的活儿全被机器干了?说实话,我一开始也抱着同样的疑虑,直到上手折腾了一轮EasyData,才敢坐下来把这几…

2026/10/1 22:53:22 阅读更多 →

日新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 1:01:17 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 19:40:48 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/1 19:41:40 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/10/1 20:05:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 1:01:17 阅读更多 →