ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

download4cj下载进度监控指南:fetchProgress与BlockInfo打造丝滑进度条

download4cj下载进度监控指南:fetchProgress与BlockInfo打造丝滑进度条 download4cj下载进度监控指南fetchProgress与BlockInfo打造丝滑进度条【免费下载链接】download4cj一个文件下载库项目地址: https://gitcode.com/Cangjie-TPC/download4cjdownload4cj 是一个纯仓颉Cangjie语言编写的文件下载库支持多线程下载、暂停续传与异步任务调度。这篇download4cj 下载进度监控指南聚焦fetchProgress回调与BlockInfo分块信息两个核心 API教你用极少的代码打造丝滑的下载进度条 一、为什么进度条会卡顿fetchProgress回调时机揭秘很多新手第一次实现下载进度条时都会遇到进度跳着走、UI卡死的问题。根源在于下载数据是按缓冲区一次性读入的默认每次读取readBufferSize字节如果把每次读缓冲都当作一次回调UI 线程就会被海量回调淹没。download4cj 在源码层已经帮你做了节流。数据读取发生在 fetch_data_inteceptor.cj每次从网络读到数据后先通过increaseCallbackBytes累加未回调字节数再由 callback_dispatcher.cj 判断距离上次回调是否达到了你在setMinIntervalMillisCallbackProcess中设置的间隔示例中为 30ms到了时机才触发一次 fetchProgress 回调把累加的字节数一次性冲刷出去见 download_chain.cj。 一句话理解fetchProgress 给你的是增量increaseBytes不是总量进度条要自己做累加。二、三步打造丝滑进度条建任务、收回调、算总进度第1步用 DownloadTaskBuilder 构造任务并设置节流间隔let task: DownloadTask DownloadTaskBuilder(url, parentFilePath) .setFilename(single-test.jpg) .setMinIntervalMillisCallbackProcess(30) // 每30ms回调一次进度 .build() task.execute(MyListen()) // 同步下载 // task.enqueue(MyListen()) // 异步下载setMinIntervalMillisCallbackProcess(30)就是丝滑度的关键旋钮值越小进度条越灵敏值越大回调越省 CPU。接口定义详见 doc/feature_api.md。第2步在监听器中接收 fetchProgress 增量实现DownloadListener接口完整回调清单见 download_listener.cj只需关注进度相关的三个回调public class MyListen : DownloadListener { public func fetchProgress(task: DownloadTask, blockIndex: Int64, increaseBytes: Int64): Unit { // increaseBytes这一批新下载的字节数累加即可驱动进度条 } // taskStart / taskEnd / fetchStart / fetchEnd ... 其余回调按需实现 }第3步汇总所有分块计算总进度download4cj 默认把文件拆成多个块block多线程下载每个块各自回调。总进度 各块已下字节之和 ÷ 各块长度之和let blocks: ArrayListBlockInfo task.getBlockInfoList().getOrThrow() var downloaded: Int64 0 var total: Int64 0 for (b in blocks) { downloaded b.getCurrentOffset() total b.getContentLength() } var percent: Double Double(downloaded) / Double(total) * 100.0三、BlockInfo详解每个下载块的5个进度关键字段BlockInfo是进度监控的数据底座源码block_info.cj它用原子变量AtomicInt64保存当前块进度多线程下读取也安全方法含义在进度条中的用途getCurrentOffset()该块已下载的字节数块进度分子 ✅getContentLength()该块的总长度块进度分母getStartOffset()该块在文件中的起始字节偏移定位块在文件中的位置getRangeLeft()startOffset currentOffset已下载部分的右边界可视化下到哪了getRangeRight()startOffset contentLength - 1块的右边界判断块是否下载完毕所有块的BlockInfo统一存放在BreakpointInfo中break_ponit_info.cj任务每新增一个下载块就addBlock一条记录。四、暂停时监控进度getBlockInfoList一键取断点信息暂停/断点续传场景下想知道暂停那一刻每个块下到了哪里直接调用 getBlockInfoList 即可task.cancel() // 暂停任务 let blockList: ArrayListBlockInfo task.getBlockInfoList().getOrThrow() for (oneitem in blockList) { println(blockinfoCurrent oneitem.getCurrentOffset().toString() blockinfoContent oneitem.getContentLength().toString()) println(blockinfoRangeLeft oneitem.getRangeLeft().toString() blockinfoRangeRight oneitem.getRangeRight().toString()) }官方 README 中的暂停下载示例README.md 同步下载暂停下载示例一节就是这么打印每个块的currentOffset / contentLength / rangeLeft / rangeRight的多任务暂停场景则配合DownloadTask.cancels(tasks)批量处理。五、让进度条更顺滑的3个实战技巧合理设置节流间隔普通场景 30ms 左右即可大文件、低速网络可放宽到 100~200ms避免无意义刷新。多任务用 taskId 区分task.getId()返回唯一任务 ID回调中用它把不同文件的进度映射到各自的进度条 UI 上。注意 chunked 传输若服务器响应未携带Content-Length分块传输编码单块contentLength可能不可知此时建议用已下载字节数 实时速率替代百分比展示BreakpointInfo内部已用chunked标记区分该情况。六、核心源码文件速查想进一步深入进度监控机制可以按下面路径阅读源码进度回调定义src/download_listener.cj分块进度数据src/block_info.cj、src/break_ponit_info.cj节流与冲刷逻辑src/callback_dispatcher.cj、src/download_chain.cj数据读取与进度累加src/fetch_data_inteceptor.cj获取块进度列表src/download_task.cj完整接口文档doc/feature_api.md七、总结download4cj 的下载进度监控设计非常清晰fetchProgress 负责高频增量通知BlockInfo 负责随时可查的分块进度快照。只要记住三步——设置节流间隔、累加增量回调、汇总getBlockInfoList计算总进度——你就能为自己的仓颉应用打造一条流畅、准确、可暂停续传的下载进度条 【免费下载链接】download4cj一个文件下载库项目地址: https://gitcode.com/Cangjie-TPC/download4cj创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表