修复ftp上传完成后,删除服务器端的文件,无法重新下载的问题

pull/617/head
laoyuyu 5 years ago
parent e14928e260
commit 8158c58d6e
  1. 10
      Aria/src/main/java/com/arialyy/aria/core/common/AbsBuilderTarget.java
  2. 17
      Aria/src/main/java/com/arialyy/aria/core/common/AbsNormalTarget.java
  3. 7
      Aria/src/main/java/com/arialyy/aria/core/download/CheckFtpDirEntityUtil.java
  4. 2
      Aria/src/main/java/com/arialyy/aria/core/download/target/FtpDirConfigHandler.java
  5. 14
      Aria/src/main/java/com/arialyy/aria/core/download/target/FtpDirNormalTarget.java
  6. 5
      Aria/src/main/java/com/arialyy/aria/core/manager/DGTaskWrapperFactory.java
  7. 2
      DEV_LOG.md
  8. 8
      FtpComponent/src/main/java/com/arialyy/aria/ftp/AbsFtpInfoTask.java
  9. 20
      FtpComponent/src/main/java/com/arialyy/aria/ftp/FtpRecordHandler.java
  10. 13
      FtpComponent/src/main/java/com/arialyy/aria/ftp/FtpTaskOption.java
  11. 47
      FtpComponent/src/main/java/com/arialyy/aria/ftp/download/FtpDGInfoTask.java
  12. 38
      FtpComponent/src/main/java/com/arialyy/aria/ftp/upload/FtpUFileInfoTask.java
  13. 22
      FtpComponent/src/main/java/com/arialyy/aria/ftp/upload/FtpUThreadTaskAdapter.java
  14. 2
      PublicComponent/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java
  15. 3
      PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsGroupLoader.java
  16. 5
      PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsSubDLoadUtil.java
  17. 2
      PublicComponent/src/main/java/com/arialyy/aria/core/group/GroupRunState.java
  18. 2
      PublicComponent/src/main/java/com/arialyy/aria/core/group/GroupSendParams.java
  19. 41
      PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSchedulers.java
  20. 2
      PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSubQueue.java
  21. 49
      PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSubRetryQueue.java
  22. 13
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsNormalTTBuilder.java
  23. 7
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/SubLoader.java
  24. 8
      PublicComponent/src/main/java/com/arialyy/aria/core/task/ThreadTask.java
  25. 5
      PublicComponent/src/main/java/com/arialyy/aria/orm/DelegateFind.java
  26. 9
      PublicComponent/src/main/java/com/arialyy/aria/util/RecordUtil.java
  27. 5
      app/src/main/java/com/arialyy/simple/core/download/group/FTPDirDownloadActivity.java
  28. 3
      app/src/main/java/com/arialyy/simple/core/upload/FtpUploadActivity.java
  29. 3
      app/src/main/java/com/arialyy/simple/core/upload/UploadModule.java

