多线程断点续传下载实践
来源:互联网 发布:陈奕迅热门歌曲知乎 编辑:程序博客网 时间:2024/06/03 18:45
各位同学,大家好,时隔半年我又回来了。这半年发生了很多事情… 感受颇为深刻,沾染上了赌博,很是后悔 但还能怎么样,接着撸代码吧 17年把输的钱好好敲代码赚回来。 大家如果有什么 项目呀都可以找我做。
有项目可以找我做。
有项目可以找我做。
有项目可以找我做。
卷起袖子开始撸吧 ,大家可以下看下 大概实现的功能以及最终效果;
如果想直接使用 请 进入:https://github.com/LidongWen/DownLoadUtils ;
需要达成的目标
实现的功能
- 文件可分为多段线程下载
- 基本功能
- 开始下载
- 暂停下载
- 继续下载
- 重新下载
- 自定义
- 设置 Https 证书、
- 设置下载地址、
- 最大下载文件数量等…
- 数据库操作
- 获取未完成列表;
- 获取已完成列表;
- 自定义获取列表;
最终效果图
不好意思,gif上传失败 示例图请查看:https://github.com/LidongWen/DownLoadUtils/blob/master/img/GIF.gif
或者 下载demo :https://fir.im/downLoad
扫一扫下载
准备知识
看完效果图以后觉得 ok 那么继续往下看,实现以上功能 我们需要掌握哪些知识
知识大纲列表
- Http原理
- RandomAccessFile 文件IO处理(文件创建、存放、分段写入)
- 广播(通知,数据回传,通知客户 我这个下载了 百分之几 了,我下载的速度是多少、我下载失败了 等…)
- 多线程编程(控制同时运行线程的数量;因为CPU资源有限的,如果CPU负荷过重 会导致我们的APP会挂掉,所以下载线程需要放在线程池中)
- 数据库(保存我们数据)
- 服务(可选)
稍微详细一点的 知识列表
- http原理
- https 签名认证
- http头字段
- http头部参数 http://xiejiaming.com/195.html
- Range(请求内容字节范围。字节偏移以0开始) 完整格式:
- Range: bytes=startOffset-targetOffset/sum [表示从startOffset读取,一直读取到targetOffset位置,读取总数为sum直接]
- Range: bytes=startOffset-targetOffset [字节总数也可以去掉]
- Range: bytes=startOffset- [从startOffset读取 到文件末尾]
- RandomAccessFile 随机访问文件流:
- public void seek(long pos) 设置当前文件指针相对于文件开头的偏移量
- Service :
- Service的使用场景:
- 后台任务,耗时操作 ,且需要在不同的UI内对其控制;
- Service生命周期;
- Service启动与销毁;
- startService()–stopService();
- bindService()–unbindService();
- startService()+bindService() – stopService()+unbindService();
- Service与 UI 通信:
- 对 UI 操作 影响Service
- bindService开启服务,UI 获取 binder对象 并通过binger提供的方法 操作 Service;
- startService() UI 传入数据service ,service通过数据来做相对应的动作;
- Service 影响 UI
- 通过广播通知
- 广播:
- 广播的生命周期;
- 广播的使用;
- 多线程
- thread 的使用;
- 线程池 ThreadPoolExecutor 的使用;
- 数据库
- sqlLite 升级处理:数据不丢失;
- sqlLite 增删查改的基本使用;
思路
- 使用 http 的 Range 字段 控制 拉取具体数据(比如 文件A 有10000字节,我可以控制 我只需要 500-1000 这段数据)
- RandomAccessFile 分段写入(比如文件 10000字节, 我可以 0-500 ,500-1000 写入)
- 线程池(控制最大下载的数量,下载队列…)
- 广播(通知)
- 数据库(保存下载的状态、进度 等待信息)
- 以上知识通过逻辑相互调用,就能做出一个多线程断点续传下载功能啦
我就写一下核心代码;
http 下载部分、写入文件流部分
将一个文件分为若干部分,分别下载,在下载过程中发送进度通知 UI。
我们先获取文件的长度,分为若干各部分分段下载
这边我一个文件分为3部分下载,得到三个 ThreadInfo(包含了每一段线程的信息,开始字节点、结束字节点、下载url):
int length = mFileInfo.getLength() / 3; // 获取单个线程下载长度for (int i = 0; i < mThreadNum; i++) { // 创建线程信息 ThreadInfo threadInfo = new ThreadInfo(); threadInfo.setId(mFileInfo.getId() + "_" + i); threadInfo.setUrl(mFileInfo.getUrl()); threadInfo.setStart(length * i); //开始节点 threadInfo.setEnd(((i + 1) * length - 1)); //结束节点 threadInfo.setFinished(0); threadInfo.setFileId(mFileInfo.getId()); threadInfo.setMd5(mFileInfo.getMd5()); threadInfo.setOver(false); threadInfo.setOvertime("none"); if (i == mThreadNum - 1) { threadInfo.setEnd(mFileInfo.getLength());// 设置最后一个线程的下载长度 } threadInfoList.add(threadInfo); // 添加线程信息到集合}
线程池启动三个线程分别下载ThreadInfo
下载的部分(这边大概写下 http数据流获取, 写入文件):
HttpURLConnection conn = null; conn = HttpUtils.getInstance().createConnection(mThreadInfo.getUrl()); conn.setRequestProperty("Range", "bytes=" + start + "-" + mThreadInfo.getEnd()); // 指定字节段 0~300.. if (conn.getResponseCode() == 206) {//注意这边 返回码是 206 input =conn.getInputStream();//得到输入流 //写入文件 File file = new File(DownloadConfig.getFileDir(), mFileInfo.getFileName()); raf = new RandomAccessFile(file, "rwd"); raf.seek(start);//指定位置开始写入 while ((len = input.read(buf)) != -1) { //写入文件 raf.write(buf, 0, len); mFinishedLen += len;// /** * 通知UI更新进度条 */ .... } ....
线程池
这部分 我直接使用 Executors.newFixedThreadPool
public static ExecutorService sExecutorService = Executors.newFixedThreadPool(5); //同时运行的线程数量,超过5个时,其他线程进入等待状态。 sExecutorService.execute(downloadThread);//加入线程池
数据库
作用:管理保存各个文件的状态 下载进度等信息。
这边我用的 greenDao,增删查改 等… 具体不写了
广播
在下在过程中 发送广播通知UI更新下载进度
Intent intent = new Intent(IntentAction.ACTION_UPDATE);intent.putExtra(KeyName.FINISHED_TAG, mFinishedLen);....intent.putExtra(KeyName.OTHER_MESSAGE, ((Serializable) postion));mContext.sendBroadcast(intent);
以上是发送更新广播, 暂停、结束等广播发送与其类似。就看你何时调用 传啥数据。
核心技术实现部分就几乎是以上部分了。
具体逻辑请查看代码具体代码清查看https://github.com/LidongWen/DownLoadUtils/tree/master/DownLoader;
基本上了解完上面的知识,代码就非常容易理解了, 没有理解又着急用也没有关系,我已经将它做成框架,几行代码就能集成使用啦
具体用法 API 请 进入:https://github.com/LidongWen/DownLoadUtils ;
- 多线程断点续传下载实践
- 多线程断点续传实践
- 多线程断点续传实践
- 多线程断点续传实践
- 多线程断点续传后台下载
- 多线程断点续传后台下载
- android 多线程断点续传下载
- 多线程断点续传后台下载
- 多线程并行下载,断点续传
- Android多线程.断点续传下载
- android 多线程断点续传下载
- Android 多线程下载断点续传
- Java多线程断点续传下载
- 多线程断点续传后台下载
- Android多线程断点续传下载
- 多线程断点续传下载Demo
- 多线程下载 断点续传
- 多线程断点续传下载
- 随笔 2. Master之后的深度学习
- 利用hibernate自动生成数据表的方法
- 基于SQL Alwayson的Windows Server 2012 WSFC搭建指南(2)——Windows 2012 Cluster搭建
- 阿里云上如何解析二级域名
- hdu 2126 Buy the souvenirs
- 多线程断点续传下载实践
- 视图
- 程序员面试金典——解题总结: 9.17中等难题 17.5珠玑妙算游戏
- 多线程原理
- 编辑文章 - 博客频道 - CSDN.NET
- 特征工程概述
- 北京天宇联科技有限责任公司—智慧园区
- 获取对象的内存地址
- (scala/java/python)实现分析商店购买记录