修复组合任务多次回调onStop注解的问题, 修复多次重复快速点击暂停、开始时,任务有可能重复下载的问题, 修复组合任务中没有等待中的只任务实体保存失败的问题
This commit is contained in:
@@ -72,13 +72,16 @@ class StartCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
|
||||
int state = task.getState();
|
||||
if (mQueue.getCurrentExePoolNum() < maxTaskNum) {
|
||||
if (state == IEntity.STATE_STOP
|
||||
|| task.getState() == IEntity.STATE_FAIL
|
||||
|| task.getState() == IEntity.STATE_OTHER
|
||||
|| task.getState() == IEntity.STATE_PRE
|
||||
|| task.getState() == IEntity.STATE_POST_PRE
|
||||
|| task.getState() == IEntity.STATE_COMPLETE) {
|
||||
|| state == IEntity.STATE_FAIL
|
||||
|| state == IEntity.STATE_OTHER
|
||||
|| state == IEntity.STATE_PRE
|
||||
|| state == IEntity.STATE_POST_PRE
|
||||
|| state == IEntity.STATE_COMPLETE) {
|
||||
resumeTask();
|
||||
} else if (state == IEntity.STATE_RUNNING) {
|
||||
ALog.w(TAG, String.format("任务【%s】已经在运行", task.getTaskName()));
|
||||
} else {
|
||||
ALog.d(TAG, String.format("开始新任务, 任务状态:%s", state));
|
||||
startTask();
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.arialyy.aria.core.common;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Looper;
|
||||
import android.util.SparseArray;
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import com.arialyy.aria.core.download.BaseDListener;
|
||||
@@ -125,7 +124,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_WRAPPER ext
|
||||
if (mTask != null && mTask.size() != 0) {
|
||||
for (int i = 0; i < mTask.size(); i++) {
|
||||
AbsThreadTask task = mTask.get(i);
|
||||
if (task != null && !task.isRunning()) {
|
||||
if (task != null) {
|
||||
task.breakTask();
|
||||
}
|
||||
}
|
||||
@@ -144,7 +143,6 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_WRAPPER ext
|
||||
mConstance.resetState();
|
||||
ALog.d(TAG, "path: " + getFilePath());
|
||||
checkRecord();
|
||||
mConstance.isRunning = true;
|
||||
mConstance.TASK_RECORD = mRecord;
|
||||
if (!mTaskWrapper.isSupportBP() || mTaskWrapper.asHttp().isChunked()) {
|
||||
mTotalThreadNum = 1;
|
||||
@@ -183,7 +181,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_WRAPPER ext
|
||||
}
|
||||
|
||||
@Override public void run() {
|
||||
if (mConstance.isRunning) {
|
||||
if (isRunning()) {
|
||||
return;
|
||||
}
|
||||
startFlow();
|
||||
@@ -205,6 +203,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_WRAPPER ext
|
||||
* 启动进度获取定时器
|
||||
*/
|
||||
private synchronized void startTimer() {
|
||||
ALog.d(TAG, "启动定时器");
|
||||
mTimer = new ScheduledThreadPoolExecutor(1);
|
||||
mTimer.scheduleWithFixedDelay(new Runnable() {
|
||||
@Override public void run() {
|
||||
@@ -212,7 +211,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_WRAPPER ext
|
||||
|| mConstance.isStop()
|
||||
|| mConstance.isCancel()
|
||||
|| mConstance.isFail()
|
||||
|| !mConstance.isRunning) {
|
||||
|| !isRunning()) {
|
||||
closeTimer();
|
||||
} else if (mConstance.CURRENT_LOCATION >= 0) {
|
||||
mListener.onProgress(mConstance.CURRENT_LOCATION);
|
||||
@@ -252,7 +251,9 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_WRAPPER ext
|
||||
}
|
||||
|
||||
public synchronized boolean isRunning() {
|
||||
return mConstance.isRunning;
|
||||
boolean b = ThreadTaskManager.getInstance().taskIsRunning(mTaskWrapper.getKey());
|
||||
//ALog.d(TAG, "isRunning = " + b);
|
||||
return b;
|
||||
}
|
||||
|
||||
public synchronized void cancel() {
|
||||
@@ -260,7 +261,6 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_WRAPPER ext
|
||||
return;
|
||||
}
|
||||
closeTimer();
|
||||
mConstance.isRunning = false;
|
||||
mConstance.isCancel = true;
|
||||
new Thread(new Runnable() {
|
||||
@Override public void run() {
|
||||
@@ -281,7 +281,6 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_WRAPPER ext
|
||||
return;
|
||||
}
|
||||
closeTimer();
|
||||
mConstance.isRunning = false;
|
||||
mConstance.isStop = true;
|
||||
if (mConstance.isComplete()) return;
|
||||
new Thread(new Runnable() {
|
||||
@@ -302,7 +301,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_WRAPPER ext
|
||||
* 直接调用的时候会自动启动线程执行
|
||||
*/
|
||||
public synchronized void start() {
|
||||
if (mConstance.isRunning) {
|
||||
if (isRunning()) {
|
||||
return;
|
||||
}
|
||||
new Thread(this).start();
|
||||
@@ -541,7 +540,6 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_WRAPPER ext
|
||||
if (mConstance.isComplete()) {
|
||||
mRecord.deleteData();
|
||||
mListener.onComplete();
|
||||
mConstance.isRunning = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -628,6 +626,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_WRAPPER ext
|
||||
if (isNewTr) {
|
||||
mRecord.threadRecords.add(tr);
|
||||
}
|
||||
//ALog.d(TAG, String.format("创建任务线程:%s,线程总数:%s", i, mTotalThreadNum));
|
||||
AbsThreadTask task = createSingThreadTask(i, startL, endL, fileLength, tr);
|
||||
if (task == null) return;
|
||||
mTask.put(i, task);
|
||||
|
||||
@@ -196,24 +196,13 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_WRAPPER
|
||||
writeConfig(false, currentTemp);
|
||||
if (getState().isStop()) {
|
||||
ALog.i(TAG, String.format("任务【%s】已中断", getConfig().TEMP_FILE.getName()));
|
||||
getState().isRunning = false;
|
||||
}
|
||||
} else {
|
||||
ALog.i(TAG, String.format("任务【%s】已中断", getConfig().TEMP_FILE.getName()));
|
||||
getState().isRunning = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否在运行
|
||||
*
|
||||
* @return {@code true}正在运行
|
||||
*/
|
||||
public boolean isRunning() {
|
||||
return getState().isRunning;
|
||||
}
|
||||
|
||||
public boolean isInterrupted() {
|
||||
return Thread.currentThread().isInterrupted();
|
||||
}
|
||||
@@ -316,14 +305,14 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_WRAPPER
|
||||
String.format("任务【%s】thread__%s__停止【当前线程停止位置:%s】", getConfig().TEMP_FILE.getName(),
|
||||
getConfig().THREAD_ID, stopLocation));
|
||||
writeConfig(false, stopLocation);
|
||||
//ALog.d(TAG, String.format("stop_thread_num=%s; start_thread_num=%s; complete_thread_num=%s",
|
||||
// getState().STOP_NUM, getState().START_THREAD_NUM, getState().COMPLETE_THREAD_NUM));
|
||||
if (getState().isStop()) {
|
||||
ALog.i(TAG, String.format("任务【%s】已停止", getConfig().TEMP_FILE.getName()));
|
||||
getState().isRunning = false;
|
||||
mListener.onStop(getState().CURRENT_LOCATION);
|
||||
}
|
||||
} else {
|
||||
ALog.i(TAG, String.format("任务【%s】已停止", getConfig().TEMP_FILE.getName()));
|
||||
getState().isRunning = false;
|
||||
mListener.onStop(getState().CURRENT_LOCATION);
|
||||
}
|
||||
}
|
||||
@@ -371,12 +360,10 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_WRAPPER
|
||||
getConfig().TEMP_FILE.delete();
|
||||
}
|
||||
ALog.d(TAG, String.format("任务【%s】已取消", getConfig().TEMP_FILE.getName()));
|
||||
getState().isRunning = false;
|
||||
mListener.onCancel();
|
||||
}
|
||||
} else {
|
||||
ALog.d(TAG, String.format("任务【%s】已取消", getConfig().TEMP_FILE.getName()));
|
||||
getState().isRunning = false;
|
||||
mListener.onCancel();
|
||||
}
|
||||
}
|
||||
@@ -501,7 +488,6 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_WRAPPER
|
||||
private void handleFailState(boolean taskNeedReTry) {
|
||||
getState().FAIL_NUM++;
|
||||
if (getState().isFail()) {
|
||||
getState().isRunning = false;
|
||||
// 手动停止不进行fail回调
|
||||
if (!getState().isStop) {
|
||||
String errorMsg = String.format("任务【%s】执行失败", getConfig().TEMP_FILE.getName());
|
||||
|
||||
@@ -29,7 +29,6 @@ public class StateConstance {
|
||||
public int COMPLETE_THREAD_NUM = 0;
|
||||
public int START_THREAD_NUM; //启动的线程数
|
||||
public long CURRENT_LOCATION = 0; //当前下载进度
|
||||
public boolean isRunning = false;
|
||||
public boolean isCancel = false;
|
||||
public boolean isStop = false;
|
||||
public TaskRecord TASK_RECORD;
|
||||
@@ -40,7 +39,6 @@ public class StateConstance {
|
||||
public void resetState() {
|
||||
isCancel = false;
|
||||
isStop = false;
|
||||
isRunning = false;
|
||||
CANCEL_NUM = 0;
|
||||
STOP_NUM = 0;
|
||||
FAIL_NUM = 0;
|
||||
|
||||
@@ -94,12 +94,12 @@ public class HttpHeaderDelegate<TARGET extends AbsTarget>
|
||||
if (adapter == null) {
|
||||
throw new IllegalArgumentException("adapter为空");
|
||||
}
|
||||
try {
|
||||
adapter.clone();
|
||||
mTarget.getTaskWrapper().asHttp().setFileLenAdapter((IHttpFileLenAdapter) adapter.clone());
|
||||
} catch (CloneNotSupportedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
//try {
|
||||
// adapter.clone();
|
||||
mTarget.getTaskWrapper().asHttp().setFileLenAdapter((IHttpFileLenAdapter) adapter);
|
||||
//} catch (CloneNotSupportedException e) {
|
||||
// e.printStackTrace();
|
||||
//}
|
||||
//// 以下代码有问题,匿名内部类不能序列化
|
||||
//String objPath = String.format("%s/obj_temp/%s", AriaManager.APP.getFilesDir().getPath(),
|
||||
// adapter.hashCode());
|
||||
|
||||
@@ -78,7 +78,7 @@ abstract class AbsGroupDelegate<TARGET extends AbsDGTarget> implements IGroupTar
|
||||
void reChangeDirPath(String newDirPath) {
|
||||
List<DTaskWrapper> subTasks = mWrapper.getSubTaskWrapper();
|
||||
if (subTasks != null && !subTasks.isEmpty()) {
|
||||
List<DbEntity> des = new ArrayList<>();
|
||||
List<DownloadEntity> des = new ArrayList<>();
|
||||
for (DTaskWrapper dte : subTasks) {
|
||||
DownloadEntity de = dte.getEntity();
|
||||
String oldPath = de.getDownloadPath();
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.support.annotation.NonNull;
|
||||
import com.arialyy.aria.core.common.http.GetDelegate;
|
||||
import com.arialyy.aria.core.common.http.HttpHeaderDelegate;
|
||||
import com.arialyy.aria.core.common.http.PostDelegate;
|
||||
import com.arialyy.aria.core.inf.AbsHttpFileLenAdapter;
|
||||
import com.arialyy.aria.core.inf.IHttpFileLenAdapter;
|
||||
import com.arialyy.aria.core.inf.IHttpHeaderDelegate;
|
||||
import java.net.Proxy;
|
||||
@@ -102,9 +103,9 @@ public class DownloadTarget extends AbsDTarget<DownloadTarget>
|
||||
/**
|
||||
* 如果你需要使用header中特定的key来设置文件长度,或有定制文件长度的需要,那么你可以通过该方法自行处理文件长度
|
||||
*/
|
||||
public DownloadTarget setFileLenAdapter(IHttpFileLenAdapter adapter) {
|
||||
//return mHeaderDelegate.setFileLenAdapter(adapter);
|
||||
return this;
|
||||
public DownloadTarget setFileLenAdapter(AbsHttpFileLenAdapter adapter) {
|
||||
return mHeaderDelegate.setFileLenAdapter(adapter);
|
||||
//return this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -125,7 +125,7 @@ class HttpGroupDelegate extends AbsGroupDelegate<DownloadGroupTarget> {
|
||||
}
|
||||
}
|
||||
|
||||
getEntity().save();
|
||||
saveEntity();
|
||||
|
||||
if (isNeedModifyPath()) {
|
||||
reChangeDirPath(getDirPathTemp());
|
||||
@@ -137,6 +137,11 @@ class HttpGroupDelegate extends AbsGroupDelegate<DownloadGroupTarget> {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void saveEntity(){
|
||||
getEntity().save();
|
||||
DbEntity.saveAll(getEntity().getSubEntities());
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新所有改动的子任务文件名
|
||||
*/
|
||||
|
||||
@@ -124,7 +124,6 @@ public class Downloader extends AbsFileer<DownloadEntity, DTaskWrapper> {
|
||||
|
||||
private void failDownload(BaseException e) {
|
||||
closeTimer();
|
||||
mConstance.isRunning = false;
|
||||
mListener.onFail(false, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,19 +142,15 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DTaskWrapper> {
|
||||
if (isBlock) {
|
||||
boolean success = mergeFile();
|
||||
if (!success) {
|
||||
//ALog.e(TAG, String.format("任务【%s】分块文件合并失败", getConfig().TEMP_FILE.getName()));
|
||||
getState().isRunning = false;
|
||||
mListener.onFail(false,
|
||||
new TaskException(TAG, String.format("任务【%s】分块文件合并失败", getConfig().TEMP_FILE.getName())));
|
||||
return;
|
||||
}
|
||||
}
|
||||
getState().TASK_RECORD.deleteData();
|
||||
getState().isRunning = false;
|
||||
mListener.onComplete();
|
||||
}
|
||||
if (getState().isFail()) {
|
||||
getState().isRunning = false;
|
||||
mListener.onFail(false,
|
||||
new TaskException(TAG, String.format("任务【%s】下载失败", getConfig().TEMP_FILE.getName())));
|
||||
}
|
||||
|
||||
@@ -214,6 +214,8 @@ public class HttpFileInfoThread implements Runnable {
|
||||
onFileInfoCallback.onComplete(mEntity.getUrl(), info);
|
||||
}
|
||||
mEntity.update();
|
||||
// 销毁文件长度适配器
|
||||
mTaskWrapper.asHttp().setFileLenAdapter(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -279,7 +279,6 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DTaskWrapper> {
|
||||
}
|
||||
if (getTaskWrapper().asHttp().isChunked()) {
|
||||
ALog.i(TAG, "任务下载完成");
|
||||
getState().isRunning = false;
|
||||
mListener.onComplete();
|
||||
return;
|
||||
}
|
||||
@@ -296,18 +295,15 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DTaskWrapper> {
|
||||
if (isBlock) {
|
||||
boolean success = mergeFile();
|
||||
if (!success) {
|
||||
getState().isRunning = false;
|
||||
mListener.onFail(false, new TaskException(TAG,
|
||||
String.format("任务【%s】分块文件合并失败", getConfig().TEMP_FILE.getName())));
|
||||
return;
|
||||
}
|
||||
}
|
||||
getState().TASK_RECORD.deleteData();
|
||||
getState().isRunning = false;
|
||||
mListener.onComplete();
|
||||
}
|
||||
if (getState().isFail()) {
|
||||
getState().isRunning = false;
|
||||
mListener.onFail(false,
|
||||
new TaskException(TAG,
|
||||
String.format("任务【%s】下载失败,filePath: %s, url: %s", getConfig().TEMP_FILE.getName(),
|
||||
@@ -315,7 +311,6 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DTaskWrapper> {
|
||||
}
|
||||
} else {
|
||||
ALog.i(TAG, "任务下载完成");
|
||||
getState().isRunning = false;
|
||||
mListener.onComplete();
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -192,22 +192,20 @@ public abstract class AbsGroupUtil implements IUtil, Runnable {
|
||||
@Override public void stop() {
|
||||
isStop = true;
|
||||
closeTimer();
|
||||
onStop();
|
||||
|
||||
Set<String> keys = mExeLoader.keySet();
|
||||
mSubQueue.clear();
|
||||
|
||||
for (String key : keys) {
|
||||
SubDownloadLoader loader = mExeLoader.get(key);
|
||||
if (loader != null && loader.isRunning()) {
|
||||
mSubQueue.stopTask(loader);
|
||||
}
|
||||
if (onStop()) {
|
||||
return;
|
||||
}
|
||||
mListener.onStop(mCurrentLocation);
|
||||
mSubQueue.stopAllTask();
|
||||
}
|
||||
|
||||
protected void onStop() {
|
||||
/**
|
||||
* 子类的钩子
|
||||
*
|
||||
* @return 返回{@code true},直接回调{@link IDownloadGroupListener#onStop(long)}
|
||||
*/
|
||||
protected boolean onStop() {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public void start() {
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.arialyy.aria.core.inf.IEntity;
|
||||
import com.arialyy.aria.exception.AriaIOException;
|
||||
import com.arialyy.aria.exception.BaseException;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@@ -38,6 +39,7 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
|
||||
private static final String TAG = "DownloadGroupUtil";
|
||||
private final Object LOCK = new Object();
|
||||
private ExecutorService mPool = null;
|
||||
private boolean getLenComplete = false;
|
||||
|
||||
public DownloadGroupUtil(IDownloadGroupListener listener, DGTaskWrapper taskWrapper) {
|
||||
super(listener, taskWrapper);
|
||||
@@ -51,8 +53,15 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
|
||||
super.onCancel();
|
||||
}
|
||||
|
||||
@Override protected void onStop() {
|
||||
super.onStop();
|
||||
@Override protected boolean onStop() {
|
||||
// 如果是isUnknownSize()标志,并且获取大小没有完成,则直接回调onStop
|
||||
if (mPool != null && !getLenComplete) {
|
||||
ALog.d(TAG, "获取长度未完成的情况下,停止组合任务");
|
||||
mPool.shutdown();
|
||||
mListener.onStop(0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override protected void onStart() {
|
||||
@@ -121,8 +130,12 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
|
||||
for (DTaskWrapper wrapper : mGTWrapper.getSubTaskWrapper()) {
|
||||
size += wrapper.getEntity().getFileSize();
|
||||
}
|
||||
mGTWrapper.getEntity().setConvertFileSize(CommonUtil.formatFileSize(size));
|
||||
mGTWrapper.getEntity().setFileSize(size);
|
||||
mGTWrapper.getEntity().update();
|
||||
mGTWrapper.asHttp().setFileLenAdapter(null);
|
||||
getLenComplete = true;
|
||||
ALog.d(TAG, String.format("获取组合任务长度完成,len:%s", size));
|
||||
} else if (failCount == mGTWrapper.getSubTaskWrapper().size()) {
|
||||
mListener.onFail(true, new AriaIOException(TAG, "获取子任务长度失败"));
|
||||
}
|
||||
|
||||
@@ -41,10 +41,15 @@ interface ISubQueue<Fileer extends IUtil> {
|
||||
void startTask(Fileer fileer);
|
||||
|
||||
/**
|
||||
* 停止任务
|
||||
* 停止单个任务,如果缓存队列中有等待中的任务,则启动等待中的任务
|
||||
*/
|
||||
void stopTask(Fileer fileer);
|
||||
|
||||
/**
|
||||
* 停止全部任务,停止所有正在执行的任务,并清空所有等待中的端服务
|
||||
*/
|
||||
void stopAllTask();
|
||||
|
||||
/**
|
||||
* 修改最大任务数
|
||||
*
|
||||
|
||||
@@ -41,7 +41,7 @@ class SimpleSchedulers implements ISchedulers {
|
||||
mGState = state;
|
||||
}
|
||||
|
||||
public static SimpleSchedulers newInstance(GroupRunState state) {
|
||||
static SimpleSchedulers newInstance(GroupRunState state) {
|
||||
|
||||
return new SimpleSchedulers(state);
|
||||
}
|
||||
@@ -75,7 +75,7 @@ class SimpleSchedulers implements ISchedulers {
|
||||
/**
|
||||
* 处理子任务失败的情况
|
||||
* 1、子任务失败次数大于等于配置的重试次数,才能认为子任务停止
|
||||
* 2、stopNum + failNum + completeNum == subSize,则认为组合任务停止
|
||||
* 2、stopNum + failNum + completeNum + cacheNum == subSize,则认为组合任务停止
|
||||
* 3、failNum == subSize,只有全部的子任务都失败了,才能任务组合任务失败
|
||||
*/
|
||||
private synchronized void handleFail(final SubDownloadLoader loader) {
|
||||
@@ -96,6 +96,7 @@ class SimpleSchedulers implements ISchedulers {
|
||||
if (mGState.getFailNum() == mGState.getSubSize()
|
||||
|| mGState.getStopNum() + mGState.getFailNum() + mGState.getCompleteNum()
|
||||
== mGState.getSubSize()) {
|
||||
mQueue.clear();
|
||||
mGState.isRunning = false;
|
||||
mGState.listener.onFail(true, new TaskException(TAG,
|
||||
String.format("任务组【%s】下载失败", mGState.getGroupHash())));
|
||||
@@ -128,8 +129,12 @@ class SimpleSchedulers implements ISchedulers {
|
||||
mGState.listener.onSubStop(loader.getEntity());
|
||||
mGState.countStopNum(loader.getKey());
|
||||
if (mGState.getStopNum() == mGState.getSubSize()
|
||||
|| mGState.getStopNum() + mGState.getCompleteNum() + mGState.getFailNum()
|
||||
|| mGState.getStopNum()
|
||||
+ mGState.getCompleteNum()
|
||||
+ mGState.getFailNum()
|
||||
+ mQueue.getCacheSize()
|
||||
== mGState.getSubSize()) {
|
||||
mQueue.clear();
|
||||
mGState.isRunning = false;
|
||||
mGState.listener.onStop(mGState.getProgress());
|
||||
} else {
|
||||
@@ -158,6 +163,7 @@ class SimpleSchedulers implements ISchedulers {
|
||||
} else {
|
||||
mGState.listener.onStop(mGState.getProgress());
|
||||
}
|
||||
mQueue.clear();
|
||||
mGState.isRunning = false;
|
||||
} else {
|
||||
startNext();
|
||||
@@ -168,6 +174,9 @@ class SimpleSchedulers implements ISchedulers {
|
||||
* 如果有等待中的任务,则启动下一任务
|
||||
*/
|
||||
private void startNext() {
|
||||
if (mQueue.isStopAll()) {
|
||||
return;
|
||||
}
|
||||
SubDownloadLoader next = mQueue.getNextTask();
|
||||
if (next != null) {
|
||||
ALog.d(TAG, String.format("启动任务:%s", next.getEntity().getFileName()));
|
||||
|
||||
@@ -44,6 +44,11 @@ class SimpleSubQueue implements ISubQueue<SubDownloadLoader> {
|
||||
*/
|
||||
private int mExecSize;
|
||||
|
||||
/**
|
||||
* 是否停止任务任务
|
||||
*/
|
||||
private boolean isStopAll = false;
|
||||
|
||||
private SimpleSubQueue() {
|
||||
mExecSize = Configuration.getInstance().dGroupCfg.getSubMaxTaskNum();
|
||||
}
|
||||
@@ -52,10 +57,21 @@ class SimpleSubQueue implements ISubQueue<SubDownloadLoader> {
|
||||
return new SimpleSubQueue();
|
||||
}
|
||||
|
||||
public Map<String, SubDownloadLoader> getExec() {
|
||||
Map<String, SubDownloadLoader> getExec() {
|
||||
return mExec;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存队列大小
|
||||
*/
|
||||
int getCacheSize() {
|
||||
return mCache.size();
|
||||
}
|
||||
|
||||
boolean isStopAll() {
|
||||
return isStopAll;
|
||||
}
|
||||
|
||||
@Override public void addTask(SubDownloadLoader fileer) {
|
||||
mCache.put(fileer.getKey(), fileer);
|
||||
}
|
||||
@@ -64,6 +80,7 @@ class SimpleSubQueue implements ISubQueue<SubDownloadLoader> {
|
||||
if (mExec.size() < mExecSize) {
|
||||
mCache.remove(fileer.getKey());
|
||||
mExec.put(fileer.getKey(), fileer);
|
||||
ALog.d(TAG, String.format("开始执行子任务:%s", fileer.getEntity().getFileName()));
|
||||
fileer.start();
|
||||
} else {
|
||||
ALog.d(TAG, String.format("执行队列已满,任务进入缓存器中,key: %s", fileer.getKey()));
|
||||
@@ -76,6 +93,19 @@ class SimpleSubQueue implements ISubQueue<SubDownloadLoader> {
|
||||
mExec.remove(fileer.getKey());
|
||||
}
|
||||
|
||||
@Override public void stopAllTask() {
|
||||
isStopAll = true;
|
||||
ALog.d(TAG, "停止组合任务");
|
||||
Set<String> keys = mExec.keySet();
|
||||
for (String key : keys) {
|
||||
SubDownloadLoader loader = mExec.get(key);
|
||||
if (loader != null) {
|
||||
ALog.d(TAG, String.format("停止子任务:%s", loader.getEntity().getFileName()));
|
||||
loader.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void modifyMaxExecNum(int num) {
|
||||
if (num < 1) {
|
||||
ALog.e(TAG, String.format("修改组合任务子任务队列数失败,num: %s", num));
|
||||
@@ -102,7 +132,7 @@ class SimpleSubQueue implements ISubQueue<SubDownloadLoader> {
|
||||
}
|
||||
Collection<SubDownloadLoader> temp = mCache.values();
|
||||
mCache.clear();
|
||||
ALog.d(TAG, String.format("测试, map size: %s", mCache.size()));
|
||||
ALog.d(TAG, String.format("测试, cacheSize: %s", mCache.size()));
|
||||
for (SubDownloadLoader cache : caches) {
|
||||
addTask(cache);
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ class SubDownloadLoader implements IUtil {
|
||||
private DTaskWrapper mWrapper;
|
||||
private Handler mSchedulers;
|
||||
private ChildDownloadListener mListener;
|
||||
private boolean needGetInfo;
|
||||
|
||||
/**
|
||||
* @param schedulers 调度器
|
||||
@@ -48,6 +49,7 @@ class SubDownloadLoader implements IUtil {
|
||||
SubDownloadLoader(Handler schedulers, DTaskWrapper taskWrapper, boolean needGetInfo) {
|
||||
mWrapper = taskWrapper;
|
||||
mSchedulers = schedulers;
|
||||
this.needGetInfo = needGetInfo;
|
||||
mListener = new ChildDownloadListener(mSchedulers, SubDownloadLoader.this);
|
||||
}
|
||||
|
||||
@@ -91,24 +93,31 @@ class SubDownloadLoader implements IUtil {
|
||||
}
|
||||
|
||||
@Override public void stop() {
|
||||
if (mDownloader != null) {
|
||||
if (mDownloader != null && isRunning()) {
|
||||
mDownloader.stop();
|
||||
} else {
|
||||
mSchedulers.obtainMessage(ISchedulers.STOP, this).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void start() {
|
||||
if (mWrapper.getRequestType() == AbsTaskWrapper.D_HTTP) {
|
||||
new Thread(new HttpFileInfoThread(mWrapper, new OnFileInfoCallback() {
|
||||
if (needGetInfo) {
|
||||
new Thread(new HttpFileInfoThread(mWrapper, new OnFileInfoCallback() {
|
||||
|
||||
@Override public void onComplete(String url, CompleteInfo info) {
|
||||
mDownloader = new Downloader(mListener, mWrapper);
|
||||
mDownloader.start();
|
||||
}
|
||||
@Override public void onComplete(String url, CompleteInfo info) {
|
||||
mDownloader = new Downloader(mListener, mWrapper);
|
||||
mDownloader.start();
|
||||
}
|
||||
|
||||
@Override public void onFail(AbsEntity entity, BaseException e, boolean needRetry) {
|
||||
mSchedulers.obtainMessage(ISchedulers.FAIL, SubDownloadLoader.this);
|
||||
}
|
||||
})).start();
|
||||
@Override public void onFail(AbsEntity entity, BaseException e, boolean needRetry) {
|
||||
mSchedulers.obtainMessage(ISchedulers.FAIL, SubDownloadLoader.this);
|
||||
}
|
||||
})).start();
|
||||
} else {
|
||||
mDownloader = new Downloader(mListener, mWrapper);
|
||||
mDownloader.start();
|
||||
}
|
||||
} else if (mWrapper.getRequestType() == AbsTaskWrapper.D_FTP) {
|
||||
mDownloader = new Downloader(mListener, mWrapper);
|
||||
mDownloader.start();
|
||||
|
||||
@@ -191,6 +191,7 @@ public abstract class AbsTask<ENTITY extends AbsEntity, TASK_WRAPPER extends Abs
|
||||
if (mUtil.isRunning()) {
|
||||
mUtil.stop();
|
||||
} else {
|
||||
ALog.d(TAG, "下载任务未执行");
|
||||
mListener.onStop(mEntity.getCurrentProgress());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,10 @@ public class ThreadTaskManager {
|
||||
temp.add(mExePool.submit(threadTask));
|
||||
}
|
||||
|
||||
public synchronized boolean taskIsRunning(String key){
|
||||
return mThreadTasks.get(getKey(key)) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止任务的所有线程
|
||||
*
|
||||
|
||||
@@ -97,11 +97,9 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UTaskWrapper> {
|
||||
getState().COMPLETE_THREAD_NUM++;
|
||||
if (getState().isComplete()) {
|
||||
getState().TASK_RECORD.deleteData();
|
||||
getState().isRunning = false;
|
||||
mListener.onComplete();
|
||||
}
|
||||
if (getState().isFail()) {
|
||||
getState().isRunning = false;
|
||||
mListener.onFail(false, new TaskException(TAG,
|
||||
String.format("上传失败,filePath: %s, uploadUrl: %s", getEntity().getFilePath(), getConfig().URL)));
|
||||
}
|
||||
|
||||
@@ -114,7 +114,6 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UTaskWrapper> {
|
||||
private void fail(BaseException e1) {
|
||||
try {
|
||||
mListener.onFail(true, e1);
|
||||
getState().isRunning = false;
|
||||
if (mOutputStream != null) {
|
||||
mOutputStream.close();
|
||||
}
|
||||
@@ -181,11 +180,11 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UTaskWrapper> {
|
||||
inputStream.close();
|
||||
writer.append(LINE_END);
|
||||
writer.flush();
|
||||
if (getState().isCancel) {
|
||||
getState().isRunning = false;
|
||||
return;
|
||||
}
|
||||
getState().isRunning = false;
|
||||
//if (getState().isCancel) {
|
||||
// getState().isRunning = false;
|
||||
// return;
|
||||
//}
|
||||
//getState().isRunning = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
- 组合任务新增`unknownSize()`,用于处理组合任务大小未知的情况,https://github.com/AriaLyy/Aria/issues/380
|
||||
- 优化`AbsThreadTask`代码
|
||||
- 新增文件长度处理功能 https://github.com/AriaLyy/Aria/issues/393
|
||||
- 修复组合任务多次回调`onStop`注解的问题
|
||||
- 优化`isRunning()`的逻辑,任务是否在执行的判断将更加准确
|
||||
- 修复多次重复快速点击`暂停、开始`时,任务有可能重复下载的问题
|
||||
- 修复组合任务中没有等待中的只任务实体保存失败的问题
|
||||
+ v_3.6.3 (2019/4/2)
|
||||
- fix bug https://github.com/AriaLyy/Aria/issues/377
|
||||
+ v_3.6.2 (2019/4/1)
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.arialyy.simple.core.download;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
@@ -36,6 +37,7 @@ import com.arialyy.aria.core.download.DTaskWrapper;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.DownloadTarget;
|
||||
import com.arialyy.aria.core.download.DownloadTask;
|
||||
import com.arialyy.aria.core.inf.AbsHttpFileLenAdapter;
|
||||
import com.arialyy.aria.core.inf.IEntity;
|
||||
import com.arialyy.aria.core.inf.IHttpFileLenAdapter;
|
||||
import com.arialyy.aria.core.scheduler.ISchedulers;
|
||||
@@ -47,6 +49,10 @@ import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.ActivitySingleBinding;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
|
||||
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
|
||||
import com.bumptech.glide.load.resource.transcode.BitmapBytesTranscoder;
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -72,6 +78,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
Button mStop;
|
||||
Button mCancel;
|
||||
RadioGroup mRg;
|
||||
DownloadTarget target;
|
||||
|
||||
BroadcastReceiver receiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
@@ -106,28 +113,20 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
mStop = findViewById(R.id.stop);
|
||||
mCancel = findViewById(R.id.cancel);
|
||||
mRg = findViewById(R.id.speeds);
|
||||
mStop.setVisibility(View.GONE);
|
||||
setTitle("单任务下载");
|
||||
Aria.download(this).register();
|
||||
DownloadTarget target = Aria.download(this).load(DOWNLOAD_URL);
|
||||
target = Aria.download(this).load(DOWNLOAD_URL);
|
||||
getBinding().setProgress(target.getPercent());
|
||||
if (target.getTaskState() == IEntity.STATE_STOP) {
|
||||
mStart.setText("恢复");
|
||||
mStart.setTextColor(getResources().getColor(android.R.color.holo_blue_light));
|
||||
setBtState(true);
|
||||
//mStart.setTextColor(getResources().getColor(android.R.color.holo_blue_light));
|
||||
} else if (target.isRunning()) {
|
||||
setBtState(false);
|
||||
mStart.setText("停止");
|
||||
}
|
||||
getBinding().setFileSize(target.getConvertFileSize());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置start 和 stop 按钮状态
|
||||
*/
|
||||
private void setBtState(boolean state) {
|
||||
//mStart.setEnabled(state);
|
||||
//mStop.setEnabled(!state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_single_task_activity, menu);
|
||||
@@ -180,7 +179,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
@Download.onPre
|
||||
protected void onPre(DownloadTask task) {
|
||||
if (task.getKey().equals(DOWNLOAD_URL)) {
|
||||
setBtState(false);
|
||||
mStart.setText("停止");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,7 +192,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
|
||||
@Download.onTaskRunning
|
||||
protected void running(DownloadTask task) {
|
||||
ALog.d(TAG, String.format("%s_running_%s", getClass().getName(), hashCode()));
|
||||
//ALog.d(TAG, String.format("%s_running_%s", getClass().getName(), hashCode()));
|
||||
//if (task.getKey().equals(DOWNLOAD_URL)) {
|
||||
//Log.d(TAG, task.getKey());
|
||||
long len = task.getFileSize();
|
||||
@@ -209,8 +208,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
@Download.onTaskResume
|
||||
void taskResume(DownloadTask task) {
|
||||
if (task.getKey().equals(DOWNLOAD_URL)) {
|
||||
mStart.setText("暂停");
|
||||
setBtState(false);
|
||||
mStart.setText("停止");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +216,6 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
void taskStop(DownloadTask task) {
|
||||
if (task.getKey().equals(DOWNLOAD_URL)) {
|
||||
mStart.setText("恢复");
|
||||
setBtState(true);
|
||||
getBinding().setSpeed("");
|
||||
}
|
||||
}
|
||||
@@ -229,7 +226,6 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
getBinding().setProgress(0);
|
||||
Toast.makeText(SingleTaskActivity.this, "取消下载", Toast.LENGTH_SHORT).show();
|
||||
mStart.setText("开始");
|
||||
setBtState(true);
|
||||
getBinding().setSpeed("");
|
||||
Log.d(TAG, "cancel");
|
||||
}
|
||||
@@ -242,24 +238,27 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
void taskFail(DownloadTask task, Exception e) {
|
||||
if (task.getKey().equals(DOWNLOAD_URL)) {
|
||||
Toast.makeText(SingleTaskActivity.this, "下载失败", Toast.LENGTH_SHORT).show();
|
||||
setBtState(true);
|
||||
//Aria.download(this)
|
||||
// .load(DOWNLOAD_URL)
|
||||
// .updateUrl("http://120.55.95.61:8811/ghcg/zg/武义总规纲要成果.zip")
|
||||
// .start();
|
||||
//DOWNLOAD_URL = "http://120.55.95.61:8811/ghcg/zg/武义总规纲要成果.zip";
|
||||
//ALog.d(TAG, ALog.getExceptionString(e));
|
||||
mStart.setText("开始");
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskComplete
|
||||
void taskComplete(DownloadTask task) {
|
||||
//Glide.with(this).load("").asBitmap().transform(new BitmapTransformation() {
|
||||
// @Override
|
||||
// protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// @Override public String getId() {
|
||||
// return null;
|
||||
// }
|
||||
//})
|
||||
//if (task.getKey().equals(DOWNLOAD_URL)) {
|
||||
getBinding().setProgress(100);
|
||||
Toast.makeText(SingleTaskActivity.this, "下载完成", Toast.LENGTH_SHORT).show();
|
||||
mStart.setText("重新开始?");
|
||||
//mCancel.setEnabled(false);
|
||||
setBtState(true);
|
||||
getBinding().setSpeed("");
|
||||
L.d(TAG, "path = " + task.getDownloadEntity().getDownloadPath());
|
||||
L.d(TAG, "md5Code = " + CommonUtil.getFileMD5(new File(task.getDownloadPath())));
|
||||
@@ -290,7 +289,11 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.start:
|
||||
startD();
|
||||
if (target.isRunning()) {
|
||||
Aria.download(this).load(DOWNLOAD_URL).stop();
|
||||
} else {
|
||||
startD();
|
||||
}
|
||||
break;
|
||||
case R.id.stop:
|
||||
Aria.download(this).load(DOWNLOAD_URL).stop();
|
||||
@@ -314,7 +317,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
//.addHeader("Cookie", "BAIDUID=648E5FF020CC69E8DD6F492D1068AAA9:FG=1; BIDUPSID=648E5FF020CC69E8DD6F492D1068AAA9; PSTM=1519099573; BD_UPN=12314753; locale=zh; BDSVRTM=0")
|
||||
.useServerFileName(true)
|
||||
.setFilePath(path, true)
|
||||
.setFileLenAdapter(new IHttpFileLenAdapter() {
|
||||
.setFileLenAdapter(new AbsHttpFileLenAdapter() {
|
||||
@Override public long handleFileLen(Map<String, List<String>> headers) {
|
||||
|
||||
List<String> sLength = headers.get("Content-Length");
|
||||
|
||||
@@ -90,18 +90,18 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
|
||||
//.setSubFileName(getModule(GroupModule.class).getSubName2())
|
||||
.setSubFileName(getModule(GroupModule.class).getSubName())
|
||||
.unknownSize()
|
||||
.setFileLenAdapter(new AbsHttpFileLenAdapter() {
|
||||
@Override public long handleFileLen(Map<String, List<String>> headers) {
|
||||
|
||||
List<String> sLength = headers.get("Content-Length");
|
||||
if (sLength == null || sLength.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
String temp = sLength.get(0);
|
||||
|
||||
return Long.parseLong(temp);
|
||||
}
|
||||
})
|
||||
//.setFileLenAdapter(new AbsHttpFileLenAdapter() {
|
||||
// @Override public long handleFileLen(Map<String, List<String>> headers) {
|
||||
//
|
||||
// List<String> sLength = headers.get("Content-Length");
|
||||
// if (sLength == null || sLength.isEmpty()) {
|
||||
// return -1;
|
||||
// }
|
||||
// String temp = sLength.get(0);
|
||||
//
|
||||
// return Long.parseLong(temp);
|
||||
// }
|
||||
//})
|
||||
//.setFileSize(114981416)
|
||||
//.updateUrls(temp)
|
||||
.start();
|
||||
@@ -111,17 +111,6 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
|
||||
break;
|
||||
case R.id.cancel:
|
||||
Aria.download(this).loadGroup(mUrls).cancel(true);
|
||||
//Aria.download(this).removeAllTask(true);
|
||||
//mUrls = getModule(GroupModule.class).getUrls1();
|
||||
//Aria.download(this)
|
||||
// .load(mUrls)
|
||||
// .setDownloadDirPath(
|
||||
// Environment.getExternalStorageDirectory().getPath() + "/Download/group_test_3")
|
||||
// .setGroupAlias("任务组测试")
|
||||
// .resetState()
|
||||
// .setSubFileName(getModule(GroupModule.class).getSubName())
|
||||
// //.setFileSize(32895492)
|
||||
// .start();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user