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/9/30 16:50:37 阅读更多 →
GPT-6 Luna (Batch) 批量处理性能与质量深度评测

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

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

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

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

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

2026/9/30 16:49:34 阅读更多 →

最新新闻

Java向上转型与向下转型的本质与实战避坑指南

Java向上转型与向下转型的本质与实战避坑指南

1. 为什么“向上转型”和“向下转型”是Java面试绕不开的坎?你刚学完继承,写了个Animal父类,再写Dog、Cat子类,顺手new了Dog对象赋值给Animal变量——编译通过,运行正常。但当你试图调用Dog特有方法bark()时&#xff0…

2026/10/1 18:58:56 阅读更多 →
基于LDA模型对豆瓣长评论进行主题分词全流程解析

基于LDA模型对豆瓣长评论进行主题分词全流程解析

简介:基于LDA模型对豆瓣长评论进行主题分词的Python源码与数据包,是一份已通过导师指导并获97分的期末大作业,面向NLP课程设计、文本挖掘实践及毕业设计参考人群。项目完整、下载即用,可快速跑通从评论清洗、中文分词、停用词过滤…

2026/10/1 18:58:56 阅读更多 →
零基础用Unity6和C#实战2D RPG战斗系统:从输入到伤害反馈

零基础用Unity6和C#实战2D RPG战斗系统:从输入到伤害反馈

1. 为什么零基础做2D RPG战斗系统,反而比做完整游戏更靠谱 很多人一上来就想做一款完整的2D RPG,结果卡在背包系统、对话系统、任务系统里出不来,三个月过去连一场像样的战斗都没跑起来。我见过太多这样的案例,包括我自己早期也是…

2026/10/1 18:58:56 阅读更多 →
【信息科学与工程学】【通信工程】第四十四篇 城域网络设计101 基础设计02

【信息科学与工程学】【通信工程】第四十四篇 城域网络设计101 基础设计02

编号246——采矿业(B06煤炭开采)接入网及端到端设计 编号 类型 领域 学科 学科中涉及的知识、属性、因素、方程式、数值设计 关联知识、标准、法律法规和相关研究 246 接入层采矿业(煤炭)专网设计 接入层(采矿) 矿山通信 / 安全生产 / 工业控制 知识:煤矿井下…

2026/10/1 18:58:56 阅读更多 →
Django美容院优质客户筛选系统:基于RFM模型的毕设设计与实现

Django美容院优质客户筛选系统:基于RFM模型的毕设设计与实现

1. 先搞清楚:美容院优质客户筛选系统到底在筛什么想用Django做一套美容院相关毕设项目的人,大概率会搜到类似的标题:基于Python的美容院优质客户筛选系统。这个方向确实常青,我也在最近完整梳理并跑通过一套这样的系统&#xff0c…

2026/10/1 18:58:56 阅读更多 →
β-环糊精组合修饰全解析:PEG链连接FITC、Biotin、DBCO的设计与应用

β-环糊精组合修饰全解析:PEG链连接FITC、Biotin、DBCO的设计与应用

拿到“PEG-荧光素修饰β-环糊精,β-CD-PEG-FITC,β-CD-PEG-Biotin,DBCO-PEG修饰β-环糊精,β-CD-DBCO-PEG”这一串产品名时,多数人的第一反应是“这到底是个东西还是好几个东西”。其实这是一类典型的组合修饰型环糊精…

2026/10/1 18:57:55 阅读更多 →

日新闻

我发现了一个新思路:用 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/9/30 13:14:22 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

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

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

2026/9/30 18:13:06 阅读更多 →
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/9/30 13:14:49 阅读更多 →

月新闻

我发现了一个新思路:用 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 阅读更多 →