这篇文章主要介绍最简单的多线程下载与断点下载,其中要用到一个很重要的类RandomAcessFile。下面贴一下代码再进行讲解。
//保存线程信息集合
private List<HashMap<String , Integer>> threadList;
//文件长度
private int length;
//下载标识
private boolean downloading = false;
if (threadList.size() == 0) {
new Thread(new Runnable() {
@Override
public void run() {
try {
url = new URL(fileurl.getText().toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
//伪装成浏览器
conn.setRequestProperty("User-Agent",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)");
//文件长度
length = conn.getContentLength();
if (length < 0) {
Toast.makeText(MainActivity.this , "文件不存在" , Toast.LENGTH_LONG).show();
return;
}
file = new File(Environment.getExternalStorageDirectory(), getfileName(fileurl.getText().toString()));
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
randomAccessFile.setLength(length);
int blockSize = length / 3;
for (int i = 0; i < 3; i++) {
int begin = i * blockSize;
int end = (i + 1) * blockSize - 1;
if (i == 2) {
end = length;
}
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("begin", begin);
map.put("end", end);
map.put("finished", 0);
threadList.add(map);
// 创建下载线程,下载
Thread t = new Thread(new DownLoadRunnable(i, begin, end, file, url));
t.start();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}else {
for (int i = 0 ; i < threadList.size() ; i++){
HashMap<String, Integer> map = threadList.get(i);
int begin = map.get("begin");
int end = map.get("end");
int finished = map.get("finished");
Thread t = new Thread(new DownLoadRunnable(i, begin + finished, end, file, url));
t.start();
}
}
简单来讲,首先获取你要下载文件的大小,然后将这个文件分块,标记起始位置和结束位置,将这个信息存储到threadlist中,作为下载的标识。需要下载是将begin、finished、end的信息提取出来,设置好起始位置和结束位置进行,创建线程和下载类进行下载。下面贴一下下载类的代码。这里的下载类是一个内部类。
class DownLoadRunnable implements Runnable{
private int begin;
private int end;
private File file;
private URL url;
private int id;
public DownLoadRunnable(int id , int begin , int end , File file, URL url){
this.id = id;
this.begin = begin;
this.end = end;
this.file = file;
this.url = url;
}
@Override
public void run() {
try {
if (begin > end)
{
return;
}
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("User-Agent",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)");
conn.setRequestProperty("Range", "bytes=" + begin + "-" + end); //设置下载区间
InputStream is = conn.getInputStream();
byte[] buf = new byte[1024 * 1024]; // 缓存
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
randomAccessFile.seek(begin);
int len;
HashMap<String, Integer> map = threadList.get(id);
while ((len = is.read(buf)) != -1 && downloading == true){
randomAccessFile.write(buf, 0, len);
updateProgress(len);
map.put("finished" , map.get("finished") + len);
Log.d("Download Lenth: " ,""+ total);
}
is.close();
randomAccessFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}