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 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!