diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java b/Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java index 33f8cf56..a52fd494 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java @@ -391,16 +391,20 @@ public abstract class AbsFileer tr.startLocation) { ALog.i(TAG, String.format("修正分块【%s】的进度记录为:%s", temp.getPath(), realLocation)); tr.startLocation = realLocation; - } else if (realLocation > tr.endLocation) { + } else { ALog.i(TAG, String.format("分块【%s】错误,将重新开始该分块", temp.getPath())); temp.delete(); tr.startLocation = i * blockLen; @@ -415,7 +419,7 @@ public abstract class AbsFileer threads = new HashSet<>(); mRecord.fileLength = fileLength; - for (int i = 0; i < mTotalThreadNum; i++) { - threadId[i] = -1; - } if (mTaskEntity.isNewTask() && !handleNewTask()) { return; } @@ -572,7 +572,7 @@ public abstract class AbsFileer recordL) { if (isBreak()) { return; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/AbsThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/common/AbsThreadTask.java index 0214c09d..fbbaaa92 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/AbsThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/AbsThreadTask.java @@ -49,7 +49,7 @@ public abstract class AbsThreadTask mEntity.getFileSize()) { + ALog.e(TAG, String.format("任务【%s】分块文件合并失败,下载长度超出文件真实长度,downloadLen: %s,fileSize: %s", + mConfig.TEMP_FILE.getName(), targetFile.length(), mEntity.getFileSize())); + return false; + } return true; } else { return false; } } + /** + * 检查下载完成的分块大小,如果下载完成的分块大小大于或小于分配的大小,则需要重新下载该分块 + * 如果是非分块任务,直接返回{@code true} + * + * @return {@code true} 分块分大小正常,{@code false} 分块大小错误 + */ + protected boolean checkBlock() { + if (!getTaskRecord().isBlock) { + return true; + } + ThreadRecord tr = getThreadRecord(); + File blockFile = getBockFile(); + if (!blockFile.exists() || blockFile.length() != tr.blockLen) { + ALog.i(TAG, String.format("分块【%s】下载错误,即将重新下载该分块,开始位置:%s,结束位置:%s", blockFile.getName(), + tr.startLocation, tr.endLocation)); + retryThis(isBreak()); + return false; + } + return true; + } + /** * 停止任务 */ public void stop() { synchronized (AriaManager.LOCK) { if (mConfig.SUPPORT_BP) { - final long currentTemp = mChildCurrentLocation; + final long stopLocation; + if (getTaskRecord().isBlock) { + File blockFile = getBockFile(); + ThreadRecord tr = getThreadRecord(); + long block = mEntity.getFileSize() / getTaskRecord().threadRecords.size(); + stopLocation = + blockFile.exists() ? (tr.threadId * block + blockFile.length()) : tr.threadId * block; + } else { + stopLocation = mChildCurrentLocation; + } STATE.STOP_NUM++; - ALog.d(TAG, String.format("任务【%s】thread__%s__停止【停止位置:%s】", mConfig.TEMP_FILE.getName(), - mConfig.THREAD_ID, currentTemp)); - writeConfig(false, currentTemp); + ALog.d(TAG, String.format("任务【%s】thread__%s__停止【当前线程停止位置:%s】", mConfig.TEMP_FILE.getName(), + mConfig.THREAD_ID, stopLocation)); + writeConfig(false, stopLocation); if (STATE.isStop()) { ALog.i(TAG, String.format("任务【%s】已停止", mConfig.TEMP_FILE.getName())); STATE.isRunning = false; @@ -273,7 +309,8 @@ public abstract class AbsThreadTask mEntity.getFileSize()) { String errorMsg = - String.format("下载失败,下载长度超出文件大;currentLocation=%s, fileSize=%s", STATE.CURRENT_LOCATION, + String.format("下载失败,下载长度超出文件真实长度;currentLocation=%s, fileSize=%s", + STATE.CURRENT_LOCATION, mEntity.getFileSize()); taskBreak = true; fail(mChildCurrentLocation, new FileException(TAG, errorMsg), false); @@ -376,31 +413,42 @@ public abstract class AbsThreadTask tr.endLocation) { - ALog.i(TAG, String.format("分块【%s】错误,将重新下载该分块", file.getPath())); - boolean b = file.delete(); - ALog.w(TAG, "删除:" + b); + + File blockFile = getBockFile(); + if (blockFile.length() > tr.blockLen) { + ALog.i(TAG, String.format("分块【%s】错误,将重新下载该分块", blockFile.getPath())); + blockFile.delete(); tr.startLocation = block * tr.threadId; tr.isComplete = false; mConfig.START_LOCATION = tr.startLocation; - } else if (file.length() == tr.endLocation) { - STATE.COMPLETE_THREAD_NUM++; - tr.isComplete = true; - } else { - tr.startLocation = block * tr.threadId + file.length(); - mConfig.START_LOCATION = tr.startLocation; + } else if (blockFile.length() < tr.blockLen) { + tr.startLocation = block * tr.threadId + blockFile.length(); tr.isComplete = false; + mConfig.START_LOCATION = tr.startLocation; STATE.CURRENT_LOCATION = getBlockRealTotalSize(); - ALog.i(TAG, String.format("修正分块【%s】进度,开始位置:%s,当前进度:%s", file.getPath(), tr.startLocation, + ALog.i(TAG, String.format("修正分块【%s】,开始位置:%s,当前进度:%s", blockFile.getPath(), tr.startLocation, STATE.CURRENT_LOCATION)); + } else { + STATE.COMPLETE_THREAD_NUM++; + tr.isComplete = true; } + tr.update(); } else { mConfig.START_LOCATION = mChildCurrentLocation == 0 ? mConfig.START_LOCATION : mConfig.THREAD_RECORD.startLocation; } } + /** + * 获取分块文件 + * + * @return 分块文件 + */ + private File getBockFile() { + return new File(String.format(AbsFileer.SUB_PATH, STATE.TASK_RECORD.filePath, + getThreadRecord().threadId)); + } + /** * 获取分块任务真实的进度 * @@ -448,7 +496,9 @@ public abstract class AbsThreadTask if (isBreak()) { return; } + if (!checkBlock()) { + return; + } ALog.i(TAG, String.format("任务【%s】线程__%s__下载完毕", mConfig.TEMP_FILE.getName(), mConfig.THREAD_ID)); writeConfig(true, mConfig.END_LOCATION); diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java index 5ae61986..56fd1d08 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java @@ -247,6 +247,9 @@ final class HttpThreadTask extends AbsThreadTask implements ITaskQueue { + protected final int TYPE_D_QUEUE = 1; + protected final int TYPE_DG_QUEUE = 2; + protected final int TYPE_U_QUEUE = 3; + private final String TAG = "AbsTaskQueue"; BaseCachePool mCachePool; BaseExecutePool mExecutePool; AbsTaskQueue() { - mCachePool = setCachePool(); - mExecutePool = setExecutePool(); + switch (getQueueType()) { + case TYPE_D_QUEUE: + case TYPE_DG_QUEUE: + mCachePool = DownloadSharePool.getInstance().cachePool; + mExecutePool = DownloadSharePool.getInstance().executePool; + break; + case TYPE_U_QUEUE: + mCachePool = UploadSharePool.getInstance().cachePool; + mExecutePool = UploadSharePool.getInstance().executePool; + break; + } } - abstract BaseCachePool setCachePool(); - - abstract BaseExecutePool setExecutePool(); + abstract int getQueueType(); @Override public boolean taskIsRunning(String key) { return mExecutePool.getTask(key) != null; diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadGroupTaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadGroupTaskQueue.java index 094e10fd..e734c8da 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadGroupTaskQueue.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadGroupTaskQueue.java @@ -19,9 +19,6 @@ package com.arialyy.aria.core.queue; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.download.DownloadGroupTask; import com.arialyy.aria.core.download.DownloadGroupTaskEntity; -import com.arialyy.aria.core.queue.pool.BaseCachePool; -import com.arialyy.aria.core.queue.pool.BaseExecutePool; -import com.arialyy.aria.core.queue.pool.DownloadSharePool; import com.arialyy.aria.core.scheduler.DownloadGroupSchedulers; import com.arialyy.aria.util.ALog; @@ -47,12 +44,8 @@ public class DownloadGroupTaskQueue private DownloadGroupTaskQueue() { } - @Override BaseCachePool setCachePool() { - return DownloadSharePool.getInstance().cachePool; - } - - @Override BaseExecutePool setExecutePool() { - return DownloadSharePool.getInstance().executePool; + @Override int getQueueType() { + return TYPE_DG_QUEUE; } @Override public int getMaxTaskNum() { diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java index 01e6b2eb..98bc84e0 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java @@ -19,11 +19,7 @@ package com.arialyy.aria.core.queue; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.core.download.DownloadTaskEntity; -import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.TaskSchedulerType; -import com.arialyy.aria.core.queue.pool.BaseCachePool; -import com.arialyy.aria.core.queue.pool.BaseExecutePool; -import com.arialyy.aria.core.queue.pool.DownloadSharePool; import com.arialyy.aria.core.scheduler.DownloadSchedulers; import com.arialyy.aria.util.ALog; import java.util.LinkedHashSet; @@ -50,12 +46,8 @@ public class DownloadTaskQueue extends AbsTaskQueue setCachePool() { - return DownloadSharePool.getInstance().cachePool; - } - - @Override BaseExecutePool setExecutePool() { - return DownloadSharePool.getInstance().executePool; + @Override int getQueueType() { + return TYPE_D_QUEUE; } @Override public int getConfigMaxNum() { diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java index d235304d..d6190dc4 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java @@ -17,9 +17,6 @@ package com.arialyy.aria.core.queue; import com.arialyy.aria.core.AriaManager; -import com.arialyy.aria.core.queue.pool.BaseCachePool; -import com.arialyy.aria.core.queue.pool.BaseExecutePool; -import com.arialyy.aria.core.queue.pool.UploadSharePool; import com.arialyy.aria.core.scheduler.UploadSchedulers; import com.arialyy.aria.core.upload.UploadTask; import com.arialyy.aria.core.upload.UploadTaskEntity; @@ -45,12 +42,8 @@ public class UploadTaskQueue extends AbsTaskQueue private UploadTaskQueue() { } - @Override BaseCachePool setCachePool() { - return UploadSharePool.getInstance().cachePool; - } - - @Override BaseExecutePool setExecutePool() { - return UploadSharePool.getInstance().executePool; + @Override int getQueueType() { + return TYPE_U_QUEUE; } @Override public int getConfigMaxNum() { diff --git a/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java b/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java index cdebd34a..1a786860 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java @@ -75,6 +75,19 @@ import java.util.regex.Pattern; public class CommonUtil { private static final String TAG = "CommonUtil"; + /** + * 获取分块文件的快大小 + * + * @param fileLen 文件总长度 + * @param blockId 分块id + * @param blockNum 分块数量 + * @return 分块长度 + */ + public static long getBlockLen(long fileLen, int blockId, int blockNum) { + final long averageLen = fileLen / blockNum; + return blockId == blockNum - 1 ? (fileLen - blockId * averageLen) : averageLen; + } + /** * 检查SD内存空间是否充足 * @@ -945,7 +958,7 @@ public class CommonUtil { final File to = new File(file.getAbsolutePath() + System.currentTimeMillis()); if (file.renameTo(to)) { to.delete(); - }else { + } else { file.delete(); } } diff --git a/app/src/main/assets/aria_config.xml b/app/src/main/assets/aria_config.xml index 4e5da29d..aacfdc1b 100644 --- a/app/src/main/assets/aria_config.xml +++ b/app/src/main/assets/aria_config.xml @@ -35,7 +35,7 @@ 3、从3.4.1开始,如果线程数为1,文件初始化时将不再预占用对应长度的空间,下载多少byte,则占多大的空间; 对于采用多线程的任务或旧任务,依然采用原来的文件空间占用方式; --> - + diff --git a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java index deb06a53..22e8f14a 100644 --- a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java @@ -55,13 +55,12 @@ public class SingleTaskActivity extends BaseActivity { //"https://yizi-kejian.oss-cn-beijing.aliyuncs.com/qimeng/package1/qmtable11.zip"; //"http://rs.0.gaoshouyou.com/d/04/1e/400423a7551e1f3f0eb1812afa1f9b44.apk"; //"http://58.210.9.131/tpk/sipgt//TDLYZTGH.tpk"; //chunked 下载 - //"https://static.donguo.me//video/ip/course/pfys_1.mp4"; + "https://static.donguo.me//video/ip/course/pfys_1.mp4"; //"https://www.baidu.com/link?url=_LFCuTPtnzFxVJByJ504QymRywIA1Z_T5xUxe9ZLuxcGM0C_RcdpWyB1eGjbJC-e5wv5wAKM4WmLMAS5KeF6EZJHB8Va3YqZUiaErqK_pxm&wd=&eqid=e8583fe70002d126000000065a99f864"; //"https://d.pcs.baidu.com/file/a02c89a2d479d4fd2756f3313d42491d?fid=4232431903-250528-1114369760340736&dstime=1525491372&rt=sh&sign=FDtAERVY-DCb740ccc5511e5e8fedcff06b081203-3C13vkOkuk4TqXvVYW05zj1K0ao%3D&expires=8h&chkv=1&chkbd=0&chkpc=et&dp-logid=8651730921842106225&dp-callid=0&r=165533013"; //"http://apk500.bce.baidu-mgame.com/game/67000/67734/20170622040827_oem_5502845.apk?r=1"; //"https://dl.genymotion.com/releases/genymotion-2.12.1/genymotion-2.12.1-vbox.exe"; //"http://9.9.9.59:5000/download/CentOS-7-x86_64-Minimal-1804.iso"; - "https://firmwareapi.azurewebsites.net/firmware-overview?name=A19_Filament_W_IMG0038_00102411-encrypted.ota"; @Bind(R.id.start) Button mStart; @Bind(R.id.stop) Button mStop; @Bind(R.id.cancel) Button mCancel; @@ -197,11 +196,11 @@ public class SingleTaskActivity extends BaseActivity { L.d(TAG, "path ==> " + task.getDownloadEntity().getDownloadPath()); L.d(TAG, "md5Code ==> " + CommonUtil.getFileMD5(new File(task.getDownloadPath()))); L.d(TAG, "data ==> " + Aria.download(this).getDownloadEntity(DOWNLOAD_URL)); - Intent install = new Intent(Intent.ACTION_VIEW); - install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - File apkFile = new File(task.getDownloadPath()); - install.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive"); - startActivity(install); + //Intent install = new Intent(Intent.ACTION_VIEW); + //install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + //File apkFile = new File(task.getDownloadPath()); + //install.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive"); + //startActivity(install); } } @@ -261,7 +260,7 @@ public class SingleTaskActivity extends BaseActivity { Aria.download(SingleTaskActivity.this) .load(DOWNLOAD_URL) //.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8") - .addHeader("Accept-Encoding", "gzip, deflate") + //.addHeader("Accept-Encoding", "gzip, deflate") //.addHeader("DNT", "1") //.addHeader("Cookie", "BAIDUID=648E5FF020CC69E8DD6F492D1068AAA9:FG=1; BIDUPSID=648E5FF020CC69E8DD6F492D1068AAA9; PSTM=1519099573; BD_UPN=12314753; locale=zh; BDSVRTM=0") .useServerFileName(true) diff --git a/build.gradle b/build.gradle index b421632b..60f55e0e 100644 --- a/build.gradle +++ b/build.gradle @@ -39,7 +39,7 @@ task clean(type: Delete) { ext { userOrg = 'arialyy' groupId = 'com.arialyy.aria' - publishVersion = '3.5.2_dev_2' + publishVersion = '3.5.2_dev_3' // publishVersion = '1.0.4' //FTP插件 repoName='maven' desc = 'android 下载框架' diff --git a/gradle.properties b/gradle.properties index 2a4e2533..733bda13 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,6 +16,6 @@ #org.gradle.daemon=true #org.gradle.jvmargs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 # gradle proxy https://chaosleong.github.io/2017/02/10/Configuring-Gradle-Proxy/ -#systemProp.socksProxyHost=127.0.0.1 -#systemProp.socksProxyPort=1080 -#systemprop.socksProxyVersion=5 \ No newline at end of file +systemProp.socksProxyHost=127.0.0.1 +systemProp.socksProxyPort=1080 +systemprop.socksProxyVersion=5 \ No newline at end of file