Android下載封裝類
public class Download implements Serializable {
private static final int START = 1; // 開始下載
private static final int PUBLISH = 2; // 更新進度
private static final int PAUSE = 3; // 暫停下載
private static final int CANCEL = 4; // 取消下載
private static final int ERROR = 5; // 下載錯誤
private static final int SUCCESS = 6; // 下載成功
private static final int GOON = 7; // 繼續下載
private static ExecutorService mThreadPool; // 線程池
static {
mThreadPool = Executors.newFixedThreadPool(5); // 默認5個
}
private int mDownloadId; // 下載id
private String mFileName; // 本地保存文件名
private String mUrl; // 下載地址
private String mLocalPath; // 本地存放目錄
private boolean isPause = false; // 是否暫停
private boolean isCanceled = false; // 是否手動停止下載
private OnDownloadListener mListener; // 監聽器
/**
* 配置下載線程池的大小
* @param maxSize 同時下載的最大線程數
*/
public static void configDownloadTheadPool(int maxSize) {
mThreadPool = Executors.newFixedThreadPool(maxSize);
}
/**
* 添加下載任務
* @param downloadId 下載任務的id
* @param url 下載地址
* @param localPath 本地存放地址
*/
public Download(int downloadId, String url, String localPath) {
if (!new File(localPath).exists()) {
new File(localPath).mkdirs();
}
Log.log("下載地址;" + url);
mDownloadId = downloadId;
mUrl = url;
String[] tempArray = url.split("/");
mFileName = tempArray[tempArray.length-1];
mLocalPath = localPath;
}
/**
* 設置監聽器
* @param listener 設置下載監聽器
* @return this
*/
public Download setOnDownloadListener(OnDownloadListener listener) {
mListener = listener;
return this;
}
/**
* 獲取文件名
* @return 文件名
*/
public String getFileName() {
return mFileName;
}
/**
* 開始下載
* params isGoon是否為繼續下載
*/
public void start(final boolean isGoon) {
// 處理消息
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case ERROR:
mListener.onError(mDownloadId);
break;
case CANCEL:
mListener.onCancel(mDownloadId);
break;
case PAUSE:
mListener.onPause(mDownloadId);
break;
case PUBLISH:
mListener.onPublish(mDownloadId, Long.parseLong(msg.obj.toString()));
break;
case SUCCESS:
mListener.onSuccess(mDownloadId);
break;
case START:
mListener.onStart(mDownloadId, Long.parseLong(msg.obj.toString()));
break;
case GOON:
mListener.onGoon(mDownloadId, Long.parseLong(msg.obj.toString()));
break;
}
}
};
// 真正開始下載
mThreadPool.execute(new Runnable() {
@Override
public void run() {
download(isGoon,handler);
}
});
}
/**
* 下載方法
* @param handler 消息處理器
*/
private void download(boolean isGoon, Handler handler) {
Message msg = null;
Log.log("開始下載。。。");
try {
RandomAccessFile localFile = new RandomAccessFile(new File(
mLocalPath + File.separator + mFileName), "rwd");
DefaultHttpClient client = new DefaultHttpClient();
client.setParams(getHttpParams());
HttpGet get = new HttpGet(mUrl);
long localFileLength = getLocalFileLength();
final long remoteFileLength = getRemoteFileLength();
long downloadedLength = localFileLength;
// 遠程文件不存在
if (remoteFileLength == -1l) {
Log.log("下載文件不存在...");
localFile.close();
handler.sendEmptyMessage(ERROR);
return;
}
// 本地文件存在
if (localFileLength > -1l && localFileLength < remoteFileLength) {
Log.log("本地文件存在...");
localFile.seek(localFileLength);
get.addHeader("Range", "bytes=" + localFileLength + "-"
+ remoteFileLength);
}
msg = Message.obtain();
// 如果不是繼續下載
if(!isGoon) {
// 發送開始下載的消息并獲取文件大小的消息
msg.what = START;
msg.obj = remoteFileLength;
}else {
msg.what = GOON;
msg.obj = localFileLength;
}
handler.sendMessage(msg);
HttpResponse response = client.execute(get);
int httpCode = response.getStatusLine().getStatusCode();
if (httpCode >= 200 && httpCode <= 300) {
InputStream in = response.getEntity().getContent();
byte[] bytes = new byte[1024];
int len = -1;
while (-1 != (len = in.read(bytes))) {
localFile.write(bytes, 0, len);
downloadedLength += len;
// Log.log((int)(downloadedLength/(float)remoteFileLength * 100));
if ((int)(downloadedLength/(float)remoteFileLength * 100) % 10 == 0) {
// 發送更新進度的消息
msg = Message.obtain();
msg.what = PUBLISH;
msg.obj = downloadedLength;
handler.sendMessage(msg);
// Log.log(mDownloadId + "已下載" + downloadedLength);
}
// 暫停下載, 退出方法
if (isPause) {
// 發送暫停的消息
handler.sendEmptyMessage(PAUSE);
Log.log("下載暫停...");
break;
}
// 取消下載, 刪除文件并退出方法
if (isCanceled) {
Log.log("手動關閉下載。。");
localFile.close();
client.getConnectionManager().shutdown();
new File(mLocalPath + File.separator + mFileName)
.delete();
// 發送取消下載的消息
handler.sendEmptyMessage(CANCEL);
return;
}
}
localFile.close();
client.getConnectionManager().shutdown();
// 發送下載完畢的消息
if(!isPause) handler.sendEmptyMessage(SUCCESS);
}
} catch (Exception e) {
// 發送下載錯誤的消息
handler.sendEmptyMessage(ERROR);
}
}
/**
* 暫停/繼續下載
* param pause 是否暫停下載
* 暫停 return true
* 繼續 return false
*/
public synchronized boolean pause(boolean pause) {
if(!pause) {
Log.log("繼續下載");
isPause = false;
start(true); // 開始下載
}else {
Log.log("暫停下載");
isPause = true;
}
return isPause;
}
/**
* 關閉下載, 會刪除文件
*/
public synchronized void cancel() {
isCanceled = true;
if(isPause) {
new File(mLocalPath + File.separator + mFileName)
.delete();
}
}
/**
* 獲取本地文件大小
* @return 本地文件的大小 or 不存在返回-1
*/
public synchronized long getLocalFileLength() {
long size = -1l;
File localFile = new File(mLocalPath + File.separator + mFileName);
if (localFile.exists()) {
size = localFile.length();
}
Log.log("本地文件大小" + size);
return size <= 0 ? -1l : size;
}
/**
* 獲取遠程文件打下 or 不存在返回-1
* @return
*/
public synchronized long getRemoteFileLength() {
long size = -1l;
try {
DefaultHttpClient client = new DefaultHttpClient();
client.setParams(getHttpParams());
HttpGet get = new HttpGet(mUrl);
HttpResponse response = client.execute(get);
int httpCode = response.getStatusLine().getStatusCode();
if (httpCode >= 200 && httpCode <= 300) {
size = response.getEntity().getContentLength();
}
client.getConnectionManager().shutdown();
} catch (Exception e) {
e.printStackTrace();
}
Log.log("遠程文件大小" + size);
return size;
}
/**
* 設置http參數 不能設置soTimeout
* @return HttpParams http參數
*/
private static HttpParams getHttpParams() {
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
HttpProtocolParams.setUseExpectContinue(params, true);
HttpProtocolParams
.setUserAgent(
params,
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2041.4 Safari/537.36");
ConnManagerParams.setTimeout(params, 4000);
HttpConnectionParams.setConnectionTimeout(params, 4000);
return params;
}
/**
* 關閉下載線程池
*/
public static void closeDownloadThread() {
if(null != mThreadPool) {
mThreadPool.shutdownNow();
}
}
public interface OnDownloadListener {
public void onStart(int downloadId, long fileSize); // 回調開始下載
public void onPublish(int downloadId, long size); // 回調更新進度
public void onSuccess(int downloadId); // 回調下載成功
public void onPause(int downloadId); // 回調暫停
public void onError(int downloadId); // 回調下載出錯
public void onCancel(int downloadId); // 回調取消下載
public void onGoon(int downloadId, long localSize); // 回調繼續下載
}
}
如何調用,如下:
Download d = new Download(1, "http://baidu.com/test.zip","/sdcard/download/");
d.setOnDownloadListener(new Download.OnDownloadListener() {
@Override
public void onSuccess(int downloadId) {
System.out.println(downloadId + "下載成功");
}
@Override
public void onStart(int downloadId, long fileSize) {
System.out.println(downloadId + "開始下載,文件大小:" + fileSize);
}
@Override
public void onPublish(int downloadId, long size) {
System.out.println("更新文件" + downloadId + "大小:" + size);
}
@Override
public void onPause(int downloadId) {
System.out.println("暫停下載" + downloadId);
}
@Override
public void onGoon(int downloadId, long localSize) {
System.out.println("繼續下載" + downloadId);
}
@Override
public void onError(int downloadId) {
System.out.println("下載出錯" + downloadId);
}
@Override
public void onCancel(int downloadId) {
System.out.println("取消下載" + downloadId);
}
});
d.start(false);
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!