// 检查缓存目录中是否已经下载过文件 private String checkFromCache(DownloadRequest request) { if (request != null && !TextUtils.isEmpty(request.mDownloadUrl)) { String saveUrl = mDownloadFilenameCreateListener != null ? mDownloadFilenameCreateListener.onFilenameCreateWithDownloadUrl( request.mDownloadUrl) : mDefaultDownloadFilenameCreateListener.onFilenameCreateWithDownloadUrl( request.mDownloadUrl); if (TextUtils.isEmpty(DOWNLOADED_FILE_DIR)) { return null; } File dir = new File(DOWNLOADED_FILE_DIR); if (!dir.exists() || dir.isFile()) { return null; } String extension = TextUtils.isEmpty(request.mFileExtension) ? "" : "." + request.mFileExtension; File cachedFile = new File(DOWNLOADED_FILE_DIR + saveUrl + extension); if (cachedFile.exists()) { if (DEBUG) { CommonUtilsConfig.LOGD_WITH_TIME( "<<<<< [[find in cache]] >>>>> ::::::::: " + cachedFile.getAbsolutePath()); } return cachedFile.getAbsolutePath(); } } if (DEBUG) { CommonUtilsConfig.LOGD_WITH_TIME( "<<<<< [[can not find in cache]] >>>>> ::::::::: " + request.toString()); } return null; }
/** * 将下载好的文件从缓存目录移动到下载完成的目录 * * @param cachedFile * @param extension * @return */ private String mvFileToDownloadedDir(String cachedFile, String extension) { CommonUtilsConfig.LOGD("----- move cached file to + " + DOWNLOADED_FILE_DIR); File dir = new File(DOWNLOADED_FILE_DIR); if (!dir.exists() || !dir.isDirectory()) { dir.delete(); dir.mkdirs(); } File file = new File(cachedFile); String ext = TextUtils.isEmpty(extension) ? "" : "." + extension; File newFile = new File(dir.getAbsolutePath() + "/" + file.getName() + ext); // // 重命名成功 if (CommonUtilsRuntime.isExternalStorageAvailable() && file.renameTo(newFile)) { CommonUtilsConfig.LOGD( "----- move cached file to + " + newFile.getAbsolutePath() + " successfully InstallApp======="); return newFile.getAbsolutePath(); } // 如果重命名失败,则通过拷贝实现 InputStream is = null; OutputStream os = null; try { is = new FileInputStream(file); os = null; if (dir.getAbsolutePath().startsWith("/data/data")) { CommonUtilsConfig.LOGD( "open world readable file" + " successfully InstallApp=======" + file.getName() + ext); os = mContext.openFileOutput(file.getName() + ext, Context.MODE_WORLD_READABLE); } else { CommonUtilsConfig.LOGD("new FileOutputStream, InstallApp"); os = new FileOutputStream(newFile); } CommonUtilsConfig.LOGD( "----- move cached file to + " + newFile.getAbsolutePath() + " successfully InstallApp======="); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (FileUtil.copy(is, os)) { file.delete(); return newFile.getAbsolutePath(); } return null; }
private DownloadRequest findRequestCanOperate(ArrayList<DownloadRequest> requestList) { if (DEBUG) { CommonUtilsConfig.LOGD_WITH_TIME("<<<<< [[findRequestCanOperate]] >>>>>"); } synchronized (requestList) { for (DownloadRequest r : requestList) { if (!r.requestIsOperating.get()) { r.requestIsOperating.set(true); if (DEBUG) { CommonUtilsConfig.LOGD_WITH_TIME( "<<<<< [[findRequestCanOperate]] end findRequestCanOperate >>>>>"); } return r; } } return null; } }
private void waitforUrl() { try { synchronized (objLock) { if (mRequestList.size() == 0 && !bIsWaiting) { bIsWaiting = true; if (DEBUG) { CommonUtilsConfig.LOGD("entry into [[waitforUrl]] for " + DEFAULT_KEEPALIVE + "ms"); } objLock.wait(mKeepAlive); if (DEBUG) { CommonUtilsConfig.LOGD("leave [[waitforUrl]] for " + DEFAULT_KEEPALIVE + "ms"); } } } } catch (Exception e) { e.printStackTrace(); if (DEBUG) { CommonUtilsConfig.LOGD("Excption : ", e); } } bIsWaiting = false; }
@Override public void run() { while (!bIsStop) { waitforUrl(); if (DEBUG) { CommonUtilsConfig.LOGD_WITH_TIME("<<<<< [[run]] >>>>>"); } synchronized (mRequestList) { if (mRequestList.size() == 0) { // bIsRunning = false; bIsStop = true; break; } } if (DEBUG) { CommonUtilsConfig.LOGD_WITH_TIME("<<<<< [[run]] end synchronized (mRequestList) >>>>>"); } DownloadRequest request = null; try { request = findRequestCanOperate(mRequestList); if (request == null) { bIsStop = true; } if (request != null && request.mStatus != DownloadRequest.STATUS_CANCEL) { if (DEBUG) { CommonUtilsConfig.LOGD( "================ <<" + Thread.currentThread().getName() + ">> working on : "); CommonUtilsConfig.LOGD("begin operate one request : " + request.toString()); CommonUtilsConfig.LOGD("============================================"); } String cacheFile = InternetUtils.requestBigResourceWithCache( mContext, request.mDownloadUrl, request.getHeaders()); if (DEBUG) { CommonUtilsConfig.LOGD("----- after get the cache file : " + cacheFile + " ======="); } if (!TextUtils.isEmpty(cacheFile)) { // 将文件移动到下载完成的页面 String filePath = mvFileToDownloadedDir(cacheFile, request.mFileExtension); if (!TextUtils.isEmpty(filePath)) { // notify success // 将文件移动到下载完成的页面 DownloadResponse response = tryToHandleDownloadFile(filePath, request); if (response != null) { mSuccessHandler.notifyAll(-1, -1, response); handleResponseByListener(DOWNLOAD_SUCCESS, request.mDownloadUrl, response, false); removeRequest(request); continue; } else { handleResponseByListener(DOWNLOAD_FAILED, request.mDownloadUrl, request, false); mFailedHandler.notifyAll(-1, -1, request); continue; } } else { handleResponseByListener(DOWNLOAD_FAILED, request.mDownloadUrl, request, false); mFailedHandler.notifyAll(-1, -1, request); continue; } } if (request.getmStatus() != DownloadRequest.STATUS_CANCEL) { handleResponseByListener(DOWNLOAD_FAILED, request.mDownloadUrl, request, false); mFailedHandler.notifyAll(-1, -1, request); } else { handleResponseByListener(DOWNLOAD_FAILED, request.mDownloadUrl, request, true); } if (DEBUG) { CommonUtilsConfig.LOGD("success end operate one request : " + request); } } } catch (Exception e) { e.printStackTrace(); if (DEBUG) { CommonUtilsConfig.LOGD("Exception : ", e); CommonUtilsConfig.LOGD("exception end operate one request : " + request); CommonUtilsConfig.LOGD(e.getStackTrace().toString()); } if (request.getmStatus() != DownloadRequest.STATUS_CANCEL) { handleResponseByListener(DOWNLOAD_FAILED, request.mDownloadUrl, request, false); mFailedHandler.notifyAll(-1, -1, request); } else { handleResponseByListener(DOWNLOAD_FAILED, request.mDownloadUrl, request, true); } } removeRequest(request); } System.gc(); }
@Override public String onInputStreamReturn(String requestUrl, InputStream is) { // if (!UtilsRuntime.isSDCardReady()) { // UtilsConfig.LOGD("return because unmount the sdcard"); // return null; // } if (DEBUG) { CommonUtilsConfig.LOGD(""); CommonUtilsConfig.LOGD("//-------------------------------------------------"); CommonUtilsConfig.LOGD("||"); CommonUtilsConfig.LOGD("|| [[FileDownloader::onInputStreamReturn]] : "); CommonUtilsConfig.LOGD("|| try to download [[BIG]] file with url : " + requestUrl); CommonUtilsConfig.LOGD("||"); CommonUtilsConfig.LOGD("\\-------------------------------------------------"); CommonUtilsConfig.LOGD(""); } if (is != null) { String saveUrl = mDownloadFilenameCreateListener != null ? mDownloadFilenameCreateListener.onFilenameCreateWithDownloadUrl(requestUrl) : mDefaultDownloadFilenameCreateListener.onFilenameCreateWithDownloadUrl(requestUrl); File bigCacheFile = new File(INPUT_STREAM_CACHE_PATH); if (!bigCacheFile.exists() || !bigCacheFile.isDirectory()) { bigCacheFile.delete(); bigCacheFile.mkdirs(); } long curTime = 0; if (DEBUG) { CommonUtilsConfig.LOGD( "try to download from inputstream to local path = " + INPUT_STREAM_CACHE_PATH + saveUrl + " for orgin URL : " + requestUrl); curTime = System.currentTimeMillis(); } // download file int totalSize = 0; try { totalSize = is.available(); } catch (Exception e) { e.printStackTrace(); } long downloadSize = 0; String savePath = null; String targetPath = INPUT_STREAM_CACHE_PATH + saveUrl; byte[] buffer = new byte[4096 * 2]; File f = new File(targetPath); int len; OutputStream os = null; boolean isClosed = false; try { if (f.exists()) { downloadSize = f.length(); } os = new FileOutputStream(f, true); while ((len = is.read(buffer)) != -1) { os.write(buffer, 0, len); // add listener to Notify UI downloadSize += len; handleProcess(requestUrl, totalSize, (int) downloadSize); if (RUNTIME_CLOSE_SUPPORTED) { DownloadRequest r = findCacelRequest(requestUrl); if (r != null && r.mStatus == DownloadRequest.STATUS_CANCEL) { CommonUtilsConfig.LOGD("try to close is >>>>>>>>>>>>>>>>>>>>"); is.close(); isClosed = true; } } } savePath = targetPath; } catch (Exception ex) { ex.printStackTrace(); } finally { if (os != null) { try { os.close(); } catch (Exception e) { e.printStackTrace(); } } buffer = null; } // end download try { if (!isClosed) { is.close(); } } catch (Exception e) { e.printStackTrace(); } if (!isClosed && !TextUtils.isEmpty(savePath) && checkInputStreamDownloadFile(savePath)) { if (DEBUG) { long successTime = System.currentTimeMillis(); CommonUtilsConfig.LOGD( "[[onInputStreamReturn]] save Request url : " + saveUrl + " success ||||||| and the saved file size : " + FileUtil.convertStorage(new File(savePath).length()) + ", save cost time = " + (successTime - curTime) + "ms"); } return savePath; } else { // 遗留文件,用于下次的断点下载 if (DEBUG) { CommonUtilsConfig.LOGD( "===== failed to downlaod requestUrl : " + requestUrl + " beacuse the debug 断点 ====="); } return null; } } else { if (DEBUG) { CommonUtilsConfig.LOGD( "===== failed to downlaod requestUrl : " + requestUrl + " beacuse requestUrl is NULL ====="); } } return null; }
/** * 新提交的request会默认 * * @param request * @return */ public boolean postRequest(DownloadRequest request) { if (mRequestList == null || request == null || TextUtils.isEmpty(request.mDownloadUrl)) { return false; } if (DEBUG) { CommonUtilsConfig.LOGD_WITH_TIME( "<<<<< [[postRequest]] >>>>> ::::::::: " + request.toString()); } // 检查是否已经下载过此request对应的文件 String cachedFile = checkFromCache(request); if (!TextUtils.isEmpty(cachedFile)) { File file = new File(cachedFile); if (file.exists()) { DownloadResponse response = tryToHandleDownloadFile(cachedFile, request); if (response != null) { mSuccessHandler.notifyAll(-1, -1, response); handleProcess(request.mDownloadUrl, (int) file.length(), (int) file.length()); } return true; } } synchronized (mRequestList) { boolean contain = false; for (DownloadRequest r : mRequestList) { if (r.mUrlHashCode == request.mUrlHashCode) { contain = true; break; } } if (!contain) { // mRequestList.add(request); // 将最新添加的任务放在下载队列的最前面 if (mLastInFirstDownload) { mRequestList.add(0, request); } else { mRequestList.add(request); } if (DEBUG) { CommonUtilsConfig.LOGD( "postRequest, add request : " + request.toString() + " into download list"); } } bIsStop = false; ThreadPoolSnapShot tss = CustomThreadPool.getInstance() .getSpecialThreadSnapShot(FileDownloader.class.getSimpleName()); if (tss == null) { return false; } else { if (tss.taskCount < tss.ALLOWED_MAX_TAKS) { if (DEBUG) { CommonUtilsConfig.LOGD("entry into [[postRequest]] to start process "); } processWorks(); } } } if (DEBUG) { CommonUtilsConfig.LOGD_WITH_TIME( "<<<<< [[postRequest]] end synchronized (mRequestList) >>>>>"); } synchronized (objLock) { if (bIsWaiting) { bIsWaiting = false; if (DEBUG) { CommonUtilsConfig.LOGD("try to notify download process begin"); } objLock.notify(); } } if (DEBUG) { CommonUtilsConfig.LOGD_WITH_TIME("<<<<< [[postRequest]] end synchronized (objLock) >>>>>"); } return true; }