技术文档--多线程断点下载

多线程断点下载

首先,在下载文件的时候大部分是在后台进行下载的,所以需要用到服务

下载文件需要四步:

第一步:获取文件的大小和在本地腾出相应的下载空间

  1,因为连接网络是耗时的操作,所以要放在线程里用HttpURLConnection连接网络

第二步:用RandomAccessFile setLength()在本地为下载的文件腾出空间

第三步:为每条下载线程分配下载的区域范围(一般都会在最后的线上分多一点的任务)

1,把新添加的下载文件的下载线程信息添加到数据库中

2,用线程池启动线程

3,判断每个文件下载是否完成,如果下载完成就发送广播通知

第四步  执行下载操作(下载操作就是对每条下载线程的下载资源的操作)

下载先需要对内存卡的状态进行判断

URL url=new URL(threadclass.getUrl());

http=(HttpURLConnection) url.openConnection();

http.setRequestMethod("GET");

http.setReadTimeout(5000);

int start=threadclass.getStart()+threadclass.getFinished();  //如果之前下载过就把该线程的开始位置和下载的资源相加

http.setRequestProperty("Range", "bytes="+start+"-"+threadclass.getEnd());

File file=new File(MyService.DOWN_FILE,soft.getName());  //下载文件的路径

access=new RandomAccessFile(file, "rwd");  //为暂停后的下载作标签

access.seek(start);   

mfinished=mfinished+threadclass.getFinished();   //之前若下载过,把之前的起源加起来

Intent intent2=new Intent(MyService.UPDATA_ACTION);  //用于下载进度更新数据发送

int code=http.getResponseCode();

if(code==206){

in=http.getInputStream();

int len=-1;

byte[] arr=new byte[1024*4];

long time=System.currentTimeMillis();  //当前的系统时间

while((len=in.read(arr))!=-1){

access.write(arr, 0, len);

threadclass.setFinished(threadclass.getFinished()+len);  //每条下载线程进度的更新

mfinished=mfinished+len;   //总的进度下载

//每隔1秒发送进度

if(System.currentTimeMillis()-time>1000){

time=System.currentTimeMillis();

intent2.putExtra("finished", mfinished*100/soft.getLength());  //进度更新

intent2.putExtra("id", soft.getId());   //判断那个文件下载

conn.sendBroadcast(intent2);   //发送广播

}

//如果标签为true直接把下载循环暂停

if(isDown){

sqlservice.updataThreadClass(threadclass.getFinished(), threadclass.getId(), threadclass.getUrl());

return;

}

}

//如果该线程下载完毕那么该标签就变成true

isFinished=true;

//监听每条线程下载资源是否完成

checkAllThreadFinished();

注意:在下载的时候,线程累加的问题,也是项目优化的一部分,就是在用完线程或

输入流,输出流时对其一一关闭,对资源的不浪费也会起到很大的作用

原文地址:https://www.cnblogs.com/zhangshibo/p/5755772.html