Android 实现多线程下载:
首先看下效果图:
UI界面
多线程下载的时候log打印界面
开始工作,首先我们通过HttpURLConnection类连接需要下载的文件:
new Thread(new Runnable() {
@Override
public void run() {
try {
url = new URL(DOWNURL);
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
// conn.connect();
totalLength = conn.getContentLength();
System.out.println(totalLength);
singleLength = (totalLength + THREADNUM - 1) / THREADNUM;
startDown();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
其中根据conn.getContentLength()函数计算需要下载文件的总字节长度
得到总长度后通过singleLength = (totalLength + THREADNUM - 1) / THREADNUM;计算出每个线程所负责的模块单位长度,在这里大家想一下为什么用这个公式而不是直接
singleLength = totalLength / THREADNUM;计算呢?
计算出单个线程负责模块长度后就方便了,我们直接通过循环调用多个线程,每个线程负责自己的下载模块,再此之前我们需要计算出每个木块下载的开始和结束位置
private void startDown() {
for (int i = 0; i < THREADNUM; i++) {
File cacheFile = new File(cacheDir, "temp" + i);
long begin = i * singleLength + cacheFile.length();
long end = begin + singleLength - 1;
System.out.println("第" + i + "个缓存文件:" + begin + "-" + end);
new downThread(begin, end, cacheFile).start();
}
}
然后开启多线程下载任务
class downThread extends Thread{
private long begin;
private long end;
private File cacheFile;
public downThread(long begin, long end, File cacheFile) {
super();
this.begin = begin;
this.end = end;
this.cacheFile = cacheFile;
}
@Override
public void run() {
try {
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
conn.setRequestProperty("Range", "bytes=" + begin + "-"
+ end);
FileOutputStream out = new FileOutputStream(cacheFile);
InputStream in = conn.getInputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = in.read(buffer)) != -1)
out.write(buffer, 0, len);
in.close();
out.close();
System.out.println(cacheFile.toString()+"缓存文件下载完成");
megageFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这里核心代码既是通过 conn.setRequestProperty("Range", "bytes=" + begin + "-" + end);这个语句控制每次请求服务器所下载的文件位置,其他地方和普通请求完全一致;
每个线程完成后,我们需要合并每个线程的缓存文件,合并缓存文件的时候要判断每个线程负责的模块都下载完毕并保证是顺序合并,
这里怎么实现,即 megageFile(); 这个函数的核心代码是什么呢?
我刚开始的时候下载文件内容1234567890 合并后就变成了 5678123490 ; 这里就不贴代码了留给大家思索
源码下载(附cache文件合并方法):点击打开链接