您的位置:首页 > 其它

多线程下载及XUtils框架使用

2014-06-27 12:13 471 查看
一、多线程下载

1、获取文件大小/**
* 获取要下载的文件大小
* @param urlStr
* @return
*/
public static long getFileLength(String urlStr) {
HttpURLConnection conn = null;
try {
URL url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(10 * 1000);
conn.setReadTimeout(6 * 1000);

conn.connect();
int code = conn.getResponseCode();
if (code == 200) {
//获取下载内容的大小,单位是byte
long contentLength = conn.getContentLength();
conn.disconnect();
return contentLength;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();
}
}
return 0;
}
2、主函数

private static int threadCount = 3; //下载的线程数量
private static long blockSize; //下载的文件平分每一块的大小

public static void main(String[] args) {
new Thread() {
public void run() {
//1,获取要下载的文件大小
String urlStr = "http://192.168.0.145//Content/App/DBX_140614_V2.0.apk";
long length = getFileLength(urlStr);
blockSize = length / threadCount;
try {
//2,本地创建一个空文件,文件大小和将下载的文件大小一样
File file = new File("D:\\test.apk");
//使用RandomAccessFile对象来创建。
//"rw"为可读写权限,当做多线程断点续传功能是,权限要改为"rwd",目的是能将中断在硬件缓冲区的数据强刷进硬盘。
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.setLength(length);
} catch (Exception e) {
e.printStackTrace();
}
//3,开启多个线程
for (int i = 0; i < threadCount; i++) {
//计算每个线程下载的开始位置和结束位置
long startPosition = i * blockSize;
long endPosition = (i + 1) * blockSize - 1;
if (i == threadCount - 1) {
endPosition = length - 1;
}
GetDataRunnable getDataRunnable = new GetDataRunnable(
urlStr, i, startPosition, endPosition);
Thread thread = new Thread(getDataRunnable);
thread.start();
}
};
}.start();
}

3、每个子线程分别下载对应的内容
private static class GetDataRunnable implements Runnable {
private int id;
private long startPosition;
private long endPosition;
private String urlStr;

public GetDataRunnable(String urlStr, int id, long startPosition,
long endPosition) {
this.id = id;
this.startPosition = startPosition;
this.endPosition = endPosition;
this.urlStr = urlStr;
}

@Override
public void run() {
HttpURLConnection conn = null;
RandomAccessFile raf = null;
InputStream is = null;
try {
URL url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
//设置该线程下载内容的范围
conn.setRequestProperty("Range", "bytes=" + startPosition + "-"
+ endPosition);
conn.setConnectTimeout(10 * 1000);
conn.setReadTimeout(6 * 1000);

conn.connect();
File file = new File("D:\\test.apk");
raf = new RandomAccessFile(file, "rw");
//把文件的位置指针定位在开始位置
raf.seek(startPosition);
//conn.getResponseCode() 成功返回码不是200
is = conn.getInputStream();
int len = -1;
byte[] b = new byte[1024];
while ((len = is.read(b)) != -1) {
//往RandomAccessFile指向的本地文件中写入数据
raf.write(b, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (raf != null) {
try {
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}

if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

}

二、Xutils框架的HttpUtils类使用
HttpUtils httpUtils = new HttpUtils();
httpUtils.download(
"http://192.168.0.145//Content/App/DBX_140614_V2.0.apk",
Environment.getExternalStorageDirectory().getAbsolutePath() + "/XX.zip", true,
true, new RequestCallBack<File>() {

@Override
public void onFailure(HttpException arg0, String arg1) {
Log.i("DBXStore", "onFailure:" + arg1);
}

@Override
public void onSuccess(ResponseInfo<File> arg0) {
Log.i("DBXStore", "onSuccess");
}
});

三、断点续传
断点续传功能其实就是在上面的多线程功能的基础上,增加一个下载字节的保存。每一个while循环都保存一下当前已下载的字节数。以便暂停后继续进行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多线程下载 Xutils