Http协议的下载功能
采用HttpClient组件实现Http下载,具有一些特有的优势。尽管java.net包提供了基本通过HTTP访问资源的功能,但它没有提供全面的灵活性和其它很多应用程序需要的功能。HttpClient就是寻求弥补这项空白的组件,通过提供一个有效的,保持更新的,功能丰富的软件包来实现客户端最新的HTTP标准和建议。
很多时候,单一的下载并不能满足我们的需要,而必须采用多线程的机制。但是众所周知,线程的创建和销毁都是需要开销的,例如,若同时打开几十个下载线程,这对系统的资源消耗是十分大的。我们可以采取线程池的方式,让池中下载的线程数目一定,这样就能做到高效的下载。
下载实现代码如下:
package com.yzy.downloader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.content.Context;
import android.content.Intent;
import android.os.Environment;
import android.util.Log;
public class DownloadManager {
// 下载地址
private String url;
// 下载任务线程池
private ExecutorService executorService;
// 应用程序上下文
private Context context;
public DownloadManager(Context context) {
super();
this.context = context;
}
public void addTask(String url, DownloadItem item) {
this.url = url;
executorService.submit(new DownloadThread(item));
}
public void stop() {
executorService.shutdown();
}
public void start() {
// 创建线程池
executorService = Executors.newFixedThreadPool(5);
}
public boolean isStop() {
return executorService.isShutdown();
}
class DownloadThread implements Runnable {
// 已经下载的字节数
private long finished;
// 文件总的字节数
private long fileLength;
// 文件ID号
private String fileId;
// 文件存储位置
private File downloadFile;
public DownloadThread(DownloadItem item) {
fileId = item.getFileId();
finished = item.getFileLength();
File sdFile = Environment.getExternalStorageDirectory();
downloadFile = new File(sdFile + File.separator + "image" + fileId
+ ".png");
if (!downloadFile.exists()) {
try {
downloadFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
Log.v("tag", "fileId=" + fileId + ",fileLength=" + fileLength);
try {
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(DownloadManager.this.url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
fileLength = httpEntity.getContentLength();
Log.v("tag", "查询得到文件大小为: " + fileLength);
httpClient.getConnectionManager().shutdown();
} catch (Exception e) {
e.printStackTrace();
}
try {
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(DownloadManager.this.url);
httpGet.addHeader("Range", "bytes=" + finished + "-"
+ (fileLength - 1));
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
FileOutputStream outputStream = new FileOutputStream(
downloadFile, true);
int count = 0;
int deltaCount = 0; // 增量
byte[] tmp = new byte[8 * 1024];
InputStream inputStream = httpEntity.getContent();
while (finished < fileLength) {
if (DownloadManager.this.executorService.isShutdown()) {
return;
}
count = inputStream.read(tmp);
finished += count;
deltaCount += count;
outputStream.write(tmp, 0, count);
if (Float.parseFloat(Integer.toString(deltaCount))
/ Float.parseFloat(Long.toString(fileLength)) > 0.05) {
deltaCount = 0;
Intent intent = new Intent("setProgressBar");
intent.putExtra("fileId", fileId);
int progressBarState = (int) (Float.parseFloat(Long
.toString(finished))
/ Float.parseFloat(Long.toString(fileLength)) * 100);
intent.putExtra("progressBarState", progressBarState);
DownloadManager.this.context.sendBroadcast(intent);
}
}
outputStream.close();
httpClient.getConnectionManager().shutdown();
Intent intent = new Intent("setProgressBar");
intent.putExtra("fileId", fileId);
intent.putExtra("progressBarState", 100);
DownloadManager.this.context.sendBroadcast(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
实现效果如下: