修复组合任务多次回调onStop注解的问题, 修复多次重复快速点击暂停、开始时,任务有可能重复下载的问题, 修复组合任务中没有等待中的只任务实体保存失败的问题

v3.6.6
laoyuyu 6 years ago
parent 0dbc515cd3
commit e6da5230e9
  1. 13
      Aria/src/main/java/com/arialyy/aria/core/command/normal/StartCmd.java
  2. 19
      Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java
  3. 18
      Aria/src/main/java/com/arialyy/aria/core/common/AbsThreadTask.java
  4. 2
      Aria/src/main/java/com/arialyy/aria/core/common/StateConstance.java
  5. 12
      Aria/src/main/java/com/arialyy/aria/core/common/http/HttpHeaderDelegate.java
  6. 2
      Aria/src/main/java/com/arialyy/aria/core/download/AbsGroupDelegate.java
  7. 7
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java
  8. 7
      Aria/src/main/java/com/arialyy/aria/core/download/HttpGroupDelegate.java
  9. 1
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java
  10. 4
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java
  11. 2
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpFileInfoThread.java
  12. 5
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java
  13. 22
      Aria/src/main/java/com/arialyy/aria/core/download/group/AbsGroupUtil.java
  14. 17
      Aria/src/main/java/com/arialyy/aria/core/download/group/DownloadGroupUtil.java
  15. 7
      Aria/src/main/java/com/arialyy/aria/core/download/group/ISubQueue.java
  16. 15
      Aria/src/main/java/com/arialyy/aria/core/download/group/SimpleSchedulers.java
  17. 34
      Aria/src/main/java/com/arialyy/aria/core/download/group/SimpleSubQueue.java
  18. 11
      Aria/src/main/java/com/arialyy/aria/core/download/group/SubDownloadLoader.java
  19. 1
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsTask.java
  20. 4
      Aria/src/main/java/com/arialyy/aria/core/manager/ThreadTaskManager.java
  21. 2
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java
  22. 11
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java
  23. 4
      DEV_LOG.md
  24. 57
      app/src/main/java/com/arialyy/simple/core/download/SingleTaskActivity.java
  25. 35
      app/src/main/java/com/arialyy/simple/core/download/group/DownloadGroupActivity.java

@ -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子任务失败次数大于等于配置的重试次数才能认为子任务停止
* 2stopNum + failNum + completeNum == subSize则认为组合任务停止
* 2stopNum + failNum + completeNum + cacheNum == subSize则认为组合任务停止
* 3failNum == 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,13 +93,16 @@ 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) {
if (needGetInfo) {
new Thread(new HttpFileInfoThread(mWrapper, new OnFileInfoCallback() {
@Override public void onComplete(String url, CompleteInfo info) {
@ -109,6 +114,10 @@ class SubDownloadLoader implements IUtil {
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:
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;
}
}

Loading…
Cancel
Save