Android 多线程下载,断点续传
https://github.com/liu8021203/DownloadDemo
实现原理:
多线程下载:通过创建一个正在下载集合,等待下载集合(使用Vector保证同步)。
private ListwaitingList=newVector<>();
private ListthreadList=newVector<>();
创建一个数据集来保存要下载的数据
private MapdownloadMap=newHashMap<>();
在下载数据前先设置下载等待队列
下载核心代码:
```
/**
* 下载数据
*@paramvo
*/
public voiddownload(finalBeanVO vo)
{
setDownloadWaitingList(vo);
if(!loading)
{
newThread(){
@Override
public voidrun() {
try{
//等待数量
intwaitingSize =0;
//下载数量
intthreadlistSize =0;
while((waitingSize =waitingList.size()) >0)
{
loading=true;
threadlistSize =threadList.size();
//设置下载最大数 同时下载队列要小于等待队列
if(threadlistSize
{
String key =waitingList.get(threadlistSize);
if(!threadList.contains(key))
{
threadList.add(key);
BeanVO beanVO =downloadMap.get(key);
File file =newFile(FILE_PATH);
DownloadThread downloadThread =newDownloadThread(beanVO,file,listener);
downloadThread.start();
downloadThreadMap.put(key,downloadThread);
}
}
Thread.sleep(1000);
}
}catch(Exception e)
{
e.printStackTrace();
}
finally{
loading=false;
}
}
}.start();
}
}
```
断点续传:
创建数据库,将每个时段的下载的数据大小保存到数据库中, 当网断开时, 使用RandomAccessFile类从当前下载的位置继续下载。
代码如下:
inputStream inputStream =null;
HttpURLConnection connection =null;
RandomAccessFile randomAccessFile =null;
longfileSize =0;
longcompleteSize =0;
try{
fileSize = getResourceSize(fileUrl);
completeSize =vo.getCompleteSize();
URL url =newURL(fileUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(10*1000);
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept-Language","zh-CN");
connection.setRequestProperty("Referer",url.toString());
connection.setRequestProperty("Charset","UTF-8");
connection.setRequestProperty("Range","bytes="+ completeSize +"-"+ fileSize);//设置获取实体数据的范围
connection.setRequestProperty("User-Agent","Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
connection.setRequestProperty("Connection","Keep-Alive");
if(connection.getResponseCode() == HttpURLConnection.HTTP_PARTIAL)
{
vo.setSize(fileSize);
inputStream = connection.getInputStream();
byte[] buffer =new byte[1024];
intoffset =0;
randomAccessFile =newRandomAccessFile(saveFile,"rwd");
randomAccessFile.seek(completeSize);
longcurrentTime =0;
while((offset = inputStream.read(buffer)) != -1&& !isPause)
{
randomAccessFile.write(buffer,0,offset);
completeSize += offset;
if(System.currentTimeMillis() - currentTime >=3000)
{
currentTime = System.currentTimeMillis();
vo.setCompleteSize(completeSize);
listener.onProgress(vo);
}
}
vo.setCompleteSize(completeSize);
if(!isPause)
{
listener.onComplete(vo);
}
else
{
listener.onCancle(vo);
}
}
}
catch(Exception e)
{
e.printStackTrace();
listener.onError(vo);
}
finally{
try{
if(inputStream !=null)
{
inputStream.close();
}
if(randomAccessFile !=null)
{
randomAccessFile.close();
}
if(connection !=null)
{
connection.disconnect();
}
}catch(Exception e)
{
e.printStackTrace();
}
}
}
```
hi
```