|
|
@ -49,7 +49,7 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY |
|
|
|
|
|
|
|
|
|
|
|
private final String TAG = "AbsThreadTask"; |
|
|
|
private final String TAG = "AbsThreadTask"; |
|
|
|
/** |
|
|
|
/** |
|
|
|
* 当前子线程的下载位置 |
|
|
|
* 当前子线程相对于总长度的位置 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected long mChildCurrentLocation = 0; |
|
|
|
protected long mChildCurrentLocation = 0; |
|
|
|
protected int mBufSize; |
|
|
|
protected int mBufSize; |
|
|
@ -236,23 +236,59 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY |
|
|
|
f.delete(); |
|
|
|
f.delete(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
File targetFile = new File(STATE.TASK_RECORD.filePath); |
|
|
|
|
|
|
|
if (targetFile.exists() && targetFile.length() > mEntity.getFileSize()) { |
|
|
|
|
|
|
|
ALog.e(TAG, String.format("任务【%s】分块文件合并失败,下载长度超出文件真实长度,downloadLen: %s,fileSize: %s", |
|
|
|
|
|
|
|
mConfig.TEMP_FILE.getName(), targetFile.length(), mEntity.getFileSize())); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
return false; |
|
|
|
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() { |
|
|
|
public void stop() { |
|
|
|
synchronized (AriaManager.LOCK) { |
|
|
|
synchronized (AriaManager.LOCK) { |
|
|
|
if (mConfig.SUPPORT_BP) { |
|
|
|
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++; |
|
|
|
STATE.STOP_NUM++; |
|
|
|
ALog.d(TAG, String.format("任务【%s】thread__%s__停止【停止位置:%s】", mConfig.TEMP_FILE.getName(), |
|
|
|
ALog.d(TAG, String.format("任务【%s】thread__%s__停止【当前线程停止位置:%s】", mConfig.TEMP_FILE.getName(), |
|
|
|
mConfig.THREAD_ID, currentTemp)); |
|
|
|
mConfig.THREAD_ID, stopLocation)); |
|
|
|
writeConfig(false, currentTemp); |
|
|
|
writeConfig(false, stopLocation); |
|
|
|
if (STATE.isStop()) { |
|
|
|
if (STATE.isStop()) { |
|
|
|
ALog.i(TAG, String.format("任务【%s】已停止", mConfig.TEMP_FILE.getName())); |
|
|
|
ALog.i(TAG, String.format("任务【%s】已停止", mConfig.TEMP_FILE.getName())); |
|
|
|
STATE.isRunning = false; |
|
|
|
STATE.isRunning = false; |
|
|
@ -273,7 +309,8 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY |
|
|
|
synchronized (AriaManager.LOCK) { |
|
|
|
synchronized (AriaManager.LOCK) { |
|
|
|
if (STATE.CURRENT_LOCATION > mEntity.getFileSize()) { |
|
|
|
if (STATE.CURRENT_LOCATION > mEntity.getFileSize()) { |
|
|
|
String errorMsg = |
|
|
|
String errorMsg = |
|
|
|
String.format("下载失败,下载长度超出文件大;currentLocation=%s, fileSize=%s", STATE.CURRENT_LOCATION, |
|
|
|
String.format("下载失败,下载长度超出文件真实长度;currentLocation=%s, fileSize=%s", |
|
|
|
|
|
|
|
STATE.CURRENT_LOCATION, |
|
|
|
mEntity.getFileSize()); |
|
|
|
mEntity.getFileSize()); |
|
|
|
taskBreak = true; |
|
|
|
taskBreak = true; |
|
|
|
fail(mChildCurrentLocation, new FileException(TAG, errorMsg), false); |
|
|
|
fail(mChildCurrentLocation, new FileException(TAG, errorMsg), false); |
|
|
@ -376,31 +413,42 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY |
|
|
|
if (getTaskRecord().isBlock) { |
|
|
|
if (getTaskRecord().isBlock) { |
|
|
|
ThreadRecord tr = getThreadRecord(); |
|
|
|
ThreadRecord tr = getThreadRecord(); |
|
|
|
long block = mEntity.getFileSize() / getTaskRecord().threadRecords.size(); |
|
|
|
long block = mEntity.getFileSize() / getTaskRecord().threadRecords.size(); |
|
|
|
File file = mConfig.TEMP_FILE; |
|
|
|
|
|
|
|
if (file.length() > tr.endLocation) { |
|
|
|
File blockFile = getBockFile(); |
|
|
|
ALog.i(TAG, String.format("分块【%s】错误,将重新下载该分块", file.getPath())); |
|
|
|
if (blockFile.length() > tr.blockLen) { |
|
|
|
boolean b = file.delete(); |
|
|
|
ALog.i(TAG, String.format("分块【%s】错误,将重新下载该分块", blockFile.getPath())); |
|
|
|
ALog.w(TAG, "删除:" + b); |
|
|
|
blockFile.delete(); |
|
|
|
tr.startLocation = block * tr.threadId; |
|
|
|
tr.startLocation = block * tr.threadId; |
|
|
|
tr.isComplete = false; |
|
|
|
tr.isComplete = false; |
|
|
|
mConfig.START_LOCATION = tr.startLocation; |
|
|
|
mConfig.START_LOCATION = tr.startLocation; |
|
|
|
} else if (file.length() == tr.endLocation) { |
|
|
|
} else if (blockFile.length() < tr.blockLen) { |
|
|
|
STATE.COMPLETE_THREAD_NUM++; |
|
|
|
tr.startLocation = block * tr.threadId + blockFile.length(); |
|
|
|
tr.isComplete = true; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
tr.startLocation = block * tr.threadId + file.length(); |
|
|
|
|
|
|
|
mConfig.START_LOCATION = tr.startLocation; |
|
|
|
|
|
|
|
tr.isComplete = false; |
|
|
|
tr.isComplete = false; |
|
|
|
|
|
|
|
mConfig.START_LOCATION = tr.startLocation; |
|
|
|
STATE.CURRENT_LOCATION = getBlockRealTotalSize(); |
|
|
|
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)); |
|
|
|
STATE.CURRENT_LOCATION)); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
STATE.COMPLETE_THREAD_NUM++; |
|
|
|
|
|
|
|
tr.isComplete = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
tr.update(); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
mConfig.START_LOCATION = mChildCurrentLocation == 0 ? mConfig.START_LOCATION |
|
|
|
mConfig.START_LOCATION = mChildCurrentLocation == 0 ? mConfig.START_LOCATION |
|
|
|
: mConfig.THREAD_RECORD.startLocation; |
|
|
|
: 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<ENTITY extends AbsNormalEntity, TASK_ENTITY |
|
|
|
ThreadRecord tr = getThreadRecord(); |
|
|
|
ThreadRecord tr = getThreadRecord(); |
|
|
|
if (tr != null) { |
|
|
|
if (tr != null) { |
|
|
|
tr.isComplete = isComplete; |
|
|
|
tr.isComplete = isComplete; |
|
|
|
if (getTaskRecord().isBlock || getTaskRecord().isOpenDynamicFile) { |
|
|
|
if (getTaskRecord().isBlock) { |
|
|
|
|
|
|
|
tr.startLocation = record; |
|
|
|
|
|
|
|
} else if (getTaskRecord().isOpenDynamicFile) { |
|
|
|
tr.startLocation = mConfig.TEMP_FILE.length(); |
|
|
|
tr.startLocation = mConfig.TEMP_FILE.length(); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
if (0 < record && record < mConfig.END_LOCATION) { |
|
|
|
if (0 < record && record < mConfig.END_LOCATION) { |
|
|
|