修复ftp服务器无法响应`abor`命令导致的无法停止上传的问题

修复ftp上传时,服务器有长度为0的文件导致上传失败的问题
修复下载任务和上传任务的文件路径是同一个时,导致的记录混乱问题
pull/617/head 3.8
laoyuyu 5 years ago
parent 0d93953cd9
commit 27c889e171
  1. 4
      Aria/src/main/java/com/arialyy/aria/core/download/CheckDEntityUtil.java
  2. 2
      Aria/src/main/java/com/arialyy/aria/core/download/CheckDGEntityUtil.java
  3. 1
      Aria/src/main/java/com/arialyy/aria/core/download/target/FtpBuilderTarget.java
  4. 3
      Aria/src/main/java/com/arialyy/aria/core/download/target/FtpDirConfigHandler.java
  5. 2
      Aria/src/main/java/com/arialyy/aria/core/download/target/HttpBuilderTarget.java
  6. 2
      Aria/src/main/java/com/arialyy/aria/core/download/target/HttpGroupConfigHandler.java
  7. 2
      Aria/src/main/java/com/arialyy/aria/core/download/target/TcpBuilderTarget.java
  8. 5
      Aria/src/main/java/com/arialyy/aria/core/manager/DTaskWrapperFactory.java
  9. 2
      Aria/src/main/java/com/arialyy/aria/core/upload/target/FtpBuilderTarget.java
  10. 6
      Aria/src/main/java/com/arialyy/aria/core/upload/target/HttpBuilderTarget.java
  11. 7
      DEV_LOG.md
  12. 7
      FtpComponent/src/main/java/com/arialyy/aria/ftp/AbsFtpInfoThread.java
  13. 4
      FtpComponent/src/main/java/com/arialyy/aria/ftp/FtpRecordAdapter.java
  14. 4
      FtpComponent/src/main/java/com/arialyy/aria/ftp/download/FtpDThreadTaskAdapter.java
  15. 22
      FtpComponent/src/main/java/com/arialyy/aria/ftp/upload/FtpUFileInfoThread.java
  16. 31
      FtpComponent/src/main/java/com/arialyy/aria/ftp/upload/FtpUThreadTaskAdapter.java
  17. 2
      HttpComponent/src/main/java/com/arialyy/aria/http/HttpFileInfoThread.java
  18. 4
      HttpComponent/src/main/java/com/arialyy/aria/http/HttpRecordAdapter.java
  19. 4
      HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDThreadTaskAdapter.java
  20. 10
      M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8RecordAdapter.java
  21. 2
      M3U8Component/src/main/java/com/arialyy/aria/m3u8/live/M3U8LiveLoader.java
  22. 12
      PublicComponent/src/main/java/com/arialyy/aria/core/TaskRecord.java
  23. 3
      PublicComponent/src/main/java/com/arialyy/aria/core/ThreadRecord.java
  24. 15
      PublicComponent/src/main/java/com/arialyy/aria/core/common/AbsNormalEntity.java
  25. 6
      PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHandler.java
  26. 32
      PublicComponent/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java
  27. 4
      PublicComponent/src/main/java/com/arialyy/aria/core/download/M3U8Entity.java
  28. 14
      PublicComponent/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java
  29. 11
      PublicComponent/src/main/java/com/arialyy/aria/orm/AbsDelegate.java
  30. 2
      PublicComponent/src/main/java/com/arialyy/aria/orm/DBConfig.java
  31. 2
      PublicComponent/src/main/java/com/arialyy/aria/orm/DelegateCommon.java
  32. 4
      PublicComponent/src/main/java/com/arialyy/aria/orm/DelegateFind.java
  33. 4
      PublicComponent/src/main/java/com/arialyy/aria/orm/DelegateUpdate.java
  34. 80
      PublicComponent/src/main/java/com/arialyy/aria/orm/SqlHelper.java
  35. 12
      PublicComponent/src/main/java/com/arialyy/aria/orm/SqlUtil.java
  36. 11
      PublicComponent/src/main/java/com/arialyy/aria/util/CheckUtil.java
  37. 20
      PublicComponent/src/main/java/com/arialyy/aria/util/DbDataHelper.java
  38. 8
      PublicComponent/src/main/java/com/arialyy/aria/util/RecordUtil.java
  39. 38
      README.md
  40. 15
      app/src/main/java/com/arialyy/simple/core/upload/FtpUploadActivity.java
  41. 9
      app/src/main/java/com/arialyy/simple/core/upload/UploadModule.java
  42. 10
      app/src/main/res/layout/activity_ftp_upload.xml
  43. 2
      build.gradle

@ -157,11 +157,11 @@ public class CheckDEntityUtil implements ICheckEntityUtil {
File oldFile = new File(mEntity.getFilePath()); File oldFile = new File(mEntity.getFilePath());
if (oldFile.exists()) { if (oldFile.exists()) {
// 处理普通任务的重命名 // 处理普通任务的重命名
RecordUtil.modifyTaskRecord(oldFile.getPath(), newFile.getPath()); RecordUtil.modifyTaskRecord(oldFile.getPath(), newFile.getPath(), mEntity.getTaskType());
ALog.i(TAG, String.format("将任务重命名为:%s", newFile.getName())); ALog.i(TAG, String.format("将任务重命名为:%s", newFile.getName()));
} else if (RecordUtil.blockTaskExists(oldFile.getPath())) { } else if (RecordUtil.blockTaskExists(oldFile.getPath())) {
// 处理分块任务的重命名 // 处理分块任务的重命名
RecordUtil.modifyTaskRecord(oldFile.getPath(), newFile.getPath()); RecordUtil.modifyTaskRecord(oldFile.getPath(), newFile.getPath(), mEntity.getTaskType());
ALog.i(TAG, String.format("将分块任务重命名为:%s", newFile.getName())); ALog.i(TAG, String.format("将分块任务重命名为:%s", newFile.getName()));
} }
} }

@ -179,7 +179,7 @@ public class CheckDGEntityUtil implements ICheckEntityUtil {
return; return;
} }
RecordUtil.modifyTaskRecord(oldPath, newPath); RecordUtil.modifyTaskRecord(oldPath, newPath, mEntity.getTaskType());
entity.setFilePath(newPath); entity.setFilePath(newPath);
entity.setFileName(newName); entity.setFileName(newName);
} }

@ -31,6 +31,7 @@ public class FtpBuilderTarget extends AbsBuilderTarget<FtpBuilderTarget> {
mConfigHandler = new DNormalConfigHandler<>(this, -1); mConfigHandler = new DNormalConfigHandler<>(this, -1);
mConfigHandler.setUrl(url); mConfigHandler.setUrl(url);
getTaskWrapper().setRequestType(ITaskWrapper.D_FTP); getTaskWrapper().setRequestType(ITaskWrapper.D_FTP);
getEntity().setTaskType(ITaskWrapper.D_FTP);
getTaskWrapper().setNewTask(true); getTaskWrapper().setNewTask(true);
} }

@ -33,11 +33,12 @@ class FtpDirConfigHandler<TARGET extends AbsTarget> extends AbsGroupConfigHandle
} }
private void init() { private void init() {
getTaskWrapper().setRequestType(AbsTaskWrapper.D_FTP_DIR); getTaskWrapper().setRequestType(ITaskWrapper.D_FTP_DIR);
List<DTaskWrapper> wrappers = getTaskWrapper().getSubTaskWrapper(); List<DTaskWrapper> wrappers = getTaskWrapper().getSubTaskWrapper();
if (!wrappers.isEmpty()) { if (!wrappers.isEmpty()) {
for (DTaskWrapper subWrapper : wrappers) { for (DTaskWrapper subWrapper : wrappers) {
subWrapper.setRequestType(ITaskWrapper.D_FTP); subWrapper.setRequestType(ITaskWrapper.D_FTP);
subWrapper.getEntity().setTaskType(ITaskWrapper.D_FTP);
} }
} }
} }

@ -18,6 +18,7 @@ package com.arialyy.aria.core.download.target;
import com.arialyy.aria.core.common.AbsBuilderTarget; import com.arialyy.aria.core.common.AbsBuilderTarget;
import com.arialyy.aria.core.common.HttpOption; import com.arialyy.aria.core.common.HttpOption;
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.m3u8.M3U8LiveOption; import com.arialyy.aria.core.download.m3u8.M3U8LiveOption;
import com.arialyy.aria.core.download.m3u8.M3U8VodOption; import com.arialyy.aria.core.download.m3u8.M3U8VodOption;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper; import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
@ -32,6 +33,7 @@ public class HttpBuilderTarget extends AbsBuilderTarget<HttpBuilderTarget> {
mConfigHandler.setUrl(url); mConfigHandler.setUrl(url);
getTaskWrapper().setRequestType(ITaskWrapper.D_HTTP); getTaskWrapper().setRequestType(ITaskWrapper.D_HTTP);
getTaskWrapper().setNewTask(true); getTaskWrapper().setNewTask(true);
((DownloadEntity)getEntity()).setTaskType(ITaskWrapper.D_HTTP);
} }
public HttpBuilderTarget m3u8VodOption(M3U8VodOption m3U8VodOption) { public HttpBuilderTarget m3u8VodOption(M3U8VodOption m3U8VodOption) {

@ -18,6 +18,7 @@ package com.arialyy.aria.core.download.target;
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.AbsTarget; import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.orm.DbEntity; 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;
@ -58,6 +59,7 @@ class HttpGroupConfigHandler<TARGET extends AbsTarget> extends AbsGroupConfigHan
List<DownloadEntity> subEntities = DbDataHelper.createHttpSubTask(groupHash, mUrls); List<DownloadEntity> subEntities = DbDataHelper.createHttpSubTask(groupHash, mUrls);
List<DTaskWrapper> wrappers = new ArrayList<>(); List<DTaskWrapper> wrappers = new ArrayList<>();
for (DownloadEntity subEntity : subEntities) { for (DownloadEntity subEntity : subEntities) {
subEntity.setTaskType(ITaskWrapper.D_HTTP);
wrappers.add(new DTaskWrapper(subEntity)); wrappers.add(new DTaskWrapper(subEntity));
} }
getEntity().setUrls(urls); getEntity().setUrls(urls);

@ -16,6 +16,7 @@
package com.arialyy.aria.core.download.target; package com.arialyy.aria.core.download.target;
import com.arialyy.aria.core.common.AbsBuilderTarget; import com.arialyy.aria.core.common.AbsBuilderTarget;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.wrapper.ITaskWrapper; import com.arialyy.aria.core.wrapper.ITaskWrapper;
/** /**
@ -29,6 +30,7 @@ public class TcpBuilderTarget extends AbsBuilderTarget<TcpBuilderTarget> {
TcpBuilderTarget(String ip, int port) { TcpBuilderTarget(String ip, int port) {
mConfigHandler = new DNormalConfigHandler<>(this, -1); mConfigHandler = new DNormalConfigHandler<>(this, -1);
getTaskWrapper().setRequestType(ITaskWrapper.D_TCP); getTaskWrapper().setRequestType(ITaskWrapper.D_TCP);
((DownloadEntity) getEntity()).setTaskType(ITaskWrapper.D_TCP);
getTaskWrapper().setNewTask(true); getTaskWrapper().setNewTask(true);
} }
// //

@ -20,6 +20,7 @@ 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.IEntity; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.IRecordHandler; import com.arialyy.aria.core.inf.IRecordHandler;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import java.io.File; import java.io.File;
/** /**
@ -71,7 +72,7 @@ class DTaskWrapperFactory implements INormalTEFactory<DownloadEntity, DTaskWrapp
if (!entity.isComplete()) { if (!entity.isComplete()) {
TaskRecord record = TaskRecord record =
TaskRecord.findFirst(TaskRecord.class, "filePath=?", entity.getDownloadPath()); TaskRecord.findFirst(TaskRecord.class, "filePath=?", entity.getFilePath());
if (record == null) { if (record == null) {
resetEntity(entity); resetEntity(entity);
} else { } else {
@ -87,7 +88,7 @@ class DTaskWrapperFactory implements INormalTEFactory<DownloadEntity, DTaskWrapp
resetEntity(entity); resetEntity(entity);
} }
} else if (!file.exists() } else if (!file.exists()
&& record.taskType != TaskRecord.TYPE_M3U8_VOD) { // 非分块文件需要判断文件是否存在 && record.taskType != ITaskWrapper.M3U8_VOD) { // 非分块文件需要判断文件是否存在
resetEntity(entity); resetEntity(entity);
} }
} }

@ -17,6 +17,7 @@ package com.arialyy.aria.core.upload.target;
import com.arialyy.aria.core.common.AbsBuilderTarget; import com.arialyy.aria.core.common.AbsBuilderTarget;
import com.arialyy.aria.core.common.FtpOption; import com.arialyy.aria.core.common.FtpOption;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.wrapper.ITaskWrapper; import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
@ -32,6 +33,7 @@ public class FtpBuilderTarget extends AbsBuilderTarget<FtpBuilderTarget> {
mConfigHandler = new UNormalConfigHandler<>(this, -1); mConfigHandler = new UNormalConfigHandler<>(this, -1);
mConfigHandler.setFilePath(filePath); mConfigHandler.setFilePath(filePath);
getTaskWrapper().setRequestType(ITaskWrapper.U_FTP); getTaskWrapper().setRequestType(ITaskWrapper.U_FTP);
((UploadEntity)getEntity()).setTaskType(ITaskWrapper.U_FTP);
getTaskWrapper().setNewTask(true); getTaskWrapper().setNewTask(true);
} }

@ -17,7 +17,8 @@ package com.arialyy.aria.core.upload.target;
import com.arialyy.aria.core.common.AbsBuilderTarget; import com.arialyy.aria.core.common.AbsBuilderTarget;
import com.arialyy.aria.core.common.HttpOption; import com.arialyy.aria.core.common.HttpOption;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper; import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
/** /**
* Created by lyy on 2017/2/28. * Created by lyy on 2017/2/28.
@ -31,7 +32,8 @@ public class HttpBuilderTarget extends AbsBuilderTarget<HttpBuilderTarget> {
mConfigHandler.setFilePath(filePath); mConfigHandler.setFilePath(filePath);
//http暂时不支持断点上传 //http暂时不支持断点上传
getTaskWrapper().setSupportBP(false); getTaskWrapper().setSupportBP(false);
getTaskWrapper().setRequestType(AbsTaskWrapper.U_HTTP); getTaskWrapper().setRequestType(ITaskWrapper.U_HTTP);
((UploadEntity) getEntity()).setTaskType(ITaskWrapper.U_HTTP);
getTaskWrapper().setNewTask(true); getTaskWrapper().setNewTask(true);
} }

@ -1,13 +1,16 @@
## 开发日志 ## 开发日志
+ v_3.8 + v_3.8 (2019/12/17)
- 移除androidx和support的依赖,现在无论是哪个版本的appcompat包都可以使用本框架 - 移除androidx和support的依赖,现在无论是哪个版本的appcompat包都可以使用本框架
- 修复一个在xml中使用fragment导致的内存泄漏问题 - 修复一个在xml中使用fragment导致的内存泄漏问题
- m3u8协议的key信息增加了`keyFormat`,`keyFormatVersion`字段 - m3u8协议的key信息增加了`keyFormat`,`keyFormatVersion`字段
- m3u8增加了`ignoreFailureTs`方法,忽略虾类失败的ts切片 - m3u8增加了`ignoreFailureTs`方法,忽略下载失败的ts切片
- 修复在dialogFragment的`onCreateDialog()`注册导致的注解不生效问题 - 修复在dialogFragment的`onCreateDialog()`注册导致的注解不生效问题
- 修复组合任务初始化失败时,无法删除的问题 - 修复组合任务初始化失败时,无法删除的问题
- 修复`reStart()`后,无法停止的问题 - 修复`reStart()`后,无法停止的问题
- ftp增加主动模式,开启主动模式:https://aria.laoyuyu.me/aria_doc/api/ftp_params.html - ftp增加主动模式,开启主动模式:https://aria.laoyuyu.me/aria_doc/api/ftp_params.html
- 修复ftp服务器无法响应`abor`命令导致的无法停止上传的问题 https://github.com/AriaLyy/Aria/issues/564
- 修复ftp上传时,服务器有长度为0的文件导致上传失败的问题
- 修复下载任务和上传任务的文件路径是同一个时,导致的记录混乱问题
- 优化提示 - 优化提示
+ v_3.7.10 (2019/12/3) + v_3.7.10 (2019/12/3)
- fix bug https://github.com/AriaLyy/Aria/issues/543#issuecomment-559733124 - fix bug https://github.com/AriaLyy/Aria/issues/543#issuecomment-559733124

@ -50,7 +50,7 @@ import javax.net.ssl.SSLContext;
public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_WRAPPER extends AbsTaskWrapper<ENTITY>> public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_WRAPPER extends AbsTaskWrapper<ENTITY>>
implements Runnable { implements Runnable {
private final String TAG = CommonUtil.getClassName(getClass()); protected final String TAG = CommonUtil.getClassName(getClass());
protected ENTITY mEntity; protected ENTITY mEntity;
protected TASK_WRAPPER mTaskWrapper; protected TASK_WRAPPER mTaskWrapper;
protected FtpTaskOption mTaskOption; protected FtpTaskOption mTaskOption;
@ -123,7 +123,7 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_WRAPPER ex
// 处理拦截功能 // 处理拦截功能
if (!onInterceptor(client, files)) { if (!onInterceptor(client, files)) {
closeClient(client); closeClient(client);
ALog.d(TAG, "拦截器处理完成任务,任务将不再执行"); ALog.d(TAG, "拦截器处理完成任务");
return; return;
} }
@ -390,8 +390,7 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_WRAPPER ex
needRetry = needRetry && !CheckUtil.ftpIsBadRequest(client.getReplyCode()); needRetry = needRetry && !CheckUtil.ftpIsBadRequest(client.getReplyCode());
} }
//mCallback.onFail(mEntity, new AriaIOException(TAG, msg), needRetry); mCallback.onFail(mEntity, new AriaIOException(TAG, msg), needRetry);
mCallback.onFail(mEntity, new AriaIOException(TAG, msg, e), false);
} }
} }

@ -58,7 +58,7 @@ public class FtpRecordAdapter extends AbsRecordHandlerAdapter {
tr.threadId = threadId; tr.threadId = threadId;
tr.startLocation = startL; tr.startLocation = startL;
tr.isComplete = false; tr.isComplete = false;
tr.threadType = TaskRecord.TYPE_HTTP_FTP; tr.threadType = getWrapper().getEntity().getTaskType();
//最后一个线程的结束位置即为文件的总长度 //最后一个线程的结束位置即为文件的总长度
if (threadId == (record.threadNum - 1)) { if (threadId == (record.threadNum - 1)) {
endL = getEntity().getFileSize(); endL = getEntity().getFileSize();
@ -81,7 +81,7 @@ public class FtpRecordAdapter extends AbsRecordHandlerAdapter {
} else { } else {
record.isBlock = false; record.isBlock = false;
} }
record.taskType = TaskRecord.TYPE_HTTP_FTP; record.taskType = getWrapper().getEntity().getTaskType();
record.isGroupRecord = getEntity().isGroupChild(); record.isGroupRecord = getEntity().isGroupChild();
if (record.isGroupRecord) { if (record.isGroupRecord) {
if (getEntity() instanceof DownloadEntity) { if (getEntity() instanceof DownloadEntity) {

@ -180,7 +180,9 @@ final class FtpDThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
try { try {
file = file =
new BufferedRandomAccessFile(getThreadConfig().tempFile, "rwd", getTaskConfig().getBuffSize()); new BufferedRandomAccessFile(getThreadConfig().tempFile, "rwd", getTaskConfig().getBuffSize());
file.seek(getThreadRecord().startLocation); if (getThreadRecord().startLocation > 0){
file.seek(getThreadRecord().startLocation);
}
byte[] buffer = new byte[getTaskConfig().getBuffSize()]; byte[] buffer = new byte[getTaskConfig().getBuffSize()];
int len; int len;
while (getThreadTask().isLive() && (len = is.read(buffer)) != -1) { while (getThreadTask().isLive() && (len = is.read(buffer)) != -1) {

@ -22,11 +22,11 @@ import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.ThreadRecord; import com.arialyy.aria.core.ThreadRecord;
import com.arialyy.aria.core.common.CompleteInfo; import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.inf.OnFileInfoCallback; import com.arialyy.aria.core.inf.OnFileInfoCallback;
import com.arialyy.aria.core.processor.FtpInterceptHandler;
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.AbsFtpInfoThread; import com.arialyy.aria.ftp.AbsFtpInfoThread;
import com.arialyy.aria.core.processor.FtpInterceptHandler;
import com.arialyy.aria.core.processor.IFtpUploadInterceptor;
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;
@ -39,7 +39,6 @@ import java.util.List;
* 单任务上传远程服务器文件信息 * 单任务上传远程服务器文件信息
*/ */
class FtpUFileInfoThread extends AbsFtpInfoThread<UploadEntity, UTaskWrapper> { class FtpUFileInfoThread extends AbsFtpInfoThread<UploadEntity, UTaskWrapper> {
private static final String TAG = "FtpUploadFileInfoThread";
static final int CODE_COMPLETE = 0xab1; static final int CODE_COMPLETE = 0xab1;
private boolean isComplete = false; private boolean isComplete = false;
private String remotePath; private String remotePath;
@ -59,10 +58,10 @@ class FtpUFileInfoThread extends AbsFtpInfoThread<UploadEntity, UTaskWrapper> {
@Override protected boolean onInterceptor(FTPClient client, FTPFile[] ftpFiles) { @Override protected boolean onInterceptor(FTPClient client, FTPFile[] ftpFiles) {
// 旧任务将不做处理,否则断点续传上传将失效 // 旧任务将不做处理,否则断点续传上传将失效
if (!mTaskWrapper.isNewTask()) { //if (!mTaskWrapper.isNewTask()) {
ALog.d(TAG, "任务是旧任务,忽略该拦截器"); // ALog.d(TAG, "任务是旧任务,忽略该拦截器");
return true; // return true;
} //}
try { try {
IFtpUploadInterceptor interceptor = mTaskOption.getUploadInterceptor(); IFtpUploadInterceptor interceptor = mTaskOption.getUploadInterceptor();
if (interceptor != null) { if (interceptor != null) {
@ -78,7 +77,7 @@ class FtpUFileInfoThread extends AbsFtpInfoThread<UploadEntity, UTaskWrapper> {
FtpInterceptHandler interceptHandler = interceptor.onIntercept(mEntity, files); FtpInterceptHandler interceptHandler = interceptor.onIntercept(mEntity, files);
/* /*
处理远端有同名文件的情况 * 处理远端有同名文件的情况
*/ */
if (files.contains(mEntity.getFileName())) { if (files.contains(mEntity.getFileName())) {
if (interceptHandler.isCoverServerFile()) { if (interceptHandler.isCoverServerFile()) {
@ -94,6 +93,7 @@ class FtpUFileInfoThread extends AbsFtpInfoThread<UploadEntity, UTaskWrapper> {
+ "/" + "/"
+ interceptHandler.getNewFileName(); + interceptHandler.getNewFileName();
mTaskOption.setNewFileName(interceptHandler.getNewFileName()); mTaskOption.setNewFileName(interceptHandler.getNewFileName());
closeClient(client); closeClient(client);
run(); run();
return false; return false;
@ -123,6 +123,9 @@ class FtpUFileInfoThread extends AbsFtpInfoThread<UploadEntity, UTaskWrapper> {
if (ftpFile.getSize() == mEntity.getFileSize()) { if (ftpFile.getSize() == mEntity.getFileSize()) {
isComplete = true; isComplete = true;
ALog.d(TAG, "FTP服务器上已存在该文件【" + ftpFile.getName() + "】"); ALog.d(TAG, "FTP服务器上已存在该文件【" + ftpFile.getName() + "】");
} else if (ftpFile.getSize() == 0) {
mTaskWrapper.setNewTask(true);
ALog.d(TAG, "FTP服务器上已存在该文件【" + ftpFile.getName() + "】,但文件长度为0,重新上传该文件");
} else { } else {
ALog.w(TAG, "FTP服务器已存在未完成的文件【" ALog.w(TAG, "FTP服务器已存在未完成的文件【"
+ ftpFile.getName() + ftpFile.getName()
@ -135,7 +138,8 @@ class FtpUFileInfoThread extends AbsFtpInfoThread<UploadEntity, UTaskWrapper> {
mTaskWrapper.setNewTask(false); mTaskWrapper.setNewTask(false);
// 修改记录 // 修改记录
TaskRecord record = DbDataHelper.getTaskRecord(mTaskWrapper.getKey()); TaskRecord record = DbDataHelper.getTaskRecord(mTaskWrapper.getKey(),
mTaskWrapper.getEntity().getTaskType());
if (record == null) { if (record == null) {
record = new TaskRecord(); record = new TaskRecord();
record.fileName = mEntity.getFileName(); record.fileName = mEntity.getFileName();

@ -34,6 +34,7 @@ import java.io.UnsupportedEncodingException;
*/ */
class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter { class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
private String dir, remotePath; private String dir, remotePath;
private boolean storeFail = false;
FtpUThreadTaskAdapter(SubThreadConfig config) { FtpUThreadTaskAdapter(SubThreadConfig config) {
super(config); super(config);
@ -67,8 +68,7 @@ class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
file = file =
new BufferedRandomAccessFile(getThreadConfig().tempFile, "rwd", new BufferedRandomAccessFile(getThreadConfig().tempFile, "rwd",
getTaskConfig().getBuffSize()); getTaskConfig().getBuffSize());
if (getThreadRecord().startLocation != 0) { if (getThreadRecord().startLocation > 0) {
//file.skipBytes((int) getThreadConfig().START_LOCATION);
file.seek(getThreadRecord().startLocation); file.seek(getThreadRecord().startLocation);
} }
boolean complete = upload(client, file); boolean complete = upload(client, file);
@ -79,6 +79,7 @@ class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
String.format("任务【%s】线程__%s__上传完毕", getEntity().getKey(), getThreadRecord().threadId)); String.format("任务【%s】线程__%s__上传完毕", getEntity().getKey(), getThreadRecord().threadId));
complete(); complete();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace();
fail(new AriaIOException(TAG, fail(new AriaIOException(TAG,
String.format("上传失败,filePath: %s, uploadUrl: %s", getEntity().getFilePath(), String.format("上传失败,filePath: %s, uploadUrl: %s", getEntity().getFilePath(),
getThreadConfig().url)), true); getThreadConfig().url)), true);
@ -118,10 +119,11 @@ class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
*/ */
private boolean upload(final FTPClient client, final BufferedRandomAccessFile bis) private boolean upload(final FTPClient client, final BufferedRandomAccessFile bis)
throws IOException { throws IOException {
final FtpFISAdapter fa = new FtpFISAdapter(bis);
storeFail = false;
try { try {
ALog.d(TAG, String.format("remotePath: %s", remotePath)); ALog.d(TAG, String.format("remotePath: %s", remotePath));
client.storeFile(remotePath, new FtpFISAdapter(bis), new OnFtpInputStreamListener() { client.storeFile(remotePath, fa, new OnFtpInputStreamListener() {
boolean isStoped = false; boolean isStoped = false;
@Override public void onFtpInputStream(FTPClient client, long totalBytesTransferred, @Override public void onFtpInputStream(FTPClient client, long totalBytesTransferred,
@ -137,23 +139,30 @@ class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
progress(bytesTransferred); progress(bytesTransferred);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
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.getReplyCode(), String msg = String.format("文件上传错误,错误码为:%s, msg:%s, filePath: %s", client.getReplyCode(),
client.getReplyString(), getEntity().getFilePath()); client.getReplyString(), getEntity().getFilePath());
if (client.isConnected()) { closeClient(client);
client.disconnect();
}
if (e.getMessage().contains("AriaIOException caught while copying")) { if (e.getMessage().contains("AriaIOException caught while copying")) {
e.printStackTrace(); e.printStackTrace();
} else { } else {
fail(new AriaIOException(TAG, msg, e), true); fail(new AriaIOException(TAG, msg, e), !storeFail);
} }
return false; return false;
} }
if (storeFail) {
return false;
}
int reply = client.getReplyCode(); int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) { if (!FTPReply.isPositiveCompletion(reply)) {
if (reply != FTPReply.TRANSFER_ABORTED) { if (reply != FTPReply.TRANSFER_ABORTED) {
@ -161,9 +170,7 @@ class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
String.format("文件上传错误,错误码为:%s, msg:%s, filePath: %s", reply, client.getReplyString(), String.format("文件上传错误,错误码为:%s, msg:%s, filePath: %s", reply, client.getReplyString(),
getEntity().getFilePath())), false); getEntity().getFilePath())), false);
} }
if (client.isConnected()) { closeClient(client);
client.disconnect();
}
return false; return false;
} }
return true; return true;

@ -277,7 +277,7 @@ public class HttpFileInfoThread implements Runnable {
} }
mEntity.setFileName(newName); mEntity.setFileName(newName);
mEntity.setFilePath(newPath); mEntity.setFilePath(newPath);
RecordUtil.modifyTaskRecord(oldFile.getPath(), newPath); RecordUtil.modifyTaskRecord(oldFile.getPath(), newPath, mEntity.getTaskType());
} }
/** /**

@ -67,7 +67,7 @@ public class HttpRecordAdapter extends AbsRecordHandlerAdapter {
tr.startLocation = startL; tr.startLocation = startL;
tr.isComplete = false; tr.isComplete = false;
tr.threadType = TaskRecord.TYPE_HTTP_FTP; tr.threadType = getEntity().getTaskType();
//最后一个线程的结束位置即为文件的总长度 //最后一个线程的结束位置即为文件的总长度
if (threadId == (record.threadNum - 1)) { if (threadId == (record.threadNum - 1)) {
endL = getEntity().getFileSize(); endL = getEntity().getFileSize();
@ -91,7 +91,7 @@ public class HttpRecordAdapter extends AbsRecordHandlerAdapter {
} else { } else {
record.isBlock = false; record.isBlock = false;
} }
record.taskType = TaskRecord.TYPE_HTTP_FTP; record.taskType = getEntity().getTaskType();
record.isGroupRecord = getEntity().isGroupChild(); record.isGroupRecord = getEntity().isGroupChild();
if (record.isGroupRecord) { if (record.isGroupRecord) {
if (getEntity() instanceof DownloadEntity) { if (getEntity() instanceof DownloadEntity) {

@ -112,7 +112,9 @@ final class HttpDThreadTaskAdapter extends BaseHttpThreadTaskAdapter {
new BufferedRandomAccessFile(getThreadConfig().tempFile, "rwd", new BufferedRandomAccessFile(getThreadConfig().tempFile, "rwd",
getTaskConfig().getBuffSize()); getTaskConfig().getBuffSize());
//设置每条线程写入文件的位置 //设置每条线程写入文件的位置
file.seek(getThreadRecord().startLocation); if (getThreadRecord().startLocation > 0){
file.seek(getThreadRecord().startLocation);
}
readNormal(is, file); readNormal(is, file);
handleComplete(); handleComplete();
} }

@ -106,7 +106,7 @@ public class M3U8RecordAdapter extends AbsRecordHandlerAdapter {
tr.threadId = threadId; tr.threadId = threadId;
tr.isComplete = false; tr.isComplete = false;
tr.startLocation = 0; tr.startLocation = 0;
tr.threadType = TaskRecord.TYPE_M3U8_VOD; tr.threadType = getEntity().getTaskType();
tr.tsUrl = mOption.getUrls().get(threadId); tr.tsUrl = mOption.getUrls().get(threadId);
return tr; return tr;
} }
@ -118,13 +118,7 @@ public class M3U8RecordAdapter extends AbsRecordHandlerAdapter {
record.threadRecords = new ArrayList<>(); record.threadRecords = new ArrayList<>();
record.threadNum = threadNum; record.threadNum = threadNum;
record.isBlock = true; record.isBlock = true;
record.taskType = getEntity().getTaskType();
int requestType = getWrapper().getRequestType();
if (requestType == ITaskWrapper.M3U8_VOD) {
record.taskType = TaskRecord.TYPE_M3U8_VOD;
} else if (requestType == ITaskWrapper.M3U8_LIVE) {
record.taskType = TaskRecord.TYPE_M3U8_LIVE;
}
record.bandWidth = mOption.getBandWidth(); record.bandWidth = mOption.getBandWidth();
return record; return record;
} }

@ -169,7 +169,7 @@ public class M3U8LiveLoader extends BaseM3U8Loader {
record.taskKey = mRecord.filePath; record.taskKey = mRecord.filePath;
record.isComplete = false; record.isComplete = false;
record.tsUrl = tsUrl; record.tsUrl = tsUrl;
record.threadType = TaskRecord.TYPE_M3U8_LIVE; record.threadType = getEntity().getTaskType();
record.threadId = indexId; record.threadId = indexId;
mRecord.threadRecords.add(record); mRecord.threadRecords.add(record);

@ -15,6 +15,7 @@
*/ */
package com.arialyy.aria.core; package com.arialyy.aria.core;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.orm.annotation.Ignore; import com.arialyy.aria.orm.annotation.Ignore;
import com.arialyy.aria.orm.annotation.NoNull; import com.arialyy.aria.orm.annotation.NoNull;
@ -26,9 +27,9 @@ import java.util.List;
* 任务上传或下载的任务记录 * 任务上传或下载的任务记录
*/ */
public class TaskRecord extends DbEntity { public class TaskRecord extends DbEntity {
public static final int TYPE_HTTP_FTP = 0; //public static final int TYPE_HTTP_FTP = 0;
public static final int TYPE_M3U8_VOD = 1; //public static final int TYPE_M3U8_VOD = 1;
public static final int TYPE_M3U8_LIVE = 2; //public static final int TYPE_M3U8_LIVE = 2;
@Ignore @Ignore
public List<ThreadRecord> threadRecords; public List<ThreadRecord> threadRecords;
@ -41,7 +42,6 @@ public class TaskRecord extends DbEntity {
/** /**
* 任务文件路径 * 任务文件路径
*/ */
@Unique
public String filePath; public String filePath;
/** /**
@ -79,8 +79,8 @@ public class TaskRecord extends DbEntity {
public boolean isBlock = false; public boolean isBlock = false;
/** /**
* 线程类型 * 任务类型
* {@link #TYPE_HTTP_FTP}{@link #TYPE_M3U8_VOD} * {@link ITaskWrapper}
*/ */
public int taskType = 0; public int taskType = 0;

@ -15,6 +15,7 @@
*/ */
package com.arialyy.aria.core; package com.arialyy.aria.core;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.orm.DbEntity;
/** /**
@ -56,7 +57,7 @@ public class ThreadRecord extends DbEntity {
/** /**
* 线程类型 * 线程类型
* {@link TaskRecord#TYPE_HTTP_FTP}{@link TaskRecord#TYPE_M3U8_VOD} * {@link ITaskWrapper}
*/ */
public int threadType = 0; public int threadType = 0;

@ -17,6 +17,7 @@ package com.arialyy.aria.core.common;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.orm.annotation.Default; import com.arialyy.aria.orm.annotation.Default;
/** /**
@ -44,6 +45,20 @@ public abstract class AbsNormalEntity extends AbsEntity implements Parcelable {
private boolean isRedirect = false; //是否重定向 private boolean isRedirect = false; //是否重定向
private String redirectUrl; //重定向链接 private String redirectUrl; //重定向链接
/**
* 任务类型
* {@link ITaskWrapper}
*/
private int taskType;
@Override public int getTaskType() {
return taskType;
}
public void setTaskType(int taskType) {
this.taskType = taskType;
}
public String getUrl() { public String getUrl() {
return url; return url;
} }

@ -71,9 +71,11 @@ public class RecordHandler implements IRecordHandler {
convertDb(); convertDb();
} else { } else {
mAdapter.onPre(); mAdapter.onPre();
mTaskRecord = DbDataHelper.getTaskRecord(getFilePath()); mTaskRecord = DbDataHelper.getTaskRecord(getFilePath(), mEntity.getTaskType());
if (mTaskRecord == null) { if (mTaskRecord == null) {
FileUtil.createFile(getFilePath()); if (!new File(getFilePath()).exists()){
FileUtil.createFile(getFilePath());
}
initRecord(true); initRecord(true);
} else { } else {
File file = new File(mTaskRecord.filePath); File file = new File(mTaskRecord.filePath);

@ -78,22 +78,22 @@ public class DownloadEntity extends AbsNormalEntity implements Parcelable {
return getUrl(); return getUrl();
} }
@Override public int getTaskType() { //@Override public int getTaskType() {
int type; // int type;
if (TextUtils.isEmpty(getUrl())) { // if (TextUtils.isEmpty(getUrl())) {
type = ITaskWrapper.ERROR; // type = ITaskWrapper.ERROR;
} else if (getUrl().startsWith("ftp")) { // } else if (getUrl().startsWith("ftp")) {
type = ITaskWrapper.D_FTP; // type = ITaskWrapper.D_FTP;
} else { // } else {
M3U8Entity temp = getM3U8Entity(); // M3U8Entity temp = getM3U8Entity();
if (temp == null) { // if (temp == null) {
type = ITaskWrapper.D_HTTP; // type = ITaskWrapper.D_HTTP;
} else { // } else {
type = temp.isLive() ? ITaskWrapper.M3U8_LIVE : ITaskWrapper.M3U8_VOD; // type = temp.isLive() ? ITaskWrapper.M3U8_LIVE : ITaskWrapper.M3U8_VOD;
} // }
} // }
return type; // return type;
} //}
public DownloadEntity() { public DownloadEntity() {
} }

@ -20,6 +20,7 @@ import android.os.Parcelable;
import android.text.TextUtils; import android.text.TextUtils;
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.wrapper.ITaskWrapper;
import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.orm.annotation.Default; import com.arialyy.aria.orm.annotation.Default;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
@ -153,7 +154,8 @@ public class M3U8Entity extends DbEntity implements Parcelable {
return null; return null;
} }
List<PeerInfo> peers = new ArrayList<>(); List<PeerInfo> peers = new ArrayList<>();
TaskRecord taskRecord = DbDataHelper.getTaskRecord(filePath); TaskRecord taskRecord = DbDataHelper.getTaskRecord(filePath,
isLive ? ITaskWrapper.M3U8_LIVE : ITaskWrapper.M3U8_VOD);
File cacheDir = new File(getCacheDir()); File cacheDir = new File(getCacheDir());
if ((taskRecord == null if ((taskRecord == null
|| taskRecord.threadRecords == null || taskRecord.threadRecords == null

@ -17,9 +17,7 @@ package com.arialyy.aria.core.upload;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.text.TextUtils;
import com.arialyy.aria.core.common.AbsNormalEntity; import com.arialyy.aria.core.common.AbsNormalEntity;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.orm.annotation.Primary; import com.arialyy.aria.orm.annotation.Primary;
/** /**
@ -58,12 +56,12 @@ public class UploadEntity extends AbsNormalEntity implements Parcelable {
return filePath; return filePath;
} }
@Override public int getTaskType() { //@Override public int getTaskType() {
if (TextUtils.isEmpty(getUrl())){ // if (TextUtils.isEmpty(getUrl())){
return ITaskWrapper.ERROR; // return ITaskWrapper.ERROR;
} // }
return getUrl().startsWith("ftp") ? ITaskWrapper.U_FTP : ITaskWrapper.U_HTTP; // return getUrl().startsWith("ftp") ? ITaskWrapper.U_FTP : ITaskWrapper.U_HTTP;
} //}
public UploadEntity() { public UploadEntity() {
} }

@ -28,16 +28,7 @@ import java.net.URLEncoder;
abstract class AbsDelegate { abstract class AbsDelegate {
static final String TAG = "AbsDelegate"; static final String TAG = "AbsDelegate";
/**
* URL编码字符串
*
* @param str 原始字符串
* @return 编码后的字符串
*/
String encodeStr(String str) {
str = str.replaceAll("\\\\+", "%2B");
return URLEncoder.encode(str);
}
/** /**
* 检查list参数是否合法list只能是{@code List<String>} * 检查list参数是否合法list只能是{@code List<String>}

@ -34,7 +34,7 @@ class DBConfig {
static boolean DEBUG = false; static boolean DEBUG = false;
static Map<String, Class<? extends DbEntity>> mapping = new LinkedHashMap<>(); static Map<String, Class<? extends DbEntity>> mapping = new LinkedHashMap<>();
static String DB_NAME; static String DB_NAME;
static int VERSION = 56; static int VERSION = 57;
/** /**
* 是否将数据库保存在Sd卡{@code true} * 是否将数据库保存在Sd卡{@code true}

@ -113,7 +113,7 @@ class DelegateCommon extends AbsDelegate {
sql = sql.replace("?", "%s"); sql = sql.replace("?", "%s");
Object[] params = new String[expression.length - 1]; Object[] params = new String[expression.length - 1];
for (int i = 0, len = params.length; i < len; i++) { for (int i = 0, len = params.length; i < len; i++) {
params[i] = String.format("'%s'", encodeStr(expression[i + 1])); params[i] = String.format("'%s'", SqlUtil.encodeStr(expression[i + 1]));
} }
sql = String.format(sql, params); sql = String.format(sql, params);
Cursor cursor = db.rawQuery(sql, null); Cursor cursor = db.rawQuery(sql, null);

@ -205,7 +205,7 @@ class DelegateFind extends AbsDelegate {
sql = sql.replace("?", "%s"); sql = sql.replace("?", "%s");
Object[] params = new String[expression.length - 1]; Object[] params = new String[expression.length - 1];
for (int i = 0, len = params.length; i < len; i++) { for (int i = 0, len = params.length; i < len; i++) {
params[i] = String.format("'%s'", encodeStr(expression[i + 1])); params[i] = String.format("'%s'", SqlUtil.encodeStr(expression[i + 1]));
} }
sql = String.format(sql, params); sql = String.format(sql, params);
} else { } else {
@ -421,7 +421,7 @@ class DelegateFind extends AbsDelegate {
String[] temp = new String[selectionArgs.length]; String[] temp = new String[selectionArgs.length];
int i = 0; int i = 0;
for (String arg : selectionArgs) { for (String arg : selectionArgs) {
temp[i] = encodeStr(arg); temp[i] = SqlUtil.encodeStr(arg);
i++; i++;
} }
Cursor cursor = db.rawQuery(sql, temp); Cursor cursor = db.rawQuery(sql, temp);

@ -47,7 +47,7 @@ class DelegateUpdate extends AbsDelegate {
sql = sql.replace("?", "%s"); sql = sql.replace("?", "%s");
Object[] params = new String[expression.length - 1]; Object[] params = new String[expression.length - 1];
for (int i = 0, len = params.length; i < len; i++) { for (int i = 0, len = params.length; i < len; i++) {
params[i] = String.format("'%s'", encodeStr(expression[i + 1])); params[i] = String.format("'%s'", SqlUtil.encodeStr(expression[i + 1]));
} }
sql = String.format(sql, params); sql = String.format(sql, params);
db.execSQL(sql); db.execSQL(sql);
@ -166,7 +166,7 @@ class DelegateUpdate extends AbsDelegate {
value = field.get(dbEntity).toString(); value = field.get(dbEntity).toString();
} }
} }
values.put(field.getName(), encodeStr(value)); values.put(field.getName(), SqlUtil.encodeStr(value));
} }
return values; return values;
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {

@ -21,6 +21,9 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteOpenHelper;
import android.os.Build; import android.os.Build;
import android.text.TextUtils;
import com.arialyy.aria.core.download.M3U8Entity;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@ -102,6 +105,10 @@ final class SqlHelper extends SQLiteOpenHelper {
} else { } else {
handleDbUpdate(db, null); handleDbUpdate(db, null);
} }
// 处理380版本TaskRecord 增加的记录类型判断
if (newVersion == 57) {
addTaskRecordType(db);
}
} }
} }
@ -256,6 +263,79 @@ final class SqlHelper extends SQLiteOpenHelper {
return temp; return temp;
} }
/**
* 给TaskRecord 增加任务类型
*/
private void addTaskRecordType(SQLiteDatabase db) {
try {
db.beginTransaction();
/*
* 增加下载实体的类型
*/
String dSql = "SELECT downloadPath, url FROM DownloadEntity";
Cursor c = db.rawQuery(dSql, null);
while (c.moveToNext()) {
int type;
String filePath = c.getString(0);
String url = c.getString(1);
if (url.startsWith("ftp") || url.startsWith("sftp")) {
type = ITaskWrapper.D_FTP;
} else {
if (mDelegate.tableExists(db, M3U8Entity.class)) {
Cursor m3u8c = db.rawQuery("SELECT isLive FROM M3U8Entity WHERE filePath=\""
+ SqlUtil.encodeStr(filePath)
+ "\"", null);
if (m3u8c.moveToNext()) {
String temp = m3u8c.getString(0);
type =
(TextUtils.isEmpty(temp) ? false : Boolean.valueOf(temp)) ? ITaskWrapper.M3U8_LIVE
: ITaskWrapper.M3U8_VOD;
} else {
type = ITaskWrapper.D_HTTP;
}
m3u8c.close();
} else {
type = ITaskWrapper.D_HTTP;
}
}
db.execSQL("UPDATE DownloadEntity SET taskType=? WHERE downloadPath=?",
new Object[] { type, filePath });
db.execSQL("UPDATE TaskRecord SET taskType=? WHERE filePath=?",
new Object[] { type, filePath });
db.execSQL("UPDATE ThreadRecord SET threadType=? WHERE taskKey=?",
new Object[] { type, filePath });
}
c.close();
/*
* 增加上传实体的类型
*/
String uSql = "SELECT filePath, url FROM UploadEntity";
c = db.rawQuery(uSql, null);
while (c.moveToNext()) {
int type;
String filePath = c.getString(c.getColumnIndex("filePath"));
String url = c.getString(c.getColumnIndex("url"));
if (url.startsWith("ftp") || url.startsWith("sftp")) {
type = ITaskWrapper.D_FTP;
} else {
type = ITaskWrapper.D_HTTP;
}
db.execSQL("UPDATE UploadEntity SET taskType=? WHERE filePath=?",
new Object[] { type, filePath });
db.execSQL("UPDATE TaskRecord SET taskType=? WHERE filePath=?",
new Object[] { type, filePath });
db.execSQL("UPDATE ThreadRecord SET threadType=? WHERE taskKey=?",
new Object[] { type, filePath });
}
c.close();
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
/** /**
* 删除重复的repeat数据 * 删除重复的repeat数据
*/ */

@ -29,6 +29,7 @@ import com.arialyy.aria.orm.annotation.Wrapper;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.net.URLEncoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -41,6 +42,17 @@ import java.util.Set;
*/ */
final class SqlUtil { final class SqlUtil {
/**
* URL编码字符串
*
* @param str 原始字符串
* @return 编码后的字符串
*/
static String encodeStr(String str) {
str = str.replaceAll("\\\\+", "%2B");
return URLEncoder.encode(str);
}
/** /**
* 获取主键字段名 * 获取主键字段名
*/ */

@ -141,8 +141,15 @@ public class CheckUtil {
*/ */
public static void checkMemberClass(Class clazz) { public static void checkMemberClass(Class clazz) {
int modifiers = clazz.getModifiers(); int modifiers = clazz.getModifiers();
if (!clazz.isMemberClass() || !Modifier.isStatic(modifiers) || Modifier.isPrivate(modifiers)) { //ALog.d(TAG, "isMemberClass = "
ALog.e(TAG, "为了防止内存泄漏,请使用静态的成员类(public static class xxx)或文件类(A.java)"); // + clazz.isMemberClass()
// + "; isStatic = "
// + Modifier.isStatic(modifiers)
// + "; isPrivate = "
// + Modifier.isPrivate(modifiers));
if (!clazz.isMemberClass() || !Modifier.isStatic(modifiers)) {
ALog.e(TAG, String.format("为了防止内存泄漏,请使用静态的成员类(public static class %s)或文件类(%s.java)",
clazz.getSimpleName(), clazz.getSimpleName()));
} }
} }

@ -15,12 +15,13 @@
*/ */
package com.arialyy.aria.util; package com.arialyy.aria.util;
import com.arialyy.aria.core.wrapper.RecordWrapper;
import com.arialyy.aria.core.TaskRecord; import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.ThreadRecord;
import com.arialyy.aria.core.download.DGEntityWrapper; import com.arialyy.aria.core.download.DGEntityWrapper;
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.download.DownloadGroupEntity; import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.orm.DbEntity;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@ -35,15 +36,20 @@ public class DbDataHelper {
* 获取任务记录 * 获取任务记录
* *
* @param filePath 文件地址 * @param filePath 文件地址
* @param taskType 任务类型{@link ITaskWrapper}
* @return 没有记录返回null有记录则返回任务记录 * @return 没有记录返回null有记录则返回任务记录
*/ */
public static TaskRecord getTaskRecord(String filePath) { public static TaskRecord getTaskRecord(String filePath, int taskType) {
List<RecordWrapper> record = TaskRecord taskRecord =
DbEntity.findRelationData(RecordWrapper.class, "TaskRecord.filePath=?", filePath); DbEntity.findFirst(TaskRecord.class, "filePath=? AND taskType=?", filePath,
if (record == null || record.size() == 0) { String.valueOf(taskType));
return null; if (taskRecord != null) {
taskRecord.threadRecords =
DbEntity.findDatas(ThreadRecord.class, "taskKey=? AND threadType=?", filePath,
String.valueOf(taskType));
} }
return record.get(0).taskRecord;
return taskRecord;
} }
/** /**

@ -25,6 +25,7 @@ import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.download.M3U8Entity; import com.arialyy.aria.core.download.M3U8Entity;
import com.arialyy.aria.core.inf.IRecordHandler; import com.arialyy.aria.core.inf.IRecordHandler;
import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.core.wrapper.RecordWrapper; import com.arialyy.aria.core.wrapper.RecordWrapper;
import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.orm.DbEntity;
import java.io.File; import java.io.File;
@ -187,7 +188,7 @@ public class RecordUtil {
* @return true 为m3u8任务 * @return true 为m3u8任务
*/ */
private static boolean recordIsM3U8(int recordType) { private static boolean recordIsM3U8(int recordType) {
return recordType == TaskRecord.TYPE_M3U8_VOD || recordType == TaskRecord.TYPE_M3U8_LIVE; return recordType == ITaskWrapper.M3U8_VOD || recordType == ITaskWrapper.M3U8_LIVE;
} }
/** /**
@ -361,13 +362,14 @@ public class RecordUtil {
* *
* @param oldPath 旧的文件路径 * @param oldPath 旧的文件路径
* @param newPath 新的文件路径 * @param newPath 新的文件路径
* @param taskType 任务类型{@link ITaskWrapper}
*/ */
public static void modifyTaskRecord(String oldPath, String newPath) { public static void modifyTaskRecord(String oldPath, String newPath, int taskType) {
if (oldPath.equals(newPath)) { if (oldPath.equals(newPath)) {
ALog.w(TAG, "修改任务记录失败,新文件路径和旧文件路径一致"); ALog.w(TAG, "修改任务记录失败,新文件路径和旧文件路径一致");
return; return;
} }
TaskRecord record = DbDataHelper.getTaskRecord(oldPath); TaskRecord record = DbDataHelper.getTaskRecord(oldPath, taskType);
if (record == null) { if (record == null) {
if (new File(oldPath).exists()) { if (new File(oldPath).exists()) {
ALog.w(TAG, "修改任务记录失败,文件【" + oldPath + "】对应的任务记录不存在"); ALog.w(TAG, "修改任务记录失败,文件【" + oldPath + "】对应的任务记录不存在");

@ -44,16 +44,16 @@ Aria有以下特点:
## 引入库 ## 引入库
[![license](http://img.shields.io/badge/license-Apache2.0-brightgreen.svg?style=flat)](https://github.com/AriaLyy/Aria/blob/master/LICENSE) [![license](http://img.shields.io/badge/license-Apache2.0-brightgreen.svg?style=flat)](https://github.com/AriaLyy/Aria/blob/master/LICENSE)
[![Core](https://img.shields.io/badge/Core-3.7.10-blue)](https://github.com/AriaLyy/Aria) [![Core](https://img.shields.io/badge/Core-3.8-blue)](https://github.com/AriaLyy/Aria)
[![Compiler](https://img.shields.io/badge/Compiler-3.7.10-blue)](https://github.com/AriaLyy/Aria) [![Compiler](https://img.shields.io/badge/Compiler-3.8-blue)](https://github.com/AriaLyy/Aria)
[![FtpComponent](https://img.shields.io/badge/FtpComponent-3.7.10-orange)](https://github.com/AriaLyy/Aria) [![FtpComponent](https://img.shields.io/badge/FtpComponent-3.8-orange)](https://github.com/AriaLyy/Aria)
[![M3U8Component](https://img.shields.io/badge/M3U8Component-3.7.10-orange)](https://github.com/AriaLyy/Aria) [![M3U8Component](https://img.shields.io/badge/M3U8Component-3.8-orange)](https://github.com/AriaLyy/Aria)
```java ```java
implementation 'com.arialyy.aria:core:3.7.10' implementation 'com.arialyy.aria:core:3.8'
annotationProcessor 'com.arialyy.aria:compiler:3.7.10' annotationProcessor 'com.arialyy.aria:compiler:3.8'
implementation 'com.arialyy.aria:ftpComponent:3.7.10' # 如果需要使用ftp,请增加该组件 implementation 'com.arialyy.aria:ftpComponent:3.8' # 如果需要使用ftp,请增加该组件
implementation 'com.arialyy.aria:m3u8Component:3.7.10' # 如果需要使用m3u8下载功能,请增加该组件 implementation 'com.arialyy.aria:m3u8Component:3.8' # 如果需要使用m3u8下载功能,请增加该组件
``` ```
如果出现android support依赖错误,请将 `compile 'com.arialyy.aria:core:<last-version>'`替换为 如果出现android support依赖错误,请将 `compile 'com.arialyy.aria:core:<last-version>'`替换为
``` ```
@ -65,7 +65,7 @@ api('com.arialyy.aria:core:<last-version>'){
__⚠注意:3.5.4以下版本升级时,需要更新[配置文件](https://aria.laoyuyu.me/aria_doc/start/config.html)!!__ __⚠注意:3.5.4以下版本升级时,需要更新[配置文件](https://aria.laoyuyu.me/aria_doc/start/config.html)!!__
__⚠注意:3.7 以上版本已经适配了AndroidX,如果是使用support库的,可使用[老版本](https://github.com/AriaLyy/Aria/tree/v3.6.6)__ __⚠注意:3.8 以上版本已经适配了AndroidX和support库都可以使用
*** ***
## 使用 ## 使用
@ -137,13 +137,19 @@ protected void onCreate(Bundle savedInstanceState) {
### 版本日志 ### 版本日志
+ v_3.7.10 (2019/12/3) + v_3.8 (2019/12/17)
- fix bug https://github.com/AriaLyy/Aria/issues/543#issuecomment-559733124 - 移除androidx和support的依赖,现在无论是哪个版本的appcompat包都可以使用本框架
- fix bug https://github.com/AriaLyy/Aria/issues/542 - 修复一个在xml中使用fragment导致的内存泄漏问题
- fix bug https://github.com/AriaLyy/Aria/issues/547 - m3u8协议的key信息增加了`keyFormat`,`keyFormatVersion`字段
- 修复下载失败时,中断重试无效的问题 - m3u8增加了`ignoreFailureTs`方法,忽略下载失败的ts切片
- 增加忽略权限检查的api,`ignoreCheckPermissions()` - 修复在dialogFragment的`onCreateDialog()`注册导致的注解不生效问题
- 增加通用的的忽略文件路径被占用的api,`isIgnoreFilePathOccupy()` - 修复组合任务初始化失败时,无法删除的问题
- 修复`reStart()`后,无法停止的问题
- ftp增加主动模式,开启主动模式:https://aria.laoyuyu.me/aria_doc/api/ftp_params.html
- 修复ftp服务器无法响应`abor`命令导致的无法停止上传的问题 https://github.com/AriaLyy/Aria/issues/564
- 修复ftp上传时,服务器有长度为0的文件导致上传失败的问题
- 修复下载任务和上传任务的文件路径是同一个时,导致的记录混乱问题
- 优化提示
[更多版本记录](https://github.com/AriaLyy/Aria/blob/master/DEV_LOG.md) [更多版本记录](https://github.com/AriaLyy/Aria/blob/master/DEV_LOG.md)

@ -55,7 +55,8 @@ 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 = "lao", pwd = "123456"; private String user = "ftpuser", pwd = "ftpuser2020";
//private String user = "lao", pwd = "123456";
@Override protected void init(Bundle savedInstanceState) { @Override protected void init(Bundle savedInstanceState) {
setTile("D_FTP 文件上传"); setTile("D_FTP 文件上传");
@ -92,11 +93,11 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
} }
private void setHelpCode() { private void setHelpCode() {
try { //try {
getBinding().codeView.setSource(AppUtil.getHelpCode(this, "FtpUpload.java")); // getBinding().codeView.setSource(AppUtil.getHelpCode(this, "FtpUpload.java"));
} catch (IOException e) { //} catch (IOException e) {
e.printStackTrace(); // e.printStackTrace();
} //}
} }
@Override protected int setLayoutId() { @Override protected int setLayoutId() {
@ -245,7 +246,7 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
@Override public FtpInterceptHandler onIntercept(UploadEntity entity, List<String> fileList) { @Override public FtpInterceptHandler onIntercept(UploadEntity entity, List<String> fileList) {
FtpInterceptHandler.Builder builder = new FtpInterceptHandler.Builder(); FtpInterceptHandler.Builder builder = new FtpInterceptHandler.Builder();
//builder.coverServerFile(); // 覆盖远端同名文件 //builder.coverServerFile(); // 覆盖远端同名文件
builder.resetFileName("test.zip"); //修改上传到远端服务器的文件名 builder.resetFileName("test12.zip"); //修改上传到远端服务器的文件名
return builder.build(); return builder.build();
} }
} }

@ -35,9 +35,12 @@ public class UploadModule extends BaseViewModule {
* 获取Ftp上传信息 * 获取Ftp上传信息
*/ */
LiveData<UploadEntity> getFtpInfo(Context context) { LiveData<UploadEntity> getFtpInfo(Context context) {
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 filePath = "/mnt/sdcard/QQMusic-import-1.2.1.zip";
UploadEntity entity = Aria.upload(context).getFirstUploadEntity(filePath); UploadEntity entity = Aria.upload(context).getFirstUploadEntity(filePath);
if (entity != null) { if (entity != null) {

@ -72,11 +72,11 @@
/> />
<com.arialyy.simple.widget.CodeView <!-- <com.arialyy.simple.widget.CodeView-->
android:id="@+id/code_view" <!-- android:id="@+id/code_view"-->
android:layout_width="match_parent" <!-- android:layout_width="match_parent"-->
android:layout_height="match_parent" <!-- android:layout_height="match_parent"-->
/> <!-- />-->
</LinearLayout> </LinearLayout>

@ -45,7 +45,7 @@ task clean(type: Delete) {
ext { ext {
versionCode = 380 versionCode = 380
versionName = '3.8_pre_1' versionName = '3.8'
userOrg = 'arialyy' userOrg = 'arialyy'
groupId = 'com.arialyy.aria' groupId = 'com.arialyy.aria'
publishVersion = versionName publishVersion = versionName

Loading…
Cancel
Save