Android多线程下载大文件解析
1、多线程介绍
用过迅雷的同学都知道。迅雷有个功能叫做多线程。另一个叫离线下载,我们这里重点介绍一下多线程下载。多线程,顾名思义就是非常多歌线程同一时候在执行,为什么要提出多线程这个概念呢?由于有时候一个线程下载太慢了。举个样例,比方小时候常做的数学题,一个人挖沟须要15天,那么两个人对着挖呢?
当然数学题上面两个人的效率是不一样的,我们这里把这个问题简化了一下。仅仅是想大家明确,什么是多线程,为什么有多线程。
在多线程上出现过一个问题,为什么有要提出多线程?事实上提出多线程是为了充分利用CPU的硬件资源,解决应用程序等待的问题。多线程是为了同步完毕多项任务,不是为了提高执行效率,而是为了提高资源使用效率来提高系统的效率。线程是在同一时间须要完毕多项任务的时候实现的。
2、思路
(1)获取网络连接
(2)初始化多线程下载信息,開始下载
(3)开辟硬盘空间,用于存放数据资源
(4)把从网络获取的数据放入申请的空间中
(5)完成下载,关闭资源链接
给出一个下载400M电影的示意图,例如以下所看到的:
RandomAccessFile支持随机的訪问
HTTP的Range头字段指定每一个线程从文件的什么位置開始下载。
3、代码解析
3.1 设置须要下载文件的信息
- RandomAccessFile randOut = new RandomAccessFile(this.saveFile, "rwd");
- if(this.fileSize>0){
- randOut.setLength(this.fileSize);//设置文件的大小
- }
- randOut.close(); //关闭该文件,使设置生效
3.2 设置下载链接,而且開始划分下载部分
- URL url = new URL(this.downloadUrl);
- if(this.data.size() != this.threads.length){ //假设原先未曾下载或者原先的下载线程数与如今的线程数不一致
- this.data.clear(); //将数据置空
- for (int i = 0; i < this.threads.length; i++) { //遍历线程池
- this.data.put(i+1, 0);//初始化每条线程已经下载的数据长度为0
- }
- this.downloadedSize = 0; //设置已经下载的长度为0
- }
3.3 開始下载文件
- for (int i = 0; i < this.threads.length; i++) {
- //通过特定的线程ID获取该线程已经下载的数据长度
- int downloadedLength = this.data.get(i+1);
- //推断线程是否已经完毕下载,否则继续下载
- if(downloadedLength < this.block && this.downloadedSize < this.fileSize){
- //初始化特定id的线程
- this.threads[i] = new DownloadThread(this, url, this.saveFile, this.block, this.data.get(i+1), i+1);
- //设置线程的优先级,Thread.NORM_PRIORITY = 5 Thread.MIN_PRIORITY = 1 Thread.MAX_PRIORITY = 10
- this.threads[i].setPriority(7);
- //启动线程
- this.threads[i].start();
- }else{
- this.threads[i] = null; //表明在线程已经完毕下载任务
- }
- }
3.4 监听文件是否下载完毕以及完毕之后的操作
- fileService.delete(this.downloadUrl); //假设存在下载记录,删除它们。然后又一次加入
- fileService.save(this.downloadUrl, this.data); //把已经下载的实时数据写入数据库
- boolean notFinished = true;//下载未完毕
- // 循环推断所有线程是否完毕下载
- while (notFinished) {
- notFinished = false;//假定所有线程下载完毕
- for (int i = 0; i < this.threads.length; i++){
- if (this.threads[i] != null && !this.threads[i].isFinished()) {//假设发现线程未完毕下载
- notFinished = true;//设置标志为下载没有完毕
- //假设下载失败,再又一次在已经下载的数据长度的基础上下载
- if(this.threads[i].getDownloadedLength() == -1){
- //又一次开辟下载线程。代码与上面一致
- }
- }
- }
- if(listener!=null){
- listener.onDownloadSize(this.downloadedSize);
- }//通知眼下已经下载完毕的数据长度
- }
- //下载完毕删除记录
- if(downloadedSize == this.fileSize){
- fileService.delete(this.downloadUrl);
- }
4、断点续传
断点续传是说在下载的时候,我们由于某些原因,导致了下载的暂停。比方在电脑上,我们的电脑突然断电了,手机上的网络中断了,都会导致当前的下载任务终止,那么当我们再次回来的时候。程序应该是能够继续下载的,不然前面下载的资源就都浪费了。
依据上面的描写叙述。我们应该能够知道。实现断点续传,关键是实现下载的数据存储在数据库中,等到之后我们程序再次进入的时候,会到数据库中去查询一下数据。然后接着继续下载。
而存储数据到数据库并非太复杂,难的是怎样识别程序的哪些数据被下载了。哪些数据是没有下载的。这里,我们在下载的时候使用了下载的线程id做识别。
假设该线程id的数据没有被完整下载。应该是不会存储到数据库的,那么这一部分的数据就要又一次下载,在下载完毕之后,数据拼接起来就是一个完整的文件了。
Android多线程下载大文件解析的更多相关文章
- Android 开发工具类 27_多线程下载大文件
多线程下载大文件时序图 FileDownloader.java package com.wangjialin.internet.service.downloader; import java.io.F ...
- Andoid 更好的Android多线程下载框架
概述 为什么是更好的Android多线程下载框架呢,原因你懂的,广告法嘛! 本篇我们我们就来聊聊多线程下载框架,先聊聊我们框架的特点: 多线程 多任务 断点续传 支持大文件 可以自定义下载数据库 高度 ...
- 更好的Android多线程下载框架
/** * 作者:Pich * 原文链接:http://me.woblog.cn/ * QQ群:129961195 * Github:https://github.com/lifengsofts */ ...
- 无废话Android之smartimageview使用、android多线程下载、显式意图激活另外一个activity,检查网络是否可用定位到网络的位置、隐式意图激活另外一个activity、隐式意图的配置,自定义隐式意图、在不同activity之间数据传递(5)
1.smartimageview使用 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&q ...
- android程序---->android多线程下载(一)
多线程下载是加快下载速度的一种方式,通过开启多个线程去执行一个任务,可以使任务的执行速度变快.多线程的任务下载时常都会使用得到断点续传下载,就是我们在一次下载未结束时退出下载,第二次下载时会接着第一次 ...
- android程序---->android多线程下载(二)
上篇我们讲到了android中下载的断点续传问题,今天我们开始学习下载的多线程问题.本次的多线程源码下载:androdi中多线程下载的实现代码.有关断点续传的问题,请参见博客:android程序--- ...
- 转(Response.WriteFile 无法下载大文件解决方法)
以前用Response.WriteFile(filename),但当遇到大文件时无法完整下载. 该方法最大的问题,它不是直接将数据抛到客户端,而是在服务器端(IIS)上缓存.当下载文件比较大时,服务器 ...
- JAVA多线程下载网络文件
JAVA多线程下载网络文件,开启多个线程,同时下载网络文件. 源码如下:(点击下载 MultiThreadDownload.java) import java.io.InputStream; im ...
- python下载大文件
1. wget def download_big_file_with_wget(url, target_file_name): """ 使用wget下载大文件 Note: ...
随机推荐
- 九度oj 题目1459:Prime ring problem
题目描述: A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ..., n into each ...
- 【Luogu】P2254瑰丽华尔兹(堆优化DP)
题目链接 我也不知道为什么脑子一抽就想了个堆优化……然后贼慢…… 因为上午听不懂wys的电音专场(快速傅立叶变换),然后就做了这么一道题. 首先朴素DP很sb都能秒出.就是枚举时刻.位置(两维)然后转 ...
- 【Luogu】P2602数字计数(数位DP)
题目链接 数位DP好喵啊.自己yy两个小时的dfs:题解40行代码=10WA:10A. md而且还不是完全理解题解是什么意思. 所以放题解链接. #include<cstdio> #inc ...
- 【Luogu】P3343地震后的幻想乡(对积分概率进行DP)
题目链接 神难qwq.配合rqy的博客食用. 首先我们学到有一个概率函数$p(x)$表示某事件发生概率取值小于x的函数.这个函数有什么特点呢? 那就是$\int_{-∞}^{∞}p(x)dx=1$ 这 ...
- ACM程序设计选修课——1051: Glamor Sequence(YY+求和公式)
1051: Glamor Sequence Time Limit: 1 Sec Memory Limit: 128 MB Submit: 16 Solved: 5 [Submit][Status] ...
- 【bzoj1257】[CQOI2007]余数之和sum
[bzoj1257][CQOI2007]余数之和sum 2014年9月1日1,9161 Description 给出正整数n和k,计算j(n, k)=k mod 1 + k mod 2 + k mod ...
- Docker 使用指南—— 基本操作
版权声明:本文由田飞雨原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/98来源:腾云阁 https://www.qcloud ...
- linux内核学习之四:进程切换简述【转】
转自:http://www.cnblogs.com/xiongyuanxiong/p/3531884.html 在讲述专业知识前,先讲讲我学习linux内核使用的入门书籍:<深入理解linux内 ...
- poj 3204(最小割--关键割边)
Ikki's Story I - Road Reconstruction Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 7 ...
- LeetCode OJ--Next Permutation *
求一个排列的下一个排列. 1,2,3 → 1,3,23,2,1 → 1,2,31,1,5 → 1,5,1 #include <iostream> #include <vector&g ...