@ -27,6 +27,13 @@ public abstract class AbsBuilderTarget<TARGET extends AbsBuilderTarget> extends
private BuilderController mStartController; private BuilderController mStartController;
/**
* 任务操作前调用
*/
protected void onPre() {
}
private synchronized BuilderController getController() { private synchronized BuilderController getController() {
if (mStartController == null) { if (mStartController == null) {
mStartController = new BuilderController(getTaskWrapper()); mStartController = new BuilderController(getTaskWrapper());
@ -58,6 +65,7 @@ public abstract class AbsBuilderTarget<TARGET extends AbsBuilderTarget> extends
*/ */
@Override @Override
public long add() { public long add() {
onPre();
return getController().add(); return getController().add();
} }
@ -68,6 +76,7 @@ public abstract class AbsBuilderTarget<TARGET extends AbsBuilderTarget> extends
*/ */
@Override @Override
public long create() { public long create() {
onPre();
return getController().create(); return getController().create();
} }
@ -82,6 +91,7 @@ public abstract class AbsBuilderTarget<TARGET extends AbsBuilderTarget> extends
*/ */
@Override @Override
public long setHighestPriority() { public long setHighestPriority() {
onPre();
return getController().setHighestPriority(); return getController().setHighestPriority();
} }
} }

@ -31,6 +31,13 @@ import com.arialyy.aria.util.RecordUtil;
public abstract class AbsNormalTarget<TARGET extends AbsNormalTarget> extends AbsTarget<TARGET> public abstract class AbsNormalTarget<TARGET extends AbsNormalTarget> extends AbsTarget<TARGET>
implements INormalFeature { implements INormalFeature {
/**
* 任务操作前调用
*/
protected void onPre() {
}
/** /**
* 是否忽略权限检查 * 是否忽略权限检查
*/ */
@ -150,6 +157,7 @@ public abstract class AbsNormalTarget<TARGET extends AbsNormalTarget> extends Ab
*/ */
@Override @Override
public void stop() { public void stop() {
onPre();
getController().stop(); getController().stop();
} }
@ -168,6 +176,7 @@ public abstract class AbsNormalTarget<TARGET extends AbsNormalTarget> extends Ab
* @param newStart true 立即将任务恢复到执行队列中 * @param newStart true 立即将任务恢复到执行队列中
*/ */
@Override public void resume(boolean newStart) { @Override public void resume(boolean newStart) {
onPre();
getController().resume(newStart); getController().resume(newStart);
} }
@ -176,7 +185,7 @@ public abstract class AbsNormalTarget<TARGET extends AbsNormalTarget> extends Ab
*/ */
@Override @Override
public void cancel() { public void cancel() {
getController().cancel(); cancel(false);
} }
/** /**
@ -184,17 +193,19 @@ public abstract class AbsNormalTarget<TARGET extends AbsNormalTarget> extends Ab
*/ */
@Override @Override
public void reTry() { public void reTry() {
onPre();
getController().reTry(); getController().reTry();
} }
/** /**
* 删除任务 * 删除任务
* *
* @param removeFile {@code true} 不仅删除任务数据库记录还会删除已经删除完成的文件 * @param removeFile {@code true} 不仅删除任务数据库记录还会删除已经完成的文件
* {@code false}如果任务已经完成只删除任务数据库记录 * {@code false}如果任务已经完成只删除任务数据库记录
*/ */
@Override @Override
public void cancel(boolean removeFile) { public void cancel(boolean removeFile) {
onPre();
getController().cancel(removeFile); getController().cancel(removeFile);
} }
@ -203,11 +214,13 @@ public abstract class AbsNormalTarget<TARGET extends AbsNormalTarget> extends Ab
*/ */
@Override @Override
public long reStart() { public long reStart() {
onPre();
return getController().reStart(); return getController().reStart();
} }
@Override @Override
public void save() { public void save() {
onPre();
getController().save(); getController().save();
} }
} }

@ -19,8 +19,8 @@ import android.text.TextUtils;
import com.arialyy.aria.core.FtpUrlEntity; import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.inf.ICheckEntityUtil; import com.arialyy.aria.core.inf.ICheckEntityUtil;
import com.arialyy.aria.core.inf.IOptionConstant; import com.arialyy.aria.core.inf.IOptionConstant;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CheckUtil;
import java.io.File; import java.io.File;
public class CheckFtpDirEntityUtil implements ICheckEntityUtil { public class CheckFtpDirEntityUtil implements ICheckEntityUtil {
@ -58,10 +58,9 @@ public class CheckFtpDirEntityUtil implements ICheckEntityUtil {
return false; 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())) { mWrapper.getDirPathTemp())) {
ALog.e(TAG, String.format("文件夹路径【%s】已被其它任务占用,请重新设置文件夹路径", mWrapper.getDirPathTemp()));
return false; return false;
} }

@ -15,10 +15,12 @@
*/ */
package com.arialyy.aria.core.download.target; 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.download.DTaskWrapper;
import com.arialyy.aria.core.inf.AbsTarget; import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper; import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.wrapper.ITaskWrapper; import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.util.CommonUtil;
import java.util.List; import java.util.List;
/** /**

@ -18,6 +18,7 @@ package com.arialyy.aria.core.download.target;
import com.arialyy.aria.core.common.AbsNormalTarget; import com.arialyy.aria.core.common.AbsNormalTarget;
import com.arialyy.aria.core.common.FtpOption; import com.arialyy.aria.core.common.FtpOption;
import com.arialyy.aria.core.download.DownloadGroupEntity; 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.core.manager.SubTaskManager;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
@ -27,6 +28,7 @@ import com.arialyy.aria.util.CommonUtil;
*/ */
public class FtpDirNormalTarget extends AbsNormalTarget<FtpDirNormalTarget> { public class FtpDirNormalTarget extends AbsNormalTarget<FtpDirNormalTarget> {
private FtpDirConfigHandler<FtpDirNormalTarget> mConfigHandler; private FtpDirConfigHandler<FtpDirNormalTarget> mConfigHandler;
private FtpOption option;
FtpDirNormalTarget(long taskId) { FtpDirNormalTarget(long taskId) {
mConfigHandler = new FtpDirConfigHandler<>(this, taskId); mConfigHandler = new FtpDirConfigHandler<>(this, taskId);
@ -71,8 +73,7 @@ public class FtpDirNormalTarget extends AbsNormalTarget<FtpDirNormalTarget> {
if (option == null) { if (option == null) {
throw new NullPointerException("ftp 任务配置为空"); throw new NullPointerException("ftp 任务配置为空");
} }
option.setUrlEntity(CommonUtil.getFtpUrlInfo(getEntity().getKey())); this.option = option;
getTaskWrapper().getOptionParams().setParams(option);
return this; return this;
} }
@ -88,4 +89,13 @@ public class FtpDirNormalTarget extends AbsNormalTarget<FtpDirNormalTarget> {
public SubTaskManager getSubTaskManager() { public SubTaskManager getSubTaskManager() {
return mConfigHandler.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);
}
} }

@ -19,6 +19,7 @@ import com.arialyy.aria.core.download.DGEntityWrapper;
import com.arialyy.aria.core.download.DGTaskWrapper; import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.aria.core.download.DownloadGroupEntity; import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.util.DbDataHelper; import com.arialyy.aria.util.DbDataHelper;
import java.util.List; import java.util.List;
@ -26,7 +27,7 @@ import java.util.List;
* Created by Aria.Lao on 2017/11/1. 组合任务wrapper * Created by Aria.Lao on 2017/11/1. 组合任务wrapper
*/ */
class DGTaskWrapperFactory implements IGroupWrapperFactory<DownloadGroupEntity, DGTaskWrapper> { class DGTaskWrapperFactory implements IGroupWrapperFactory<DownloadGroupEntity, DGTaskWrapper> {
private static final String TAG = "DTaskWrapperFactory"; private final String TAG = CommonUtil.getClassName(this);
private static volatile DGTaskWrapperFactory INSTANCE = null; private static volatile DGTaskWrapperFactory INSTANCE = null;
private DGTaskWrapperFactory() { private DGTaskWrapperFactory() {
@ -45,7 +46,7 @@ class DGTaskWrapperFactory implements IGroupWrapperFactory<DownloadGroupEntity,
DGTaskWrapper wrapper; DGTaskWrapper wrapper;
if (taskId == -1) { if (taskId == -1) {
wrapper = new DGTaskWrapper(new DownloadGroupEntity()); wrapper = new DGTaskWrapper(new DownloadGroupEntity());
}else { } else {
DownloadGroupEntity entity = getOrCreateHttpDGEntity(taskId); DownloadGroupEntity entity = getOrCreateHttpDGEntity(taskId);
wrapper = new DGTaskWrapper(entity); wrapper = new DGTaskWrapper(entity);
if (entity.getSubEntities() != null && !entity.getSubEntities().isEmpty()) { if (entity.getSubEntities() != null && !entity.getSubEntities().isEmpty()) {

@ -3,6 +3,8 @@
- fix bug https://github.com/AriaLyy/Aria/issues/573 - fix bug https://github.com/AriaLyy/Aria/issues/573
- android P适配 https://github.com/AriaLyy/Aria/issues/581 - android P适配 https://github.com/AriaLyy/Aria/issues/581
- 添加ftp服务器标志 https://github.com/AriaLyy/Aria/issues/580 - 添加ftp服务器标志 https://github.com/AriaLyy/Aria/issues/580
- 重构loader模块,让loader模块的代码更加清晰,去除一些不必要的线程创建
- 修复ftp上传完成后,删除服务器端的文件,无法重新下载的问题
+ v_3.8.1 (2019/12/22) + v_3.8.1 (2019/12/22)
- 修复一个表创建失败的问题 https://github.com/AriaLyy/Aria/issues/570 - 修复一个表创建失败的问题 https://github.com/AriaLyy/Aria/issues/570
- 修复一个非分块模式下导致下载失败的问题 https://github.com/AriaLyy/Aria/issues/571 - 修复一个非分块模式下导致下载失败的问题 https://github.com/AriaLyy/Aria/issues/571

@ -91,7 +91,7 @@ public abstract class AbsFtpInfoTask<ENTITY extends AbsEntity, TASK_WRAPPER exte
} }
String remotePath = CommonUtil.convertFtpChar(charSet, getRemotePath()); String remotePath = CommonUtil.convertFtpChar(charSet, getRemotePath());
FTPFile[] files = client.listFiles(getRemotePath()); FTPFile[] files = client.listFiles(remotePath);
boolean isExist = files.length != 0; boolean isExist = files.length != 0;
if (!isExist && !isUpload) { if (!isExist && !isUpload) {
int i = remotePath.lastIndexOf(File.separator); int i = remotePath.lastIndexOf(File.separator);
@ -128,7 +128,11 @@ public abstract class AbsFtpInfoTask<ENTITY extends AbsEntity, TASK_WRAPPER exte
} }
//为了防止编码错乱,需要使用原始字符串 //为了防止编码错乱,需要使用原始字符串
mSize = getFileSize(files, client, getRemotePath()); if (isUpload && files.length == 0){
handleFile(getRemotePath(), null);
}else {
mSize = getFileSize(files, client, getRemotePath());
}
int reply = client.getReplyCode(); int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) { if (!FTPReply.isPositiveCompletion(reply)) {
if (isUpload) { if (isUpload) {

@ -38,15 +38,21 @@ public final class FtpRecordHandler extends RecordHandler {
} }
@Override public void handlerTaskRecord(TaskRecord record) { @Override public void handlerTaskRecord(TaskRecord record) {
if (getWrapper().getRequestType() == ITaskWrapper.U_FTP) {
// 上传任务记录的处理交由FtpUFileInfoTask 完成
return;
}
RecordHelper helper = new RecordHelper(getWrapper(), record); RecordHelper helper = new RecordHelper(getWrapper(), record);
if (getWrapper().isSupportBP()) { if (record.threadNum == 1) {
if (record.isBlock) {
helper.handleBlockRecord();
} else {
helper.handleMultiRecord();
}
} else if (record.threadNum == 1) {
helper.handleSingleThreadRecord(); helper.handleSingleThreadRecord();
} else {
if (getWrapper().isSupportBP()) {
if (record.isBlock) {
helper.handleBlockRecord();
} else {
helper.handleMultiRecord();
}
}
} }
} }

@ -72,6 +72,11 @@ public final class FtpTaskOption implements ITaskOption {
*/ */
private String activeExternalIPAddress; private String activeExternalIPAddress;
/**
* 服务器文件是否存在true 文件存在用于ftp上传
*/
private boolean serveFileIsExist = true;
//---------------- ftp client 配置信息 start //---------------- ftp client 配置信息 start
private String defaultDateFormatStr = null; private String defaultDateFormatStr = null;
private String recentDateFormatStr = null; private String recentDateFormatStr = null;
@ -81,6 +86,14 @@ public final class FtpTaskOption implements ITaskOption {
private String systemKey = FTPClientConfig.SYST_UNIX; private String systemKey = FTPClientConfig.SYST_UNIX;
//---------------- ftp client 配置信息 end //---------------- ftp client 配置信息 end
public boolean isServeFileIsExist() {
return serveFileIsExist;
}
public void setServeFileIsExist(boolean serveFileIsExist) {
this.serveFileIsExist = serveFileIsExist;
}
public String getActiveExternalIPAddress() { public String getActiveExternalIPAddress() {
return activeExternalIPAddress; return activeExternalIPAddress;
} }

@ -28,6 +28,8 @@ import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper; import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.ftp.AbsFtpInfoTask; import com.arialyy.aria.ftp.AbsFtpInfoTask;
import com.arialyy.aria.ftp.FtpTaskOption; import com.arialyy.aria.ftp.FtpTaskOption;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.util.RecordUtil; import com.arialyy.aria.util.RecordUtil;
import java.nio.charset.Charset; import java.nio.charset.Charset;
@ -43,13 +45,27 @@ final class FtpDGInfoTask extends AbsFtpInfoTask<DownloadGroupEntity, DGTaskWrap
} }
@Override public void run() { @Override public void run() {
if (mTaskWrapper.getEntity().getFileSize() > 1) { if (mTaskWrapper.getEntity().getFileSize() > 1 && checkSubOption()) {
callback.onSucceed(mEntity.getKey(), new CompleteInfo(200, mTaskWrapper)); callback.onSucceed(mEntity.getKey(), new CompleteInfo(200, mTaskWrapper));
} else { } else {
super.run(); 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() { @Override protected String getRemotePath() {
return mTaskOption.getUrlEntity().remotePath; return mTaskOption.getUrlEntity().remotePath;
} }
@ -92,9 +108,14 @@ final class FtpDGInfoTask extends AbsFtpInfoTask<DownloadGroupEntity, DGTaskWrap
*/ */
private void addEntity(String remotePath, FTPFile ftpFile) { private void addEntity(String remotePath, FTPFile ftpFile) {
final FtpUrlEntity urlEntity = mTaskOption.getUrlEntity().clone(); final FtpUrlEntity urlEntity = mTaskOption.getUrlEntity().clone();
String url =
urlEntity.scheme + "://" + urlEntity.hostName + ":" + urlEntity.port + "/" + remotePath;
if (checkEntityExist(url)){
ALog.w(TAG, "子任务已存在,取消子任务的添加,url = " + url);
return;
}
DownloadEntity entity = new DownloadEntity(); DownloadEntity entity = new DownloadEntity();
entity.setUrl( entity.setUrl(url);
urlEntity.scheme + "://" + urlEntity.hostName + ":" + urlEntity.port + "/" + remotePath);
entity.setFilePath(mEntity.getDirPath() + "/" + remotePath); entity.setFilePath(mEntity.getDirPath() + "/" + remotePath);
int lastIndex = remotePath.lastIndexOf("/"); int lastIndex = remotePath.lastIndexOf("/");
String fileName = lastIndex < 0 ? CommonUtil.keyToHashKey(remotePath) String fileName = lastIndex < 0 ? CommonUtil.keyToHashKey(remotePath)
@ -106,8 +127,9 @@ final class FtpDGInfoTask extends AbsFtpInfoTask<DownloadGroupEntity, DGTaskWrap
entity.setConvertFileSize(CommonUtil.formatFileSize(ftpFile.getSize())); entity.setConvertFileSize(CommonUtil.formatFileSize(ftpFile.getSize()));
entity.setFileSize(ftpFile.getSize()); entity.setFileSize(ftpFile.getSize());
//if(CheckUtil.checkDPathConflicts(mTaskWrapper.is)) if (DbEntity.checkDataExist(DownloadEntity.class, "downloadPath=?", entity.getFilePath())) {
DbEntity.deleteData(DownloadEntity.class, "downloadPath=?", entity.getFilePath());
}
entity.insert(); entity.insert();
DTaskWrapper subWrapper = new DTaskWrapper(entity); DTaskWrapper subWrapper = new DTaskWrapper(entity);
@ -139,6 +161,21 @@ final class FtpDGInfoTask extends AbsFtpInfoTask<DownloadGroupEntity, DGTaskWrap
subWrapper.setTaskOption(subOption); subWrapper.setTaskOption(subOption);
} }
/**
* 检查子任务是否已经存在如果子任务存在取消添加操作
*
* @param key url
* @return true 子任务已存在false 子任务不存在
*/
private boolean checkEntityExist(String key) {
for (DTaskWrapper wrapper : mTaskWrapper.getSubTaskWrapper()) {
if (wrapper.getKey().equals(key)) {
return true;
}
}
return false;
}
@Override @Override
protected void failDownload(FTPClient client, String msg, Exception e, boolean needRetry) { protected void failDownload(FTPClient client, String msg, Exception e, boolean needRetry) {
super.failDownload(client, msg, e, needRetry); super.failDownload(client, msg, e, needRetry);

@ -26,9 +26,11 @@ import com.arialyy.aria.core.processor.IFtpUploadInterceptor;
import com.arialyy.aria.core.upload.UTaskWrapper; import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.ftp.AbsFtpInfoTask; import com.arialyy.aria.ftp.AbsFtpInfoTask;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.util.DbDataHelper; import com.arialyy.aria.util.DbDataHelper;
import com.arialyy.aria.util.RecordUtil;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -61,7 +63,7 @@ final class FtpUFileInfoTask extends AbsFtpInfoTask<UploadEntity, UTaskWrapper>
try { try {
IFtpUploadInterceptor interceptor = mTaskOption.getUploadInterceptor(); IFtpUploadInterceptor interceptor = mTaskOption.getUploadInterceptor();
if (interceptor != null) { if (interceptor != null) {
/** /*
* true 使用拦截器false 不使用拦截器 * true 使用拦截器false 不使用拦截器
*/ */
List<String> files = new ArrayList<>(); List<String> files = new ArrayList<>();
@ -84,6 +86,7 @@ final class FtpUFileInfoTask extends AbsFtpInfoTask<UploadEntity, UTaskWrapper>
ALog.d(TAG, ALog.d(TAG,
String.format("删除文件%s,code: %s, msg: %s", b ? "成功" : "失败", client.getReplyCode(), String.format("删除文件%s,code: %s, msg: %s", b ? "成功" : "失败", client.getReplyCode(),
client.getReplyString())); client.getReplyString()));
mTaskOption.setServeFileIsExist(false);
} else if (!TextUtils.isEmpty(interceptHandler.getNewFileName())) { } else if (!TextUtils.isEmpty(interceptHandler.getNewFileName())) {
ALog.i(TAG, String.format("远端已拥有同名文件,将修改remotePath,原文件名:%s,新文件名:%s", ALog.i(TAG, String.format("远端已拥有同名文件,将修改remotePath,原文件名:%s,新文件名:%s",
mEntity.getFileName(), interceptHandler.getNewFileName())); mEntity.getFileName(), interceptHandler.getNewFileName()));
@ -92,6 +95,7 @@ final class FtpUFileInfoTask extends AbsFtpInfoTask<UploadEntity, UTaskWrapper>
+ interceptHandler.getNewFileName(); + interceptHandler.getNewFileName();
mTaskOption.setNewFileName(interceptHandler.getNewFileName()); mTaskOption.setNewFileName(interceptHandler.getNewFileName());
mTaskOption.setServeFileIsExist(false);
closeClient(client); closeClient(client);
run(); run();
return false; return false;
@ -156,7 +160,39 @@ final class FtpUFileInfoTask extends AbsFtpInfoTask<UploadEntity, UTaskWrapper>
record.save(); record.save();
threadRecord.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<ThreadRecord> threadRecords = record.threadRecords;
if (threadRecords != null && !threadRecords.isEmpty()){
for (ThreadRecord tr : threadRecords){
tr.deleteData();
}
} }
record.deleteData();
} }
@Override protected void onPreComplete(int code) { @Override protected void onPreComplete(int code) {

@ -130,9 +130,10 @@ final class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
if (isTimeOut) { if (isTimeOut) {
fail(new AriaIOException(TAG, "socket连接失败,该问题一般出现于网络断开,客户端重新连接," fail(new AriaIOException(TAG, "socket连接失败,该问题一般出现于网络断开,客户端重新连接,"
+ "但是服务器端无法创建socket缺没有返回错误码的情况。"), false); + "但是服务器端无法创建socket缺没有返回错误码的情况。"), false);
} if (fa != null) {
if (fa != null) { fa.close();
fa.close(); }
closeTimer();
} }
isTimeOut = true; isTimeOut = true;
} catch (IOException e) { } catch (IOException e) {
@ -143,6 +144,7 @@ final class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
} }
private void closeTimer() { private void closeTimer() {
ALog.d(TAG, "closeTimer");
if (timer != null && !timer.isShutdown()) { if (timer != null && !timer.isShutdown()) {
timer.shutdown(); timer.shutdown();
} }
@ -158,6 +160,7 @@ final class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
fa = new FtpFISAdapter(bis); fa = new FtpFISAdapter(bis);
storeFail = false; storeFail = false;
startTimer(); startTimer();
final long fileSize = getThreadConfig().tempFile.length();
try { try {
ALog.d(TAG, String.format("remotePath: %s", remotePath)); ALog.d(TAG, String.format("remotePath: %s", remotePath));
client.storeFile(remotePath, fa, new OnFtpInputStreamListener() { client.storeFile(remotePath, fa, new OnFtpInputStreamListener() {
@ -170,6 +173,7 @@ final class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
if (getThreadTask().isBreak() && !isStoped) { if (getThreadTask().isBreak() && !isStoped) {
isStoped = true; isStoped = true;
client.abor(); client.abor();
return;
} }
if (mSpeedBandUtil != null) { if (mSpeedBandUtil != null) {
mSpeedBandUtil.limitNextBytes(bytesTransferred); mSpeedBandUtil.limitNextBytes(bytesTransferred);
@ -178,19 +182,12 @@ final class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
storeFail = true; storeFail = true;
try {
fa.close();
} catch (IOException e1) {
e1.printStackTrace();
}
closeClient(client);
} }
} }
}); });
} catch (IOException e) { } catch (IOException e) {
String msg = String.format("文件上传错误,错误码为:%s, msg:%s, filePath: %s", client.getReply(), String msg = String.format("文件上传错误,错误码为:%s, msg:%s, filePath: %s", client.getReply(),
client.getReplyString(), getEntity().getFilePath()); client.getReplyString(), getEntity().getFilePath());
closeClient(client);
e.printStackTrace(); e.printStackTrace();
if (e.getMessage().contains("AriaIOException caught while copying")) { if (e.getMessage().contains("AriaIOException caught while copying")) {
e.printStackTrace(); e.printStackTrace();
@ -198,11 +195,14 @@ final class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
fail(new AriaIOException(TAG, msg, e), !storeFail); fail(new AriaIOException(TAG, msg, e), !storeFail);
} }
return false; return false;
} finally {
fa.close();
closeClient(client);
} }
if (storeFail) { if (storeFail) {
return false; return false;
} }
int reply = client.getReply(); int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) { if (!FTPReply.isPositiveCompletion(reply)) {
if (reply != FTPReply.TRANSFER_ABORTED) { if (reply != FTPReply.TRANSFER_ABORTED) {
fail(new AriaIOException(TAG, fail(new AriaIOException(TAG,

@ -53,7 +53,7 @@ public class DownloadGroupEntity extends AbsGroupEntity {
getSubEntities().get(0).getUrl())) { getSubEntities().get(0).getUrl())) {
return ITaskWrapper.ERROR; 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; : ITaskWrapper.DG_HTTP;
} }

@ -267,7 +267,8 @@ public abstract class AbsGroupLoader implements ILoaderVisitor, ILoader {
Looper looper = Looper.myLooper(); Looper looper = Looper.myLooper();
initState(looper); initState(looper);
getState().setSubSize(getWrapper().getSubTaskWrapper().size()); getState().setSubSize(getWrapper().getSubTaskWrapper().size());
if (getState().getCompleteNum() == getState().getSubSize()) { if (getState().getCompleteNum() != 0
&& getState().getCompleteNum() == getState().getSubSize()) {
mListener.onComplete(); mListener.onComplete();
return; return;
} }

@ -16,6 +16,7 @@
package com.arialyy.aria.core.group; package com.arialyy.aria.core.group;
import android.os.Handler; import android.os.Handler;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.download.DTaskWrapper; import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.inf.IUtil; import com.arialyy.aria.core.inf.IUtil;
@ -81,6 +82,10 @@ public abstract class AbsSubDLoadUtil implements IUtil, Runnable {
return mWrapper.getEntity(); return mWrapper.getEntity();
} }
public TaskRecord getRecord(){
return getLoader().getRecord();
}
@Override public void run() { @Override public void run() {
if (isStop || isCancel) { if (isStop || isCancel) {
return; return;

@ -23,7 +23,7 @@ import java.util.Set;
/** /**
* 组合任务执行中的状态信息 * 组合任务执行中的状态信息
*/ */
public class GroupRunState { public final class GroupRunState {
/** /**
* 子任务数 * 子任务数
*/ */

@ -22,7 +22,7 @@ import com.arialyy.aria.core.task.AbsGroupTask;
* Created by lyy on 2017/9/8. * Created by lyy on 2017/9/8.
* 任务组参数传递 * 任务组参数传递
*/ */
public class GroupSendParams<GROUP_TASK extends AbsGroupTask, ENTITY extends AbsNormalEntity> { public final class GroupSendParams<GROUP_TASK extends AbsGroupTask, ENTITY extends AbsNormalEntity> {
public GROUP_TASK groupTask; public GROUP_TASK groupTask;
public ENTITY entity; public ENTITY entity;

@ -20,21 +20,20 @@ import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
import com.arialyy.aria.core.AriaConfig; 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.config.Configuration;
import com.arialyy.aria.core.inf.IThreadStateManager; 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.core.manager.ThreadTaskManager;
import com.arialyy.aria.exception.TaskException; import com.arialyy.aria.exception.TaskException;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.NetUtils; import com.arialyy.aria.util.NetUtils;
import java.util.concurrent.ScheduledThreadPoolExecutor; import java.io.File;
import java.util.concurrent.TimeUnit;
/** /**
* 组合任务子任务调度器用于调度任务的开始停止失败完成等情况 * 组合任务子任务调度器用于调度任务的开始停止失败完成等情况
* 该调度器生命周期和{@link AbsGroupLoaderUtil}生命周期一致 * 该调度器生命周期和{@link AbsGroupLoaderUtil}生命周期一致
*/ */
class SimpleSchedulers implements Handler.Callback { final class SimpleSchedulers implements Handler.Callback {
private static final String TAG = "SimpleSchedulers"; private static final String TAG = "SimpleSchedulers";
private SimpleSubQueue mQueue; private SimpleSubQueue mQueue;
private GroupRunState mGState; private GroupRunState mGState;
@ -86,7 +85,8 @@ class SimpleSchedulers implements Handler.Callback {
ThreadTaskManager.getInstance().removeSingleTaskThread(mKey, threadName); ThreadTaskManager.getInstance().removeSingleTaskThread(mKey, threadName);
break; break;
case IThreadStateManager.STATE_FAIL: case IThreadStateManager.STATE_FAIL:
handleFail(loaderUtil); boolean needRetry = b.getBoolean(IThreadStateManager.DATA_RETRY, false);
handleFail(loaderUtil, needRetry);
ThreadTaskManager.getInstance().removeSingleTaskThread(mKey, threadName); ThreadTaskManager.getInstance().removeSingleTaskThread(mKey, threadName);
break; break;
} }
@ -98,18 +98,19 @@ class SimpleSchedulers implements Handler.Callback {
* 1子任务失败次数大于等于配置的重试次数才能认为子任务停止 * 1子任务失败次数大于等于配置的重试次数才能认为子任务停止
* 2stopNum + failNum + completeNum + cacheNum == subSize则认为组合任务停止 * 2stopNum + failNum + completeNum + cacheNum == subSize则认为组合任务停止
* 3failNum == subSize只有全部的子任务都失败了才能任务组合任务失败 * 3failNum == 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(); Configuration config = Configuration.getInstance();
long interval = config.dGroupCfg.getSubReTryInterval();
int num = config.dGroupCfg.getSubReTryNum(); int num = config.dGroupCfg.getSubReTryNum();
boolean isNotNetRetry = config.appCfg.isNotNetRetry(); boolean isNotNetRetry = config.appCfg.isNotNetRetry();
final int reTryNum = num; if (!needRetry
if ((!NetUtils.isConnected(AriaConfig.getInstance().getAPP()) && !isNotNetRetry) || (!NetUtils.isConnected(AriaConfig.getInstance().getAPP()) && !isNotNetRetry)
|| loaderUtil.getLoader() == null // 如果获取不到文件信息,loader为空 || loaderUtil.getLoader() == null // 如果获取不到文件信息,loader为空
|| loaderUtil.getEntity().getFailNum() > reTryNum) { || loaderUtil.getEntity().getFailNum() > num) {
mQueue.removeTaskFromExecQ(loaderUtil); mQueue.removeTaskFromExecQ(loaderUtil);
mGState.listener.onSubFail(loaderUtil.getEntity(), new TaskException(TAG, mGState.listener.onSubFail(loaderUtil.getEntity(), new TaskException(TAG,
String.format("任务组子任务【%s】下载失败,下载地址【%s】", loaderUtil.getEntity().getFileName(), String.format("任务组子任务【%s】下载失败,下载地址【%s】", loaderUtil.getEntity().getFileName(),
@ -127,20 +128,7 @@ class SimpleSchedulers implements Handler.Callback {
} }
return; return;
} }
SimpleSubRetryQueue.getInstance().offer(loaderUtil);
// 如果获取不到文件信息,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);
} }
/** /**
@ -175,6 +163,11 @@ class SimpleSchedulers implements Handler.Callback {
*/ */
private synchronized void handleComplete(AbsSubDLoadUtil loader) { private synchronized void handleComplete(AbsSubDLoadUtil loader) {
ALog.d(TAG, String.format("子任务【%s】完成", loader.getEntity().getFileName())); 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()); ThreadTaskManager.getInstance().removeTaskThread(loader.getKey());
mGState.listener.onSubComplete(loader.getEntity()); mGState.listener.onSubComplete(loader.getEntity());
mQueue.removeTaskFromExecQ(loader); mQueue.removeTaskFromExecQ(loader);

@ -29,7 +29,7 @@ import java.util.Set;
/** /**
* 组合任务队列该队列生命周期和{@link AbsGroupLoaderUtil}生命周期一致 * 组合任务队列该队列生命周期和{@link AbsGroupLoaderUtil}生命周期一致
*/ */
class SimpleSubQueue implements ISubQueue<AbsSubDLoadUtil> { final class SimpleSubQueue implements ISubQueue<AbsSubDLoadUtil> {
private final String TAG = CommonUtil.getClassName(getClass()); private final String TAG = CommonUtil.getClassName(getClass());
/** /**
* 缓存下载器 * 缓存下载器

@ -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<Runnable>());
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());
}
}

@ -1,6 +1,8 @@
package com.arialyy.aria.core.loader; package com.arialyy.aria.core.loader;
import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Message;
import com.arialyy.aria.core.TaskRecord; import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.ThreadRecord; import com.arialyy.aria.core.ThreadRecord;
import com.arialyy.aria.core.common.AbsNormalEntity; import com.arialyy.aria.core.common.AbsNormalEntity;
@ -133,7 +135,16 @@ public abstract class AbsNormalTTBuilder implements IThreadTaskBuilder {
if (tr.isComplete) {//该线程已经完成 if (tr.isComplete) {//该线程已经完成
currentProgress += endL - startL; currentProgress += endL - startL;
ALog.d(TAG, String.format("任务【%s】线程__%s__已完成", mWrapper.getKey(), i)); 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; continue;
} }

@ -48,6 +48,7 @@ public final class SubLoader implements ILoader, ILoaderVisitor {
private IRecordHandler recordHandler; private IRecordHandler recordHandler;
private IThreadTask threadTask; private IThreadTask threadTask;
private String parentKey; private String parentKey;
private TaskRecord record;
public SubLoader(AbsTaskWrapper wrapper, Handler schedulers) { public SubLoader(AbsTaskWrapper wrapper, Handler schedulers) {
this.wrapper = wrapper; this.wrapper = wrapper;
@ -92,7 +93,7 @@ public final class SubLoader implements ILoader, ILoaderVisitor {
} }
private void handlerTask() { private void handlerTask() {
TaskRecord record = recordHandler.getRecord(wrapper.getEntity().getFileSize()); record = recordHandler.getRecord(wrapper.getEntity().getFileSize());
if (record.threadRecords != null if (record.threadRecords != null
&& !TextUtils.isEmpty(record.filePath) && !TextUtils.isEmpty(record.filePath)
&& new File(record.filePath).exists() && 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) { public void setParentKey(String parentKey) {
this.parentKey = parentKey; this.parentKey = parentKey;
} }

@ -86,11 +86,17 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
mEntity = mTaskWrapper.getEntity(); mEntity = mTaskWrapper.getEntity();
mLastSaveTime = System.currentTimeMillis(); mLastSaveTime = System.currentTimeMillis();
mConfigThreadPool = Executors.newCachedThreadPool(); mConfigThreadPool = Executors.newCachedThreadPool();
isNotNetRetry = AriaConfig.getInstance().getAConfig().isNotNetRetry(); isNotNetRetry = AriaConfig.getInstance().getAConfig().isNotNetRetry();
mRangeProgress = mRecord.startLocation; mRangeProgress = mRecord.startLocation;
mLastRangeProgress = mRangeProgress; mLastRangeProgress = mRangeProgress;
updateInterval = config.updateInterval; updateInterval = config.updateInterval;
checkFileExist();
}
private void checkFileExist() {
if (!getConfig().tempFile.exists()) {
FileUtil.createFile(getConfig().tempFile);
}
} }
/** /**

@ -98,7 +98,7 @@ class DelegateFind extends AbsDelegate {
*/ */
<T extends AbsDbWrapper> List<T> findRelationData(SQLiteDatabase db, Class<T> clazz, <T extends AbsDbWrapper> List<T> findRelationData(SQLiteDatabase db, Class<T> clazz,
String... expression) { String... expression) {
return exeRelationSql(db, clazz, -1, -1, expression); return exeRelationSql(db, clazz, 1, 10, expression);
} }
/** /**
@ -111,6 +111,7 @@ class DelegateFind extends AbsDelegate {
<T extends AbsDbWrapper> List<T> findRelationData(SQLiteDatabase db, Class<T> clazz, <T extends AbsDbWrapper> List<T> findRelationData(SQLiteDatabase db, Class<T> clazz,
int page, int num, String... expression) { int page, int num, String... expression) {
if (page < 1 || num < 1) { if (page < 1 || num < 1) {
ALog.w(TAG, "page,num 小于1");
return null; return null;
} }
return exeRelationSql(db, clazz, page, num, expression); return exeRelationSql(db, clazz, page, num, expression);
@ -345,6 +346,7 @@ class DelegateFind extends AbsDelegate {
<T extends DbEntity> List<T> findData(SQLiteDatabase db, Class<T> clazz, int page, int num, <T extends DbEntity> List<T> findData(SQLiteDatabase db, Class<T> clazz, int page, int num,
String... expression) { String... expression) {
if (page < 1 || num < 1) { if (page < 1 || num < 1) {
ALog.w(TAG, "page, bum 小于1");
return null; return null;
} }
db = checkDb(db); db = checkDb(db);
@ -390,6 +392,7 @@ class DelegateFind extends AbsDelegate {
<T extends DbEntity> List<T> findDataByFuzzy(SQLiteDatabase db, Class<T> clazz, <T extends DbEntity> List<T> findDataByFuzzy(SQLiteDatabase db, Class<T> clazz,
int page, int num, String conditions) { int page, int num, String conditions) {
if (page < 1 || num < 1) { if (page < 1 || num < 1) {
ALog.w(TAG, "page, bum 小于1");
return null; return null;
} }
db = checkDb(db); db = checkDb(db);

@ -65,6 +65,15 @@ public class RecordUtil {
return; return;
} }
DownloadGroupEntity groupEntity = DbDataHelper.getDGEntityByPath(dirPath); 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); delGroupTaskRecord(groupEntity, removeFile, true);
} }

@ -37,7 +37,7 @@ import java.security.AlgorithmConstraints;
* Created by lyy on 2017/7/6. * Created by lyy on 2017/7/6.
*/ */
public class FTPDirDownloadActivity extends BaseActivity<ActivityDownloadGroupBinding> { public class FTPDirDownloadActivity extends BaseActivity<ActivityDownloadGroupBinding> {
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 SubStateLinearLayout mChildList;
private long mTaskId = -1; private long mTaskId = -1;
@ -81,6 +81,7 @@ public class FTPDirDownloadActivity extends BaseActivity<ActivityDownloadGroupBi
Environment.getExternalStorageDirectory().getPath() + "/Download/ftp_dir") Environment.getExternalStorageDirectory().getPath() + "/Download/ftp_dir")
.setGroupAlias("ftp文件夹下载") .setGroupAlias("ftp文件夹下载")
.option(getFtpOption()) .option(getFtpOption())
.ignoreFilePathOccupy()
.create(); .create();
getBinding().setStateStr(getString(R.string.stop)); getBinding().setStateStr(getString(R.string.stop));
break; break;
@ -124,6 +125,7 @@ public class FTPDirDownloadActivity extends BaseActivity<ActivityDownloadGroupBi
} }
@DownloadGroup.onTaskRunning() protected void running(DownloadGroupTask task) { @DownloadGroup.onTaskRunning() protected void running(DownloadGroupTask task) {
ALog.d(TAG, "ftp dir running, p = " + task.getPercent());
getBinding().setProgress(task.getPercent()); getBinding().setProgress(task.getPercent());
getBinding().setSpeed(task.getConvertSpeed()); getBinding().setSpeed(task.getConvertSpeed());
mChildList.updateChildProgress(task.getEntity().getSubEntities()); mChildList.updateChildProgress(task.getEntity().getSubEntities());
@ -135,6 +137,7 @@ public class FTPDirDownloadActivity extends BaseActivity<ActivityDownloadGroupBi
@DownloadGroup.onTaskStop() void taskStop(DownloadGroupTask task) { @DownloadGroup.onTaskStop() void taskStop(DownloadGroupTask task) {
getBinding().setSpeed(""); getBinding().setSpeed("");
getBinding().setStateStr(getString(R.string.start));
} }
@DownloadGroup.onTaskCancel() void taskCancel(DownloadGroupTask task) { @DownloadGroup.onTaskCancel() void taskCancel(DownloadGroupTask task) {

@ -55,8 +55,7 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
private String mUrl; private String mUrl;
private UploadModule mModule; private UploadModule mModule;
private long mTaskId = -1; 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) { @Override protected void init(Bundle savedInstanceState) {
setTile("D_FTP 文件上传"); setTile("D_FTP 文件上传");

@ -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 url = AppUtil.getConfigValue(context, FTP_URL_KEY, "ftp://9.9.9.72:2121/aab/你好");
//String filePath = AppUtil.getConfigValue(context, FTP_PATH_KEY, //String filePath = AppUtil.getConfigValue(context, FTP_PATH_KEY,
// Environment.getExternalStorageDirectory().getPath() + "/Download/AndroidAria.db"); // 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"; String filePath = "/mnt/sdcard/QQMusic-import-1.2.1.zip";
UploadEntity entity = Aria.upload(context).getFirstUploadEntity(filePath); UploadEntity entity = Aria.upload(context).getFirstUploadEntity(filePath);

Loading…
Cancel
Save