多线程断点下载
首先,在下载文件的时候大部分是在后台进行下载的,所以需要用到服务
下载文件需要四步:
第一步:获取文件的大小和在本地腾出相应的下载空间
,因为连接网络是耗时的操作,所以要放在线程里用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();
注意:在下载的时候,线程累加的问题,也是项目优化的一部分,就是在用完线程或
输入流,输出流时对其一一关闭,对资源的不浪费也会起到很大的作用