|
|
@@ -22,11 +22,11 @@ import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
|
|
|
import com.arialyy.aria.core.download.DownloadTaskEntity;
|
|
|
import com.arialyy.aria.core.inf.IDownloadListener;
|
|
|
import com.arialyy.aria.core.inf.IEntity;
|
|
|
-import com.arialyy.aria.util.ALog;
|
|
|
+import com.arialyy.aria.orm.DbEntity;
|
|
|
import com.arialyy.aria.util.CommonUtil;
|
|
|
-import com.arialyy.aria.util.NetUtils;
|
|
|
import java.io.File;
|
|
|
import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Set;
|
|
|
import java.util.Timer;
|
|
|
@@ -38,27 +38,26 @@ import java.util.concurrent.Executors;
|
|
|
* Created by AriaL on 2017/6/30.
|
|
|
* 任务组核心逻辑
|
|
|
*/
|
|
|
-public abstract class AbsGroupUtil implements IUtil {
|
|
|
- private final String TAG = "AbsGroupUtil";
|
|
|
+abstract class AbsGroupUtil implements IUtil {
|
|
|
+ private final String TAG = "DownloadGroupUtil";
|
|
|
/**
|
|
|
- * FTP文件夹
|
|
|
+ * 任务组所有任务总大小
|
|
|
*/
|
|
|
- protected int FTP_DIR = 0xa1;
|
|
|
+ long mTotalSize = 0;
|
|
|
+ protected long mCurrentLocation = 0;
|
|
|
+ private ExecutorService mExePool;
|
|
|
+ protected IDownloadGroupListener mListener;
|
|
|
+ protected DownloadGroupTaskEntity mTaskEntity;
|
|
|
+ private boolean isRunning = true;
|
|
|
+ private Timer mTimer;
|
|
|
/**
|
|
|
- * HTTP 任务组
|
|
|
+ * 初始化完成的任务书数
|
|
|
*/
|
|
|
- protected int HTTP_GROUP = 0xa2;
|
|
|
-
|
|
|
+ int mInitNum = 0;
|
|
|
/**
|
|
|
- * 任务组所有任务总长度
|
|
|
+ * 初始化失败的任务数
|
|
|
*/
|
|
|
- long mTotalLen = 0;
|
|
|
- long mCurrentLocation = 0;
|
|
|
- private ExecutorService mExePool;
|
|
|
- protected IDownloadGroupListener mListener;
|
|
|
- protected DownloadGroupTaskEntity mGTEntity;
|
|
|
- private boolean isRunning = false;
|
|
|
- private Timer mTimer;
|
|
|
+ int mInitFailNum = 0;
|
|
|
/**
|
|
|
* 保存所有没有下载完成的任务,key为下载地址
|
|
|
*/
|
|
|
@@ -70,145 +69,49 @@ public abstract class AbsGroupUtil implements IUtil {
|
|
|
Map<String, DownloadTaskEntity> mFailMap = new HashMap<>();
|
|
|
|
|
|
/**
|
|
|
- * 该任务组对应的所有任务
|
|
|
- */
|
|
|
- private Map<String, DownloadTaskEntity> mTasksMap = new HashMap<>();
|
|
|
-
|
|
|
- /**
|
|
|
* 下载器映射表,key为下载地址
|
|
|
*/
|
|
|
private Map<String, Downloader> mDownloaderMap = new HashMap<>();
|
|
|
|
|
|
/**
|
|
|
- * 是否需要读取文件长度,{@code true}需要
|
|
|
+ * 该任务组对应的所有任务
|
|
|
*/
|
|
|
- boolean isNeedLoadFileSize = true;
|
|
|
+ private Map<String, DownloadTaskEntity> mTasksMap = new HashMap<>();
|
|
|
//已经完成的任务数
|
|
|
- int mCompleteNum = 0;
|
|
|
- //停止的任务数
|
|
|
- private int mStopNum = 0;
|
|
|
- //任务组大小
|
|
|
- int mGroupSize = 0;
|
|
|
- private long mUpdateInterval = 1000;
|
|
|
-
|
|
|
- AbsGroupUtil(IDownloadGroupListener listener, DownloadGroupTaskEntity groupEntity) {
|
|
|
+ private int mCompleteNum = 0;
|
|
|
+ //失败的任务数
|
|
|
+ private int mFailNum = 0;
|
|
|
+ //实际的下载任务数
|
|
|
+ int mActualTaskNum = 0;
|
|
|
+
|
|
|
+ AbsGroupUtil(IDownloadGroupListener listener, DownloadGroupTaskEntity taskEntity) {
|
|
|
mListener = listener;
|
|
|
- mGTEntity = groupEntity;
|
|
|
+ mTaskEntity = taskEntity;
|
|
|
mExePool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
|
|
- mUpdateInterval =
|
|
|
- AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getUpdateInterval();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取任务类型
|
|
|
- *
|
|
|
- * @return {@link #FTP_DIR}、{@link #HTTP_GROUP}
|
|
|
- */
|
|
|
- abstract int getTaskType();
|
|
|
-
|
|
|
- /**
|
|
|
- * 更新任务组文件大小
|
|
|
- */
|
|
|
- void updateFileSize() {
|
|
|
- if (isNeedLoadFileSize) {
|
|
|
- mGTEntity.getEntity().setFileSize(mTotalLen);
|
|
|
- mGTEntity.getEntity().update();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 启动子任务下载
|
|
|
- *
|
|
|
- * @param url 子任务下载地址
|
|
|
- */
|
|
|
- public void startSubTask(String url) {
|
|
|
- if (!checkSubTask(url, "开始")) return;
|
|
|
- if (!isRunning) {
|
|
|
- isRunning = true;
|
|
|
- startTimer();
|
|
|
- }
|
|
|
- Downloader d = getDownloader(url, false);
|
|
|
- if (d != null && !d.isRunning()) {
|
|
|
- d.setNewTask(false);
|
|
|
- d.start();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 停止子任务下载
|
|
|
- *
|
|
|
- * @param url 子任务下载地址
|
|
|
- */
|
|
|
- public void stopSubTask(String url) {
|
|
|
- if (!checkSubTask(url, "停止")) return;
|
|
|
- Downloader d = getDownloader(url, false);
|
|
|
- if (d != null && d.isRunning()) {
|
|
|
- d.stop();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 删除子任务
|
|
|
- *
|
|
|
- * @param url 子任务下载地址
|
|
|
- */
|
|
|
- public void cancelSubTask(String url) {
|
|
|
- Set<String> urls = mTasksMap.keySet();
|
|
|
- if (!urls.isEmpty() && urls.contains(url)) {
|
|
|
- DownloadTaskEntity det = mTasksMap.get(url);
|
|
|
- if (det != null) {
|
|
|
- mTotalLen -= det.getEntity().getFileSize();
|
|
|
- mGroupSize--;
|
|
|
- if (mGroupSize == 0) {
|
|
|
- closeTimer(false);
|
|
|
- mListener.onCancel();
|
|
|
- }
|
|
|
+ List<DownloadTaskEntity> tasks =
|
|
|
+ DbEntity.findDatas(DownloadTaskEntity.class, "groupName=?", mTaskEntity.key);
|
|
|
+ if (tasks != null && !tasks.isEmpty()) {
|
|
|
+ for (DownloadTaskEntity te : tasks) {
|
|
|
+ mTasksMap.put(te.getEntity().getUrl(), te);
|
|
|
}
|
|
|
- mGTEntity.update();
|
|
|
- }
|
|
|
- Downloader d = getDownloader(url, false);
|
|
|
- if (d != null) {
|
|
|
- d.cancel();
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 检查子任务
|
|
|
- *
|
|
|
- * @param url 子任务url
|
|
|
- * @param type 任务类型
|
|
|
- * @return {@code true} 任务可以下载
|
|
|
- */
|
|
|
- private boolean checkSubTask(String url, String type) {
|
|
|
- DownloadTaskEntity entity = mTasksMap.get(url);
|
|
|
- if (entity != null) {
|
|
|
- if (entity.getState() == IEntity.STATE_COMPLETE) {
|
|
|
- ALog.w(TAG, "任务【" + url + "】已完成," + type + "失败");
|
|
|
- return false;
|
|
|
+ for (DownloadEntity entity : mTaskEntity.entity.getSubTask()) {
|
|
|
+ File file = new File(entity.getDownloadPath());
|
|
|
+ if (entity.getState() == IEntity.STATE_COMPLETE && file.exists()) {
|
|
|
+ mCompleteNum++;
|
|
|
+ mInitNum++;
|
|
|
+ mCurrentLocation += entity.getFileSize();
|
|
|
+ } else {
|
|
|
+ mExeMap.put(entity.getUrl(), createChildDownloadTask(entity));
|
|
|
+ mCurrentLocation += entity.getCurrentProgress();
|
|
|
+ mActualTaskNum++;
|
|
|
}
|
|
|
- } else {
|
|
|
- ALog.w(TAG, "任务组中没有该任务【" + url + "】," + type + "失败");
|
|
|
- return false;
|
|
|
- }
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 通过地址获取下载器
|
|
|
- *
|
|
|
- * @param url 子任务下载地址
|
|
|
- * @param start 是否启动任务
|
|
|
- */
|
|
|
- private Downloader getDownloader(String url, boolean start) {
|
|
|
- Downloader d = mDownloaderMap.get(url);
|
|
|
- if (d == null) {
|
|
|
- return createChildDownload(mTasksMap.get(url), start);
|
|
|
+ mTotalSize += entity.getFileSize();
|
|
|
}
|
|
|
- return d;
|
|
|
}
|
|
|
|
|
|
@Override public long getFileSize() {
|
|
|
- return mTotalLen;
|
|
|
+ return mTotalSize;
|
|
|
}
|
|
|
|
|
|
@Override public long getCurrentLocation() {
|
|
|
@@ -221,6 +124,7 @@ public abstract class AbsGroupUtil implements IUtil {
|
|
|
|
|
|
@Override public void cancel() {
|
|
|
closeTimer(false);
|
|
|
+ mListener.onCancel();
|
|
|
onCancel();
|
|
|
if (!mExePool.isShutdown()) {
|
|
|
mExePool.shutdown();
|
|
|
@@ -233,16 +137,29 @@ public abstract class AbsGroupUtil implements IUtil {
|
|
|
dt.cancel();
|
|
|
}
|
|
|
}
|
|
|
- clearState();
|
|
|
- mListener.onCancel();
|
|
|
+ delDownloadInfo();
|
|
|
+ mTaskEntity.deleteData();
|
|
|
}
|
|
|
|
|
|
public void onCancel() {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 删除所有子任务的下载信息
|
|
|
+ */
|
|
|
+ private void delDownloadInfo() {
|
|
|
+ List<DownloadTaskEntity> tasks =
|
|
|
+ DbEntity.findDatas(DownloadTaskEntity.class, "groupName=?", mTaskEntity.key);
|
|
|
+ if (tasks == null || tasks.isEmpty()) return;
|
|
|
+ for (DownloadTaskEntity taskEntity : tasks) {
|
|
|
+ CommonUtil.delDownloadTaskConfig(taskEntity.removeFile, taskEntity);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
@Override public void stop() {
|
|
|
closeTimer(false);
|
|
|
+ mListener.onStop(mCurrentLocation);
|
|
|
onStop();
|
|
|
if (!mExePool.isShutdown()) {
|
|
|
mExePool.shutdown();
|
|
|
@@ -261,35 +178,10 @@ public abstract class AbsGroupUtil implements IUtil {
|
|
|
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 预处理操作,由于属性的不同,http任务组在构造函数中就可以完成了
|
|
|
- * 而FTP文件夹的,需要获取完成所有子任务信息才算预处理完成
|
|
|
- */
|
|
|
- protected void onPre() {
|
|
|
- mListener.onPre();
|
|
|
- mGroupSize = mGTEntity.getSubTaskEntities().size();
|
|
|
- mTotalLen = mGTEntity.getEntity().getFileSize();
|
|
|
- isNeedLoadFileSize = mTotalLen <= 1;
|
|
|
- for (DownloadTaskEntity te : mGTEntity.getSubTaskEntities()) {
|
|
|
- File file = new File(te.getKey());
|
|
|
- if (te.getState() == IEntity.STATE_COMPLETE && file.exists()) {
|
|
|
- mCompleteNum++;
|
|
|
- mCurrentLocation += te.getEntity().getFileSize();
|
|
|
- } else {
|
|
|
- mExeMap.put(te.getUrl(), te);
|
|
|
- mCurrentLocation += file.exists() ? te.getEntity().getCurrentProgress() : 0;
|
|
|
- }
|
|
|
- if (isNeedLoadFileSize) {
|
|
|
- mTotalLen += te.getEntity().getFileSize();
|
|
|
- }
|
|
|
- mTasksMap.put(te.getUrl(), te);
|
|
|
- }
|
|
|
- updateFileSize();
|
|
|
- }
|
|
|
-
|
|
|
@Override public void start() {
|
|
|
isRunning = true;
|
|
|
- clearState();
|
|
|
+ mFailNum = 0;
|
|
|
+ mListener.onPre();
|
|
|
onStart();
|
|
|
}
|
|
|
|
|
|
@@ -306,17 +198,11 @@ public abstract class AbsGroupUtil implements IUtil {
|
|
|
|
|
|
}
|
|
|
|
|
|
- private void clearState(){
|
|
|
- mDownloaderMap.clear();
|
|
|
- mFailMap.clear();
|
|
|
- }
|
|
|
-
|
|
|
private void closeTimer(boolean isRunning) {
|
|
|
this.isRunning = isRunning;
|
|
|
if (mTimer != null) {
|
|
|
mTimer.purge();
|
|
|
mTimer.cancel();
|
|
|
- mTimer = null;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -325,12 +211,8 @@ public abstract class AbsGroupUtil implements IUtil {
|
|
|
*/
|
|
|
void startRunningFlow() {
|
|
|
closeTimer(true);
|
|
|
- mListener.onPostPre(mTotalLen);
|
|
|
+ mListener.onPostPre(mTotalSize);
|
|
|
mListener.onStart(mCurrentLocation);
|
|
|
- startTimer();
|
|
|
- }
|
|
|
-
|
|
|
- private void startTimer() {
|
|
|
mTimer = new Timer(true);
|
|
|
mTimer.schedule(new TimerTask() {
|
|
|
@Override public void run() {
|
|
|
@@ -340,48 +222,66 @@ public abstract class AbsGroupUtil implements IUtil {
|
|
|
mListener.onProgress(mCurrentLocation);
|
|
|
}
|
|
|
}
|
|
|
- }, 0, mUpdateInterval);
|
|
|
+ }, 0, 1000);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 创建子任务下载器,默认创建完成自动启动
|
|
|
+ * 启动子任务下载器
|
|
|
*/
|
|
|
- Downloader createChildDownload(DownloadTaskEntity taskEntity) {
|
|
|
- return createChildDownload(taskEntity, true);
|
|
|
+ void startChildDownload(DownloadTaskEntity taskEntity) {
|
|
|
+ ChildDownloadListener listener = new ChildDownloadListener(taskEntity);
|
|
|
+ Downloader dt = new Downloader(listener, taskEntity);
|
|
|
+ mDownloaderMap.put(taskEntity.getEntity().getUrl(), dt);
|
|
|
+ if (mExePool.isShutdown()) return;
|
|
|
+ mExePool.execute(dt);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 创建子任务下载器,启动子任务下载器
|
|
|
- *
|
|
|
- * @param start 是否启动下载
|
|
|
+ * 创建子任务下载信息
|
|
|
*/
|
|
|
- private Downloader createChildDownload(DownloadTaskEntity taskEntity, boolean start) {
|
|
|
- ChildDownloadListener listener = new ChildDownloadListener(taskEntity);
|
|
|
- Downloader dt = new Downloader(listener, taskEntity);
|
|
|
- mDownloaderMap.put(taskEntity.getEntity().getUrl(), dt);
|
|
|
- if (mExePool.isShutdown()) return dt;
|
|
|
- if (start) {
|
|
|
- mExePool.execute(dt);
|
|
|
+ DownloadTaskEntity createChildDownloadTask(DownloadEntity entity) {
|
|
|
+ DownloadTaskEntity taskEntity = mTasksMap.get(entity.getUrl());
|
|
|
+ if (taskEntity != null) {
|
|
|
+ taskEntity.entity = entity;
|
|
|
+ //ftp登录的
|
|
|
+ taskEntity.userName = mTaskEntity.userName;
|
|
|
+ taskEntity.userPw = mTaskEntity.userPw;
|
|
|
+ taskEntity.account = mTaskEntity.account;
|
|
|
+ return taskEntity;
|
|
|
}
|
|
|
- return dt;
|
|
|
+ taskEntity = new DownloadTaskEntity();
|
|
|
+ taskEntity.entity = entity;
|
|
|
+ taskEntity.headers = mTaskEntity.headers;
|
|
|
+ taskEntity.requestEnum = mTaskEntity.requestEnum;
|
|
|
+ taskEntity.redirectUrlKey = mTaskEntity.redirectUrlKey;
|
|
|
+ taskEntity.removeFile = mTaskEntity.removeFile;
|
|
|
+ taskEntity.groupName = mTaskEntity.key;
|
|
|
+ taskEntity.isGroupTask = true;
|
|
|
+ taskEntity.requestType = mTaskEntity.requestType;
|
|
|
+ //ftp登录的
|
|
|
+ taskEntity.userName = mTaskEntity.userName;
|
|
|
+ taskEntity.userPw = mTaskEntity.userPw;
|
|
|
+ taskEntity.account = mTaskEntity.account;
|
|
|
+ taskEntity.key = entity.getDownloadPath();
|
|
|
+ taskEntity.save();
|
|
|
+ return taskEntity;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 子任务事件监听
|
|
|
*/
|
|
|
private class ChildDownloadListener implements IDownloadListener {
|
|
|
- private DownloadTaskEntity subTaskEntity;
|
|
|
- private DownloadEntity subEntity;
|
|
|
- private int RUN_SAVE_INTERVAL = 5 * 1000; //5s保存一次下载中的进度
|
|
|
- private long lastSaveTime;
|
|
|
- private long lastLen = 0;
|
|
|
+
|
|
|
+ DownloadTaskEntity taskEntity;
|
|
|
+ DownloadEntity entity;
|
|
|
+
|
|
|
+ long lastLen = 0;
|
|
|
|
|
|
ChildDownloadListener(DownloadTaskEntity entity) {
|
|
|
- subTaskEntity = entity;
|
|
|
- subEntity = subTaskEntity.getEntity();
|
|
|
- subEntity.setFailNum(0);
|
|
|
- lastLen = subEntity.getCurrentProgress();
|
|
|
- lastSaveTime = System.currentTimeMillis();
|
|
|
+ this.taskEntity = entity;
|
|
|
+ this.entity = taskEntity.getEntity();
|
|
|
+ lastLen = this.entity.getCurrentProgress();
|
|
|
+ this.entity.setFailNum(0);
|
|
|
}
|
|
|
|
|
|
@Override public void onPre() {
|
|
|
@@ -389,99 +289,77 @@ public abstract class AbsGroupUtil implements IUtil {
|
|
|
}
|
|
|
|
|
|
@Override public void onPostPre(long fileSize) {
|
|
|
- subEntity.setFileSize(fileSize);
|
|
|
- subEntity.setConvertFileSize(CommonUtil.formatFileSize(fileSize));
|
|
|
+ entity.setFileSize(fileSize);
|
|
|
+ entity.setConvertFileSize(CommonUtil.formatFileSize(fileSize));
|
|
|
saveData(IEntity.STATE_POST_PRE, -1);
|
|
|
- mListener.onSubPre(subEntity);
|
|
|
}
|
|
|
|
|
|
@Override public void onResume(long resumeLocation) {
|
|
|
saveData(IEntity.STATE_POST_PRE, IEntity.STATE_RUNNING);
|
|
|
lastLen = resumeLocation;
|
|
|
- mListener.onSubStart(subEntity);
|
|
|
}
|
|
|
|
|
|
@Override public void onStart(long startLocation) {
|
|
|
saveData(IEntity.STATE_POST_PRE, IEntity.STATE_RUNNING);
|
|
|
lastLen = startLocation;
|
|
|
- mListener.onSubStart(subEntity);
|
|
|
}
|
|
|
|
|
|
@Override public void onProgress(long currentLocation) {
|
|
|
long speed = currentLocation - lastLen;
|
|
|
mCurrentLocation += speed;
|
|
|
- subEntity.setCurrentProgress(currentLocation);
|
|
|
- handleSpeed(speed);
|
|
|
- mListener.onSubRunning(subEntity);
|
|
|
- if (System.currentTimeMillis() - lastSaveTime >= RUN_SAVE_INTERVAL) {
|
|
|
- saveData(IEntity.STATE_RUNNING, currentLocation);
|
|
|
- lastSaveTime = System.currentTimeMillis();
|
|
|
- }
|
|
|
lastLen = currentLocation;
|
|
|
+ entity.setCurrentProgress(currentLocation);
|
|
|
+ handleSpeed(speed);
|
|
|
}
|
|
|
|
|
|
@Override public void onStop(long stopLocation) {
|
|
|
saveData(IEntity.STATE_STOP, stopLocation);
|
|
|
handleSpeed(0);
|
|
|
- mListener.onSubStop(subEntity);
|
|
|
- synchronized (AbsGroupUtil.class) {
|
|
|
- mStopNum++;
|
|
|
- if (mStopNum + mCompleteNum + mFailMap.size() == mGroupSize) {
|
|
|
- closeTimer(false);
|
|
|
- mListener.onStop(mCurrentLocation);
|
|
|
- }
|
|
|
- }
|
|
|
+ mListener.onSubStop(entity);
|
|
|
}
|
|
|
|
|
|
@Override public void onCancel() {
|
|
|
saveData(IEntity.STATE_CANCEL, -1);
|
|
|
handleSpeed(0);
|
|
|
- mListener.onSubCancel(subEntity);
|
|
|
+ mListener.onSubCancel(entity);
|
|
|
}
|
|
|
|
|
|
@Override public void onComplete() {
|
|
|
- saveData(IEntity.STATE_COMPLETE, subEntity.getFileSize());
|
|
|
+ saveData(IEntity.STATE_COMPLETE, entity.getFileSize());
|
|
|
+ mCompleteNum++;
|
|
|
handleSpeed(0);
|
|
|
- mListener.onSubComplete(subEntity);
|
|
|
- synchronized (ChildDownloadListener.class) {
|
|
|
- mCompleteNum++;
|
|
|
- //如果子任务完成的数量和总任务数一致,表示任务组任务已经完成
|
|
|
- if (mCompleteNum >= mGroupSize) {
|
|
|
- closeTimer(false);
|
|
|
- mListener.onComplete();
|
|
|
- } else if (mFailMap.size() > 0 && mStopNum + mCompleteNum + mFailMap.size() >= mGroupSize) {
|
|
|
- //如果子任务完成数量加上失败的数量和总任务数一致,则任务组停止下载
|
|
|
- closeTimer(false);
|
|
|
- mListener.onStop(mCurrentLocation);
|
|
|
- }
|
|
|
+ mListener.onSubComplete(entity);
|
|
|
+ //如果子任务完成的数量和总任务数一致,表示任务组任务已经完成
|
|
|
+ if (mCompleteNum >= mTaskEntity.getEntity().getSubTask().size()) {
|
|
|
+ closeTimer(false);
|
|
|
+ mListener.onComplete();
|
|
|
+ } else if (mCompleteNum + mFailNum >= mActualTaskNum) {
|
|
|
+ //如果子任务完成数量加上失败的数量和总任务数一致,则任务组停止下载
|
|
|
+ closeTimer(false);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @Override public void onFail(boolean needRetry) {
|
|
|
- subEntity.setFailNum(subEntity.getFailNum() + 1);
|
|
|
+ @Override public void onFail() {
|
|
|
+ entity.setFailNum(entity.getFailNum() + 1);
|
|
|
saveData(IEntity.STATE_FAIL, lastLen);
|
|
|
handleSpeed(0);
|
|
|
- reTry(needRetry);
|
|
|
+ reTry();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 重试下载
|
|
|
+ * 失败后重试下载,如果失败次数超过5次,不再重试
|
|
|
*/
|
|
|
- private void reTry(boolean needRetry) {
|
|
|
- synchronized (ChildDownloadListener.class) {
|
|
|
- if (subEntity.getFailNum() < 5 && needRetry && NetUtils.isConnected(AriaManager.APP)) {
|
|
|
+ private void reTry() {
|
|
|
+ synchronized (AriaManager.LOCK) {
|
|
|
+ if (entity.getFailNum() < 5 && isRunning) {
|
|
|
reStartTask();
|
|
|
} else {
|
|
|
- mFailMap.put(subTaskEntity.getUrl(), subTaskEntity);
|
|
|
- mListener.onSubFail(subEntity);
|
|
|
+ mFailNum++;
|
|
|
+ mListener.onSubFail(entity);
|
|
|
//如果失败的任务数大于实际的下载任务数,任务组停止下载
|
|
|
- if (mFailMap.size() >= mExeMap.size()) {
|
|
|
+ if (mFailNum >= mActualTaskNum) {
|
|
|
closeTimer(false);
|
|
|
- if (mFailMap.size() == mGroupSize) { //所有任务都失败了,则认为该任务组已经失败
|
|
|
- mListener.onFail(true);
|
|
|
- } else {
|
|
|
- mListener.onStop(mCurrentLocation);
|
|
|
- }
|
|
|
+ mListener.onStop(mCurrentLocation);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -491,33 +369,27 @@ public abstract class AbsGroupUtil implements IUtil {
|
|
|
Timer timer = new Timer();
|
|
|
timer.schedule(new TimerTask() {
|
|
|
@Override public void run() {
|
|
|
- Downloader dt = mDownloaderMap.get(subEntity.getUrl());
|
|
|
+ Downloader dt = mDownloaderMap.get(entity.getUrl());
|
|
|
dt.start();
|
|
|
}
|
|
|
}, 3000);
|
|
|
}
|
|
|
|
|
|
private void handleSpeed(long speed) {
|
|
|
- subEntity.setSpeed(speed);
|
|
|
- subEntity.setConvertSpeed(speed <= 0 ? "" : CommonUtil.formatFileSize(speed) + "/s");
|
|
|
- subEntity.setPercent((int) (subEntity.getFileSize() <= 0 ? 0
|
|
|
- : subEntity.getCurrentProgress() * 100 / subEntity.getFileSize()));
|
|
|
+ entity.setSpeed(speed);
|
|
|
+ entity.setConvertSpeed(speed <= 0 ? "" : CommonUtil.formatFileSize(speed) + "/s");
|
|
|
}
|
|
|
|
|
|
private void saveData(int state, long location) {
|
|
|
- subTaskEntity.setState(state);
|
|
|
- subEntity.setState(state);
|
|
|
- subEntity.setComplete(state == IEntity.STATE_COMPLETE);
|
|
|
- if (state == IEntity.STATE_CANCEL) {
|
|
|
- subEntity.deleteData();
|
|
|
- return;
|
|
|
- } else if (subEntity.isComplete()) {
|
|
|
- subEntity.setCompleteTime(System.currentTimeMillis());
|
|
|
- subEntity.setCurrentProgress(subEntity.getFileSize());
|
|
|
+ entity.setState(state);
|
|
|
+ entity.setComplete(state == IEntity.STATE_COMPLETE);
|
|
|
+ if (entity.isComplete()) {
|
|
|
+ entity.setCompleteTime(System.currentTimeMillis());
|
|
|
+ entity.setCurrentProgress(entity.getFileSize());
|
|
|
} else if (location > 0) {
|
|
|
- subEntity.setCurrentProgress(location);
|
|
|
+ entity.setCurrentProgress(location);
|
|
|
}
|
|
|
- subTaskEntity.update();
|
|
|
+ entity.update();
|
|
|
}
|
|
|
|
|
|
@Override public void supportBreakpoint(boolean support) {
|