多线程断点下载

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

下载文件需要四步:

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

,因为连接网络是耗时的操作,所以要放在线程里用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();

 

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

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