From 8158c58d6efd1aa0e44d9d844911f3bc7e473f9b Mon Sep 17 00:00:00 2001 From: laoyuyu <511455842@qq.com> Date: Mon, 6 Jan 2020 19:59:17 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dftp=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=90=8E=EF=BC=8C=E5=88=A0=E9=99=A4=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=E7=AB=AF=E7=9A=84=E6=96=87=E4=BB=B6=EF=BC=8C?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E9=87=8D=E6=96=B0=E4=B8=8B=E8=BD=BD=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aria/core/common/AbsBuilderTarget.java | 10 ++++ .../aria/core/common/AbsNormalTarget.java | 17 ++++++- .../core/download/CheckFtpDirEntityUtil.java | 7 ++- .../download/target/FtpDirConfigHandler.java | 2 + .../download/target/FtpDirNormalTarget.java | 14 +++++- .../core/manager/DGTaskWrapperFactory.java | 5 +- DEV_LOG.md | 2 + .../com/arialyy/aria/ftp/AbsFtpInfoTask.java | 8 ++- .../arialyy/aria/ftp/FtpRecordHandler.java | 20 +++++--- .../com/arialyy/aria/ftp/FtpTaskOption.java | 13 +++++ .../aria/ftp/download/FtpDGInfoTask.java | 47 ++++++++++++++++-- .../aria/ftp/upload/FtpUFileInfoTask.java | 38 +++++++++++++- .../ftp/upload/FtpUThreadTaskAdapter.java | 22 ++++----- .../core/download/DownloadGroupEntity.java | 2 +- .../aria/core/group/AbsGroupLoader.java | 3 +- .../aria/core/group/AbsSubDLoadUtil.java | 5 ++ .../aria/core/group/GroupRunState.java | 2 +- .../aria/core/group/GroupSendParams.java | 2 +- .../aria/core/group/SimpleSchedulers.java | 41 +++++++--------- .../aria/core/group/SimpleSubQueue.java | 2 +- .../aria/core/group/SimpleSubRetryQueue.java | 49 +++++++++++++++++++ .../aria/core/loader/AbsNormalTTBuilder.java | 13 ++++- .../arialyy/aria/core/loader/SubLoader.java | 7 ++- .../arialyy/aria/core/task/ThreadTask.java | 8 ++- .../com/arialyy/aria/orm/DelegateFind.java | 5 +- .../com/arialyy/aria/util/RecordUtil.java | 9 ++++ .../group/FTPDirDownloadActivity.java | 5 +- .../simple/core/upload/FtpUploadActivity.java | 3 +- .../simple/core/upload/UploadModule.java | 3 +- 29 files changed, 290 insertions(+), 74 deletions(-) create mode 100644 PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSubRetryQueue.java diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/AbsBuilderTarget.java b/Aria/src/main/java/com/arialyy/aria/core/common/AbsBuilderTarget.java index 16eb20c8..a070bf83 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/AbsBuilderTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/AbsBuilderTarget.java @@ -27,6 +27,13 @@ public abstract class AbsBuilderTarget extends private BuilderController mStartController; + /** + * 任务操作前调用 + */ + protected void onPre() { + + } + private synchronized BuilderController getController() { if (mStartController == null) { mStartController = new BuilderController(getTaskWrapper()); @@ -58,6 +65,7 @@ public abstract class AbsBuilderTarget extends */ @Override public long add() { + onPre(); return getController().add(); } @@ -68,6 +76,7 @@ public abstract class AbsBuilderTarget extends */ @Override public long create() { + onPre(); return getController().create(); } @@ -82,6 +91,7 @@ public abstract class AbsBuilderTarget extends */ @Override public long setHighestPriority() { + onPre(); return getController().setHighestPriority(); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/AbsNormalTarget.java b/Aria/src/main/java/com/arialyy/aria/core/common/AbsNormalTarget.java index 4920b9a6..863e63f6 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/AbsNormalTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/AbsNormalTarget.java @@ -31,6 +31,13 @@ import com.arialyy.aria.util.RecordUtil; public abstract class AbsNormalTarget extends AbsTarget implements INormalFeature { + /** + * 任务操作前调用 + */ + protected void onPre() { + + } + /** * 是否忽略权限检查 */ @@ -150,6 +157,7 @@ public abstract class AbsNormalTarget extends Ab */ @Override public void stop() { + onPre(); getController().stop(); } @@ -168,6 +176,7 @@ public abstract class AbsNormalTarget extends Ab * @param newStart true 立即将任务恢复到执行队列中 */ @Override public void resume(boolean newStart) { + onPre(); getController().resume(newStart); } @@ -176,7 +185,7 @@ public abstract class AbsNormalTarget extends Ab */ @Override public void cancel() { - getController().cancel(); + cancel(false); } /** @@ -184,17 +193,19 @@ public abstract class AbsNormalTarget extends Ab */ @Override public void reTry() { + onPre(); getController().reTry(); } /** * 删除任务 * - * @param removeFile {@code true} 不仅删除任务数据库记录,还会删除已经删除完成的文件 + * @param removeFile {@code true} 不仅删除任务数据库记录,还会删除已经完成的文件 * {@code false}如果任务已经完成,只删除任务数据库记录, */ @Override public void cancel(boolean removeFile) { + onPre(); getController().cancel(removeFile); } @@ -203,11 +214,13 @@ public abstract class AbsNormalTarget extends Ab */ @Override public long reStart() { + onPre(); return getController().reStart(); } @Override public void save() { + onPre(); getController().save(); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/CheckFtpDirEntityUtil.java b/Aria/src/main/java/com/arialyy/aria/core/download/CheckFtpDirEntityUtil.java index b46da62a..a5d63470 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/CheckFtpDirEntityUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/CheckFtpDirEntityUtil.java @@ -19,8 +19,8 @@ import android.text.TextUtils; import com.arialyy.aria.core.FtpUrlEntity; import com.arialyy.aria.core.inf.ICheckEntityUtil; import com.arialyy.aria.core.inf.IOptionConstant; -import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.util.ALog; +import com.arialyy.aria.util.CheckUtil; import java.io.File; public class CheckFtpDirEntityUtil implements ICheckEntityUtil { @@ -58,10 +58,9 @@ public class CheckFtpDirEntityUtil implements ICheckEntityUtil { return false; } - if ((mEntity.getDirPath() == null || !mEntity.getDirPath().equals(mWrapper.getDirPathTemp())) - && DbEntity.checkDataExist(DownloadGroupEntity.class, "dirPath=?", + // 检查路径冲突 + if (mWrapper.isNewTask() && !CheckUtil.checkDGPathConflicts(mWrapper.isIgnoreFilePathOccupy(), mWrapper.getDirPathTemp())) { - ALog.e(TAG, String.format("文件夹路径【%s】已被其它任务占用,请重新设置文件夹路径", mWrapper.getDirPathTemp())); return false; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/target/FtpDirConfigHandler.java b/Aria/src/main/java/com/arialyy/aria/core/download/target/FtpDirConfigHandler.java index 049001fd..3595874f 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/target/FtpDirConfigHandler.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/target/FtpDirConfigHandler.java @@ -15,10 +15,12 @@ */ package com.arialyy.aria.core.download.target; +import com.arialyy.aria.core.common.FtpOption; import com.arialyy.aria.core.download.DTaskWrapper; import com.arialyy.aria.core.inf.AbsTarget; import com.arialyy.aria.core.wrapper.AbsTaskWrapper; import com.arialyy.aria.core.wrapper.ITaskWrapper; +import com.arialyy.aria.util.CommonUtil; import java.util.List; /** diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/target/FtpDirNormalTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/target/FtpDirNormalTarget.java index f221a394..b79d158b 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/target/FtpDirNormalTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/target/FtpDirNormalTarget.java @@ -18,6 +18,7 @@ package com.arialyy.aria.core.download.target; import com.arialyy.aria.core.common.AbsNormalTarget; import com.arialyy.aria.core.common.FtpOption; import com.arialyy.aria.core.download.DownloadGroupEntity; +import com.arialyy.aria.core.inf.IOptionConstant; import com.arialyy.aria.core.manager.SubTaskManager; import com.arialyy.aria.util.CommonUtil; @@ -27,6 +28,7 @@ import com.arialyy.aria.util.CommonUtil; */ public class FtpDirNormalTarget extends AbsNormalTarget { private FtpDirConfigHandler mConfigHandler; + private FtpOption option; FtpDirNormalTarget(long taskId) { mConfigHandler = new FtpDirConfigHandler<>(this, taskId); @@ -71,8 +73,7 @@ public class FtpDirNormalTarget extends AbsNormalTarget { if (option == null) { throw new NullPointerException("ftp 任务配置为空"); } - option.setUrlEntity(CommonUtil.getFtpUrlInfo(getEntity().getKey())); - getTaskWrapper().getOptionParams().setParams(option); + this.option = option; return this; } @@ -88,4 +89,13 @@ public class FtpDirNormalTarget extends AbsNormalTarget { public SubTaskManager getSubTaskManager() { return mConfigHandler.getSubTaskManager(); } + + @Override protected void onPre() { + super.onPre(); + if (option == null) { + option = new FtpOption(); + } + option.setUrlEntity(CommonUtil.getFtpUrlInfo(getEntity().getKey())); + getTaskWrapper().getOptionParams().setParams(option); + } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/manager/DGTaskWrapperFactory.java b/Aria/src/main/java/com/arialyy/aria/core/manager/DGTaskWrapperFactory.java index 4cbf22c9..e877052b 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/manager/DGTaskWrapperFactory.java +++ b/Aria/src/main/java/com/arialyy/aria/core/manager/DGTaskWrapperFactory.java @@ -19,6 +19,7 @@ import com.arialyy.aria.core.download.DGEntityWrapper; import com.arialyy.aria.core.download.DGTaskWrapper; import com.arialyy.aria.core.download.DownloadGroupEntity; import com.arialyy.aria.orm.DbEntity; +import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.DbDataHelper; import java.util.List; @@ -26,7 +27,7 @@ import java.util.List; * Created by Aria.Lao on 2017/11/1. 组合任务wrapper */ class DGTaskWrapperFactory implements IGroupWrapperFactory { - private static final String TAG = "DTaskWrapperFactory"; + private final String TAG = CommonUtil.getClassName(this); private static volatile DGTaskWrapperFactory INSTANCE = null; private DGTaskWrapperFactory() { @@ -45,7 +46,7 @@ class DGTaskWrapperFactory implements IGroupWrapperFactory 1) { + if (mTaskWrapper.getEntity().getFileSize() > 1 && checkSubOption()) { callback.onSucceed(mEntity.getKey(), new CompleteInfo(200, mTaskWrapper)); } else { super.run(); } } + /** + * 检查子任务的任务设置 + * + * @return true 子任务任务设置成功,false 子任务任务设置失败 + */ + private boolean checkSubOption() { + for (DTaskWrapper wrapper : mTaskWrapper.getSubTaskWrapper()) { + if (wrapper.getTaskOption() == null) { + return false; + } + } + return true; + } + @Override protected String getRemotePath() { return mTaskOption.getUrlEntity().remotePath; } @@ -92,9 +108,14 @@ final class FtpDGInfoTask extends AbsFtpInfoTask try { IFtpUploadInterceptor interceptor = mTaskOption.getUploadInterceptor(); if (interceptor != null) { - /** + /* * true 使用拦截器,false 不使用拦截器 */ List files = new ArrayList<>(); @@ -84,6 +86,7 @@ final class FtpUFileInfoTask extends AbsFtpInfoTask ALog.d(TAG, String.format("删除文件%s,code: %s, msg: %s", b ? "成功" : "失败", client.getReplyCode(), client.getReplyString())); + mTaskOption.setServeFileIsExist(false); } else if (!TextUtils.isEmpty(interceptHandler.getNewFileName())) { ALog.i(TAG, String.format("远端已拥有同名文件,将修改remotePath,原文件名:%s,新文件名:%s", mEntity.getFileName(), interceptHandler.getNewFileName())); @@ -92,6 +95,7 @@ final class FtpUFileInfoTask extends AbsFtpInfoTask + interceptHandler.getNewFileName(); mTaskOption.setNewFileName(interceptHandler.getNewFileName()); + mTaskOption.setServeFileIsExist(false); closeClient(client); run(); return false; @@ -156,7 +160,39 @@ final class FtpUFileInfoTask extends AbsFtpInfoTask record.save(); threadRecord.save(); } + }else { + ALog.d(TAG, "FTP服务器上不存在该文件"); + mTaskWrapper.setNewTask(false); + TaskRecord record = DbDataHelper.getTaskRecord(mTaskWrapper.getKey(), + mTaskWrapper.getEntity().getTaskType()); + if (record != null){ + ALog.w(TAG, String.format("任务记录【%s】已存在,将删除该记录", mTaskWrapper.getKey())); + delTaskRecord(record); + } + mTaskWrapper.setNewTask(true); + record = new TaskRecord(); + record.fileName = mEntity.getFileName(); + record.filePath = mTaskWrapper.getKey(); + record.threadRecords = new ArrayList<>(); + ThreadRecord threadRecord = new ThreadRecord(); + threadRecord.taskKey = record.filePath; + threadRecord.startLocation = 0; + threadRecord.endLocation = mEntity.getFileSize(); + threadRecord.isComplete = false; + + record.save(); + threadRecord.save(); + } + } + + private void delTaskRecord(TaskRecord record){ + List threadRecords = record.threadRecords; + if (threadRecords != null && !threadRecords.isEmpty()){ + for (ThreadRecord tr : threadRecords){ + tr.deleteData(); + } } + record.deleteData(); } @Override protected void onPreComplete(int code) { diff --git a/FtpComponent/src/main/java/com/arialyy/aria/ftp/upload/FtpUThreadTaskAdapter.java b/FtpComponent/src/main/java/com/arialyy/aria/ftp/upload/FtpUThreadTaskAdapter.java index 6b8d9aa7..8d05431a 100644 --- a/FtpComponent/src/main/java/com/arialyy/aria/ftp/upload/FtpUThreadTaskAdapter.java +++ b/FtpComponent/src/main/java/com/arialyy/aria/ftp/upload/FtpUThreadTaskAdapter.java @@ -130,9 +130,10 @@ final class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter { if (isTimeOut) { fail(new AriaIOException(TAG, "socket连接失败,该问题一般出现于网络断开,客户端重新连接," + "但是服务器端无法创建socket缺没有返回错误码的情况。"), false); - } - if (fa != null) { - fa.close(); + if (fa != null) { + fa.close(); + } + closeTimer(); } isTimeOut = true; } catch (IOException e) { @@ -143,6 +144,7 @@ final class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter { } private void closeTimer() { + ALog.d(TAG, "closeTimer"); if (timer != null && !timer.isShutdown()) { timer.shutdown(); } @@ -158,6 +160,7 @@ final class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter { fa = new FtpFISAdapter(bis); storeFail = false; startTimer(); + final long fileSize = getThreadConfig().tempFile.length(); try { ALog.d(TAG, String.format("remotePath: %s", remotePath)); client.storeFile(remotePath, fa, new OnFtpInputStreamListener() { @@ -170,6 +173,7 @@ final class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter { if (getThreadTask().isBreak() && !isStoped) { isStoped = true; client.abor(); + return; } if (mSpeedBandUtil != null) { mSpeedBandUtil.limitNextBytes(bytesTransferred); @@ -178,19 +182,12 @@ final class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter { } catch (IOException e) { e.printStackTrace(); storeFail = true; - try { - fa.close(); - } catch (IOException e1) { - e1.printStackTrace(); - } - closeClient(client); } } }); } catch (IOException e) { String msg = String.format("文件上传错误,错误码为:%s, msg:%s, filePath: %s", client.getReply(), client.getReplyString(), getEntity().getFilePath()); - closeClient(client); e.printStackTrace(); if (e.getMessage().contains("AriaIOException caught while copying")) { e.printStackTrace(); @@ -198,11 +195,14 @@ final class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter { fail(new AriaIOException(TAG, msg, e), !storeFail); } return false; + } finally { + fa.close(); + closeClient(client); } if (storeFail) { return false; } - int reply = client.getReply(); + int reply = client.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { if (reply != FTPReply.TRANSFER_ABORTED) { fail(new AriaIOException(TAG, diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java b/PublicComponent/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java index a6b3c0ef..9aa6f10e 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java @@ -53,7 +53,7 @@ public class DownloadGroupEntity extends AbsGroupEntity { getSubEntities().get(0).getUrl())) { return ITaskWrapper.ERROR; } - return getSubEntities().get(0).getUrl().startsWith("ftp") ? ITaskWrapper.D_FTP_DIR + return (groupHash.startsWith("ftp") || groupHash.startsWith("sftp")) ? ITaskWrapper.D_FTP_DIR : ITaskWrapper.DG_HTTP; } diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsGroupLoader.java b/PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsGroupLoader.java index 7bd3ff25..3969971a 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsGroupLoader.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsGroupLoader.java @@ -267,7 +267,8 @@ public abstract class AbsGroupLoader implements ILoaderVisitor, ILoader { Looper looper = Looper.myLooper(); initState(looper); getState().setSubSize(getWrapper().getSubTaskWrapper().size()); - if (getState().getCompleteNum() == getState().getSubSize()) { + if (getState().getCompleteNum() != 0 + && getState().getCompleteNum() == getState().getSubSize()) { mListener.onComplete(); return; } diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsSubDLoadUtil.java b/PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsSubDLoadUtil.java index fe5ebb3b..3ec13a77 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsSubDLoadUtil.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsSubDLoadUtil.java @@ -16,6 +16,7 @@ package com.arialyy.aria.core.group; import android.os.Handler; +import com.arialyy.aria.core.TaskRecord; import com.arialyy.aria.core.download.DTaskWrapper; import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.inf.IUtil; @@ -81,6 +82,10 @@ public abstract class AbsSubDLoadUtil implements IUtil, Runnable { return mWrapper.getEntity(); } + public TaskRecord getRecord(){ + return getLoader().getRecord(); + } + @Override public void run() { if (isStop || isCancel) { return; diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/group/GroupRunState.java b/PublicComponent/src/main/java/com/arialyy/aria/core/group/GroupRunState.java index dee9834f..7dcbcc13 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/core/group/GroupRunState.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/core/group/GroupRunState.java @@ -23,7 +23,7 @@ import java.util.Set; /** * 组合任务执行中的状态信息 */ -public class GroupRunState { +public final class GroupRunState { /** * 子任务数 */ diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/group/GroupSendParams.java b/PublicComponent/src/main/java/com/arialyy/aria/core/group/GroupSendParams.java index 82a157ec..303fff3d 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/core/group/GroupSendParams.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/core/group/GroupSendParams.java @@ -22,7 +22,7 @@ import com.arialyy.aria.core.task.AbsGroupTask; * Created by lyy on 2017/9/8. * 任务组参数传递 */ -public class GroupSendParams { +public final class GroupSendParams { public GROUP_TASK groupTask; public ENTITY entity; diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSchedulers.java b/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSchedulers.java index 9634b497..7bf10c0f 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSchedulers.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSchedulers.java @@ -20,21 +20,20 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import com.arialyy.aria.core.AriaConfig; -import com.arialyy.aria.core.common.AbsEntity; import com.arialyy.aria.core.config.Configuration; import com.arialyy.aria.core.inf.IThreadStateManager; +import com.arialyy.aria.core.loader.IRecordHandler; import com.arialyy.aria.core.manager.ThreadTaskManager; import com.arialyy.aria.exception.TaskException; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.NetUtils; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.TimeUnit; +import java.io.File; /** * 组合任务子任务调度器,用于调度任务的开始、停止、失败、完成等情况 * 该调度器生命周期和{@link AbsGroupLoaderUtil}生命周期一致 */ -class SimpleSchedulers implements Handler.Callback { +final class SimpleSchedulers implements Handler.Callback { private static final String TAG = "SimpleSchedulers"; private SimpleSubQueue mQueue; private GroupRunState mGState; @@ -86,7 +85,8 @@ class SimpleSchedulers implements Handler.Callback { ThreadTaskManager.getInstance().removeSingleTaskThread(mKey, threadName); break; case IThreadStateManager.STATE_FAIL: - handleFail(loaderUtil); + boolean needRetry = b.getBoolean(IThreadStateManager.DATA_RETRY, false); + handleFail(loaderUtil, needRetry); ThreadTaskManager.getInstance().removeSingleTaskThread(mKey, threadName); break; } @@ -98,18 +98,19 @@ class SimpleSchedulers implements Handler.Callback { * 1、子任务失败次数大于等于配置的重试次数,才能认为子任务停止 * 2、stopNum + failNum + completeNum + cacheNum == subSize,则认为组合任务停止 * 3、failNum == subSize,只有全部的子任务都失败了,才能任务组合任务失败 + * + * @param needRetry true 需要重试,false 不需要重试 */ - private synchronized void handleFail(final AbsSubDLoadUtil loaderUtil) { + private synchronized void handleFail(final AbsSubDLoadUtil loaderUtil, boolean needRetry) { Configuration config = Configuration.getInstance(); - long interval = config.dGroupCfg.getSubReTryInterval(); int num = config.dGroupCfg.getSubReTryNum(); boolean isNotNetRetry = config.appCfg.isNotNetRetry(); - final int reTryNum = num; - if ((!NetUtils.isConnected(AriaConfig.getInstance().getAPP()) && !isNotNetRetry) + if (!needRetry + || (!NetUtils.isConnected(AriaConfig.getInstance().getAPP()) && !isNotNetRetry) || loaderUtil.getLoader() == null // 如果获取不到文件信息,loader为空 - || loaderUtil.getEntity().getFailNum() > reTryNum) { + || loaderUtil.getEntity().getFailNum() > num) { mQueue.removeTaskFromExecQ(loaderUtil); mGState.listener.onSubFail(loaderUtil.getEntity(), new TaskException(TAG, String.format("任务组子任务【%s】下载失败,下载地址【%s】", loaderUtil.getEntity().getFileName(), @@ -127,20 +128,7 @@ class SimpleSchedulers implements Handler.Callback { } return; } - - // 如果获取不到文件信息,loader为空 - final ScheduledThreadPoolExecutor timer = new ScheduledThreadPoolExecutor(1); - timer.schedule(new Runnable() { - @Override public void run() { - AbsEntity entity = loaderUtil.getEntity(); - if (entity.getFailNum() <= reTryNum) { - ALog.d(TAG, String.format("任务【%s】开始重试", loaderUtil.getEntity().getFileName())); - loaderUtil.reStart(); - } else { - startNext(); - } - } - }, interval, TimeUnit.MILLISECONDS); + SimpleSubRetryQueue.getInstance().offer(loaderUtil); } /** @@ -175,6 +163,11 @@ class SimpleSchedulers implements Handler.Callback { */ private synchronized void handleComplete(AbsSubDLoadUtil loader) { ALog.d(TAG, String.format("子任务【%s】完成", loader.getEntity().getFileName())); + if (loader.getRecord().isBlock) { + File partFile = + new File(String.format(IRecordHandler.SUB_PATH, loader.getRecord().filePath, 0)); + partFile.renameTo(new File(loader.getRecord().filePath)); + } ThreadTaskManager.getInstance().removeTaskThread(loader.getKey()); mGState.listener.onSubComplete(loader.getEntity()); mQueue.removeTaskFromExecQ(loader); diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSubQueue.java b/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSubQueue.java index 57020f3c..b50c7758 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSubQueue.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSubQueue.java @@ -29,7 +29,7 @@ import java.util.Set; /** * 组合任务队列,该队列生命周期和{@link AbsGroupLoaderUtil}生命周期一致 */ -class SimpleSubQueue implements ISubQueue { +final class SimpleSubQueue implements ISubQueue { private final String TAG = CommonUtil.getClassName(getClass()); /** * 缓存下载器 diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSubRetryQueue.java b/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSubRetryQueue.java new file mode 100644 index 00000000..0d95cd05 --- /dev/null +++ b/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSubRetryQueue.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.arialyy.aria.core.group; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * 子任务重试队列 + */ +final class SimpleSubRetryQueue { + private volatile static SimpleSubRetryQueue INSTANCE = null; + private ExecutorService pool = new ThreadPoolExecutor(5, 100, + 60L, TimeUnit.SECONDS, + new SynchronousQueue()); + + public synchronized static SimpleSubRetryQueue getInstance() { + if (INSTANCE == null) { + synchronized (SimpleSubRetryQueue.class) { + INSTANCE = new SimpleSubRetryQueue(); + } + } + + return INSTANCE; + } + + private SimpleSubRetryQueue() { + + } + + void offer(AbsSubDLoadUtil subDLoadUtil) { + pool.submit(subDLoadUtil.getLoader()); + } +} diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsNormalTTBuilder.java b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsNormalTTBuilder.java index 33d7eb86..4f29e41a 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsNormalTTBuilder.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsNormalTTBuilder.java @@ -1,6 +1,8 @@ package com.arialyy.aria.core.loader; +import android.os.Bundle; import android.os.Handler; +import android.os.Message; import com.arialyy.aria.core.TaskRecord; import com.arialyy.aria.core.ThreadRecord; import com.arialyy.aria.core.common.AbsNormalEntity; @@ -133,7 +135,16 @@ public abstract class AbsNormalTTBuilder implements IThreadTaskBuilder { if (tr.isComplete) {//该线程已经完成 currentProgress += endL - startL; ALog.d(TAG, String.format("任务【%s】线程__%s__已完成", mWrapper.getKey(), i)); - mStateHandler.obtainMessage(IThreadStateManager.STATE_COMPLETE).sendToTarget(); + Message msg = mStateHandler.obtainMessage(); + msg.what = IThreadStateManager.STATE_COMPLETE; + Bundle b = msg.getData(); + if (b == null){ + b = new Bundle(); + } + b.putString(IThreadStateManager.DATA_THREAD_NAME, + CommonUtil.getThreadName(getEntity().getUrl(), tr.threadId)); + msg.setData(b); + msg.sendToTarget(); continue; } diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/SubLoader.java b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/SubLoader.java index 5d162beb..f227b2e7 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/SubLoader.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/SubLoader.java @@ -48,6 +48,7 @@ public final class SubLoader implements ILoader, ILoaderVisitor { private IRecordHandler recordHandler; private IThreadTask threadTask; private String parentKey; + private TaskRecord record; public SubLoader(AbsTaskWrapper wrapper, Handler schedulers) { this.wrapper = wrapper; @@ -92,7 +93,7 @@ public final class SubLoader implements ILoader, ILoaderVisitor { } private void handlerTask() { - TaskRecord record = recordHandler.getRecord(wrapper.getEntity().getFileSize()); + record = recordHandler.getRecord(wrapper.getEntity().getFileSize()); if (record.threadRecords != null && !TextUtils.isEmpty(record.filePath) && new File(record.filePath).exists() @@ -123,6 +124,10 @@ public final class SubLoader implements ILoader, ILoaderVisitor { } } + public TaskRecord getRecord(){ + return record; + } + public void setParentKey(String parentKey) { this.parentKey = parentKey; } diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/task/ThreadTask.java b/PublicComponent/src/main/java/com/arialyy/aria/core/task/ThreadTask.java index 8c36ae72..a9463d26 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/core/task/ThreadTask.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/core/task/ThreadTask.java @@ -86,11 +86,17 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver { mEntity = mTaskWrapper.getEntity(); mLastSaveTime = System.currentTimeMillis(); mConfigThreadPool = Executors.newCachedThreadPool(); - isNotNetRetry = AriaConfig.getInstance().getAConfig().isNotNetRetry(); mRangeProgress = mRecord.startLocation; mLastRangeProgress = mRangeProgress; updateInterval = config.updateInterval; + checkFileExist(); + } + + private void checkFileExist() { + if (!getConfig().tempFile.exists()) { + FileUtil.createFile(getConfig().tempFile); + } } /** diff --git a/PublicComponent/src/main/java/com/arialyy/aria/orm/DelegateFind.java b/PublicComponent/src/main/java/com/arialyy/aria/orm/DelegateFind.java index 55dbfffc..4f0ba511 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/orm/DelegateFind.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/orm/DelegateFind.java @@ -98,7 +98,7 @@ class DelegateFind extends AbsDelegate { */ List findRelationData(SQLiteDatabase db, Class clazz, String... expression) { - return exeRelationSql(db, clazz, -1, -1, expression); + return exeRelationSql(db, clazz, 1, 10, expression); } /** @@ -111,6 +111,7 @@ class DelegateFind extends AbsDelegate { List findRelationData(SQLiteDatabase db, Class clazz, int page, int num, String... expression) { if (page < 1 || num < 1) { + ALog.w(TAG, "page,num 小于1"); return null; } return exeRelationSql(db, clazz, page, num, expression); @@ -345,6 +346,7 @@ class DelegateFind extends AbsDelegate { List findData(SQLiteDatabase db, Class clazz, int page, int num, String... expression) { if (page < 1 || num < 1) { + ALog.w(TAG, "page, bum 小于1"); return null; } db = checkDb(db); @@ -390,6 +392,7 @@ class DelegateFind extends AbsDelegate { List findDataByFuzzy(SQLiteDatabase db, Class clazz, int page, int num, String conditions) { if (page < 1 || num < 1) { + ALog.w(TAG, "page, bum 小于1"); return null; } db = checkDb(db); diff --git a/PublicComponent/src/main/java/com/arialyy/aria/util/RecordUtil.java b/PublicComponent/src/main/java/com/arialyy/aria/util/RecordUtil.java index 3debb45f..7754b050 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/util/RecordUtil.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/util/RecordUtil.java @@ -65,6 +65,15 @@ public class RecordUtil { return; } DownloadGroupEntity groupEntity = DbDataHelper.getDGEntityByPath(dirPath); + // 处理组任务存在,而子任务为空的情况 + if (groupEntity == null) { + groupEntity = DbEntity.findFirst(DownloadGroupEntity.class, "dirPath=?", dirPath); + if (groupEntity != null) { + groupEntity.deleteData(); + DbEntity.deleteData(DownloadEntity.class, "groupHash=?", groupEntity.getGroupHash()); + } + return; + } delGroupTaskRecord(groupEntity, removeFile, true); } diff --git a/app/src/main/java/com/arialyy/simple/core/download/group/FTPDirDownloadActivity.java b/app/src/main/java/com/arialyy/simple/core/download/group/FTPDirDownloadActivity.java index a5fb594f..e13632d2 100644 --- a/app/src/main/java/com/arialyy/simple/core/download/group/FTPDirDownloadActivity.java +++ b/app/src/main/java/com/arialyy/simple/core/download/group/FTPDirDownloadActivity.java @@ -37,7 +37,7 @@ import java.security.AlgorithmConstraints; * Created by lyy on 2017/7/6. */ public class FTPDirDownloadActivity extends BaseActivity { - private static final String dir = "ftp://9.9.9.50:2121/upload/测试"; + private static final String dir = "ftp://9.9.9.72:2121/upload/测试"; private SubStateLinearLayout mChildList; private long mTaskId = -1; @@ -81,6 +81,7 @@ public class FTPDirDownloadActivity extends BaseActivity { private String mUrl; private UploadModule mModule; private long mTaskId = -1; - private String user = "ftpuser", pwd = "ftpuser2020"; - //private String user = "lao", pwd = "123456"; + private String user = "lao", pwd = "123456"; @Override protected void init(Bundle savedInstanceState) { setTile("D_FTP 文件上传"); diff --git a/app/src/main/java/com/arialyy/simple/core/upload/UploadModule.java b/app/src/main/java/com/arialyy/simple/core/upload/UploadModule.java index 6dcb68d7..deff3f3c 100644 --- a/app/src/main/java/com/arialyy/simple/core/upload/UploadModule.java +++ b/app/src/main/java/com/arialyy/simple/core/upload/UploadModule.java @@ -38,8 +38,7 @@ public class UploadModule extends BaseViewModule { //String url = AppUtil.getConfigValue(context, FTP_URL_KEY, "ftp://9.9.9.72:2121/aab/你好"); //String filePath = AppUtil.getConfigValue(context, FTP_PATH_KEY, // Environment.getExternalStorageDirectory().getPath() + "/Download/AndroidAria.db"); - String url = "ftp://101.132.33.64:21/home/ftpuser/videopic/historymonitor/jobs/test"; - //String url = "ftp://9.9.9.72:2121/aab/你好"; + String url = "ftp://9.9.9.72:2121/aab/你好"; String filePath = "/mnt/sdcard/QQMusic-import-1.2.1.zip"; UploadEntity entity = Aria.upload(context).getFirstUploadEntity(filePath);