fix bug https://github.com/AriaLyy/Aria/issues/505
增加上传任务强制上传的功能
pull/617/head
laoyuyu 5 years ago
parent 5ad485890c
commit 846e6c0720
  1. 6
      Aria/src/main/java/com/arialyy/aria/core/command/CommandManager.java
  2. 115
      Aria/src/main/java/com/arialyy/aria/core/command/ResumeAllCmd.java
  3. 198
      Aria/src/main/java/com/arialyy/aria/core/command/ResumeThread.java
  4. 89
      Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java
  5. 1
      Aria/src/main/java/com/arialyy/aria/core/common/controller/BuilderController.java
  6. 12
      Aria/src/main/java/com/arialyy/aria/core/download/CheckDEntityUtil.java
  7. 15
      Aria/src/main/java/com/arialyy/aria/core/manager/DGTaskWrapperFactory.java
  8. 9
      Aria/src/main/java/com/arialyy/aria/core/manager/DTaskWrapperFactory.java
  9. 10
      Aria/src/main/java/com/arialyy/aria/core/manager/UTaskWrapperFactory.java
  10. 7
      Aria/src/main/java/com/arialyy/aria/core/upload/CheckUEntityUtil.java
  11. 13
      Aria/src/main/java/com/arialyy/aria/core/upload/target/FtpBuilderTarget.java
  12. 4
      Aria/src/main/java/com/arialyy/aria/core/upload/target/FtpNormalTarget.java
  13. 9
      Aria/src/main/java/com/arialyy/aria/core/upload/target/HttpBuilderTarget.java
  14. 5
      DEV_LOG.md
  15. 2
      FtpComponent/src/main/java/com/arialyy/aria/ftp/FtpDirInfoThread.java
  16. 6
      FtpComponent/src/main/java/com/arialyy/aria/ftp/FtpRecordAdapter.java
  17. 2
      FtpComponent/src/main/java/com/arialyy/aria/ftp/download/FtpDThreadTaskAdapter.java
  18. 6
      HttpComponent/src/main/java/com/arialyy/aria/http/HttpRecordAdapter.java
  19. 2
      HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDThreadTaskAdapter.java
  20. 8
      M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8RecordAdapter.java
  21. 2
      M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8ThreadTaskAdapter.java
  22. 1
      M3U8Component/src/main/java/com/arialyy/aria/m3u8/live/M3U8LiveLoader.java
  23. 1
      M3U8Component/src/main/java/com/arialyy/aria/m3u8/vod/M3U8VodLoader.java
  24. 6
      PublicComponent/src/main/java/com/arialyy/aria/core/TaskRecord.java
  25. 1
      PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHandler.java
  26. 8
      PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHelper.java
  27. 2
      PublicComponent/src/main/java/com/arialyy/aria/core/common/SubThreadConfig.java
  28. 8
      PublicComponent/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java
  29. 1
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/NormalLoader.java
  30. 2
      PublicComponent/src/main/java/com/arialyy/aria/core/task/ThreadTask.java
  31. 13
      PublicComponent/src/main/java/com/arialyy/aria/core/upload/UTaskWrapper.java
  32. 6
      PublicComponent/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java
  33. 1
      PublicComponent/src/main/java/com/arialyy/aria/core/wrapper/AbsTaskWrapper.java
  34. 2
      PublicComponent/src/main/java/com/arialyy/aria/orm/DBConfig.java
  35. 4
      PublicComponent/src/main/java/com/arialyy/aria/orm/SqlHelper.java
  36. 24
      PublicComponent/src/main/java/com/arialyy/aria/util/CheckUtil.java
  37. 3
      PublicComponent/src/main/java/com/arialyy/aria/util/ComponentUtil.java
  38. 12
      PublicComponent/src/main/java/com/arialyy/aria/util/ErrorHelp.java
  39. 2
      PublicComponent/src/main/java/com/arialyy/aria/util/RecordUtil.java
  40. 2
      app/src/main/java/com/arialyy/simple/core/download/HttpDownloadModule.java
  41. 65
      app/src/main/java/com/arialyy/simple/core/upload/FtpUploadActivity.java

@ -30,7 +30,7 @@ public class CommandManager {
EventMsgUtil.getDefault().register(this); EventMsgUtil.getDefault().register(this);
} }
public static CommandManager init() { public static void init() {
if (instance == null) { if (instance == null) {
synchronized (CommandManager.class) { synchronized (CommandManager.class) {
if (instance == null) { if (instance == null) {
@ -38,7 +38,6 @@ public class CommandManager {
} }
} }
} }
return instance;
} }
@Event @Event
@ -51,9 +50,6 @@ public class CommandManager {
@Event @Event
public void start(StartCmd cmd) { public void start(StartCmd cmd) {
if (CommonUtil.isFastDoubleClick()) {
return;
}
cmd.executeCmd(); cmd.executeCmd();
} }

@ -1,25 +1,44 @@
/*
* 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.command; package com.arialyy.aria.core.command;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.download.DGTaskWrapper; import com.arialyy.aria.core.download.DGTaskWrapper;
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.common.AbsEntity;
import com.arialyy.aria.core.task.AbsTask;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.IOptionConstant;
import com.arialyy.aria.core.manager.TaskWrapperManager; import com.arialyy.aria.core.manager.TaskWrapperManager;
import com.arialyy.aria.core.queue.DGroupTaskQueue; import com.arialyy.aria.core.queue.DGroupTaskQueue;
import com.arialyy.aria.core.queue.DTaskQueue; import com.arialyy.aria.core.queue.DTaskQueue;
import com.arialyy.aria.core.queue.UTaskQueue; import com.arialyy.aria.core.queue.UTaskQueue;
import com.arialyy.aria.core.task.AbsTask;
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.core.wrapper.AbsTaskWrapper;
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.NetUtils; import com.arialyy.aria.util.NetUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.Executors;
/** /**
* Created by AriaL on 2017/6/13. * Created by AriaL on 2017/6/13.
@ -30,7 +49,7 @@ import java.util.List;
* 4.恢复下载的任务规则是停止时间越晚的任务启动越早按照DESC来进行排序 * 4.恢复下载的任务规则是停止时间越晚的任务启动越早按照DESC来进行排序
*/ */
final class ResumeAllCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> { final class ResumeAllCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
private List<AbsTaskWrapper> mWaitList = new ArrayList<>();
ResumeAllCmd(T entity, int taskType) { ResumeAllCmd(T entity, int taskType) {
super(entity, taskType); super(entity, taskType);
@ -41,94 +60,8 @@ final class ResumeAllCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
ALog.w(TAG, "恢复任务失败,网络未连接"); ALog.w(TAG, "恢复任务失败,网络未连接");
return; return;
} }
if (isDownloadCmd) { new Thread(new ResumeThread(isDownloadCmd, IEntity.STATE_COMPLETE)).start();
findTaskData(1);
findTaskData(2);
} else {
findTaskData(3);
}
resumeWaitTask();
}
/**
* 查找数据库中的所有任务数据
*
* @param type {@code 1}单任务下载任务{@code 2}任务组下载任务{@code 3} 单任务上传任务
*/
private void findTaskData(int type) {
if (type == 1) {
List<DownloadEntity> entities =
DbEntity.findDatas(DownloadEntity.class,
"isGroupChild=? AND state!=? ORDER BY stopTime DESC", "false", "1");
if (entities != null && !entities.isEmpty()) {
for (DownloadEntity entity : entities) {
addResumeEntity(TaskWrapperManager.getInstance()
.getNormalTaskWrapper(DTaskWrapper.class, entity.getId()));
}
}
} else if (type == 2) {
List<DownloadGroupEntity> entities =
DbEntity.findDatas(DownloadGroupEntity.class, "state!=? ORDER BY stopTime DESC", "1");
if (entities != null && !entities.isEmpty()) {
for (DownloadGroupEntity entity : entities) {
addResumeEntity(
TaskWrapperManager.getInstance()
.getGroupWrapper(DGTaskWrapper.class, entity.getId()));
}
}
} else if (type == 3) {
List<UploadEntity> entities =
DbEntity.findDatas(UploadEntity.class, "state!=? ORDER BY stopTime DESC", "1");
if (entities != null && !entities.isEmpty()) {
for (UploadEntity entity : entities) {
addResumeEntity(TaskWrapperManager.getInstance()
.getNormalTaskWrapper(UTaskWrapper.class, entity.getId()));
}
}
}
}
/**
* 添加恢复实体
*/
private void addResumeEntity(AbsTaskWrapper te) {
if (te == null || te.getEntity() == null) {
return;
}
if (!mQueue.taskExists(te.getKey())) {
mWaitList.add(te);
}
} }
/**
* 处理等待状态的任务
*/
private void resumeWaitTask() {
int maxTaskNum = mQueue.getMaxTaskNum();
if (mWaitList == null || mWaitList.isEmpty()) {
return;
}
List<AbsEntity> resumeEntities = new ArrayList<>();
for (AbsTaskWrapper te : mWaitList) {
if (te instanceof DTaskWrapper) {
mQueue = DTaskQueue.getInstance();
} else if (te instanceof UTaskWrapper) {
mQueue = UTaskQueue.getInstance();
} else if (te instanceof DGTaskWrapper) {
mQueue = DGroupTaskQueue.getInstance();
}
if (mQueue.getCurrentExePoolNum() < maxTaskNum) {
startTask(createTask(te));
} else {
te.getEntity().setState(IEntity.STATE_WAIT);
AbsTask task = createTask(te);
sendWaitState(task);
resumeEntities.add(te.getEntity());
}
}
if (!resumeEntities.isEmpty()) {
DbEntity.updateManyData(resumeEntities);
}
}
} }

@ -0,0 +1,198 @@
/*
* 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.command;
import android.text.TextUtils;
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.IOptionConstant;
import com.arialyy.aria.core.listener.ISchedulers;
import com.arialyy.aria.core.manager.TaskWrapperManager;
import com.arialyy.aria.core.queue.AbsTaskQueue;
import com.arialyy.aria.core.queue.DGroupTaskQueue;
import com.arialyy.aria.core.queue.DTaskQueue;
import com.arialyy.aria.core.queue.UTaskQueue;
import com.arialyy.aria.core.task.AbsTask;
import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import java.util.ArrayList;
import java.util.List;
/**
* 恢复任务工具
*/
public class ResumeThread implements Runnable {
private String TAG = CommonUtil.getClassName(getClass());
private List<AbsTaskWrapper> mWaitList = new ArrayList<>();
private boolean isDownloadCmd;
private int excludeState;
ResumeThread(boolean isDownload, int excludeState) {
this.isDownloadCmd = isDownload;
this.excludeState = excludeState;
}
/**
* 查找数据库中的所有任务数据
*
* @param type {@code 1}单任务下载任务{@code 2}任务组下载任务{@code 3} 单任务上传任务
*/
private void findTaskData(int type) {
if (type == 1) {
List<DownloadEntity> entities =
DbEntity.findDatas(DownloadEntity.class,
"isGroupChild=? AND state!=? ORDER BY stopTime DESC", "false",
String.valueOf(excludeState));
if (entities != null && !entities.isEmpty()) {
for (DownloadEntity entity : entities) {
addResumeEntity(TaskWrapperManager.getInstance()
.getNormalTaskWrapper(DTaskWrapper.class, entity.getId()));
}
}
} else if (type == 2) {
List<DownloadGroupEntity> entities =
DbEntity.findDatas(DownloadGroupEntity.class, "state!=? ORDER BY stopTime DESC",
String.valueOf(excludeState));
if (entities != null && !entities.isEmpty()) {
for (DownloadGroupEntity entity : entities) {
addResumeEntity(
TaskWrapperManager.getInstance()
.getGroupWrapper(DGTaskWrapper.class, entity.getId()));
}
}
} else if (type == 3) {
List<UploadEntity> entities =
DbEntity.findDatas(UploadEntity.class, "state!=? ORDER BY stopTime DESC",
String.valueOf(excludeState));
if (entities != null && !entities.isEmpty()) {
for (UploadEntity entity : entities) {
addResumeEntity(TaskWrapperManager.getInstance()
.getNormalTaskWrapper(UTaskWrapper.class, entity.getId()));
}
}
}
}
/**
* 添加恢复实体
*/
private void addResumeEntity(AbsTaskWrapper te) {
if (te == null || te.getEntity() == null || TextUtils.isEmpty(te.getKey())) {
return;
}
mWaitList.add(te);
}
/**
* 处理等待状态的任务
*/
private void resumeWaitTask() {
if (mWaitList == null || mWaitList.isEmpty()) {
return;
}
List<AbsEntity> resumeEntities = new ArrayList<>();
for (AbsTaskWrapper wrapper : mWaitList) {
AbsTaskQueue queue = null;
if (wrapper instanceof DTaskWrapper) {
queue = DTaskQueue.getInstance();
} else if (wrapper instanceof UTaskWrapper) {
queue = UTaskQueue.getInstance();
} else if (wrapper instanceof DGTaskWrapper) {
queue = DGroupTaskQueue.getInstance();
}
if (queue == null){
ALog.e(TAG, "任务类型错误");
continue;
}
if (wrapper.getEntity() == null || TextUtils.isEmpty(wrapper.getKey())) {
ALog.e(TAG, "任务实体为空或key为空");
continue;
}
AbsTask task = queue.getTask(wrapper.getKey());
if (task != null) {
ALog.w(TAG, "任务已存在");
continue;
}
int maxTaskNum = queue.getMaxTaskNum();
task = queue.createTask(wrapper);
if (task == null) {
continue;
}
handleWrapper(wrapper);
if (queue.getCurrentExePoolNum() < maxTaskNum) {
queue.startTask(task);
} else {
wrapper.getEntity().setState(IEntity.STATE_WAIT);
sendWaitState(task);
resumeEntities.add(wrapper.getEntity());
}
}
if (!resumeEntities.isEmpty()) {
DbEntity.updateManyData(resumeEntities);
}
}
/**
* 处理ftp的wrapper
*/
private void handleWrapper(AbsTaskWrapper wrapper) {
int requestType = wrapper.getRequestType();
if (requestType == ITaskWrapper.D_FTP
|| requestType == ITaskWrapper.U_FTP
|| requestType == ITaskWrapper.D_FTP_DIR) {
wrapper.getOptionParams()
.setParams(IOptionConstant.ftpUrlEntity,
CommonUtil.getFtpUrlInfo(wrapper.getEntity().getKey()));
}
}
/**
* 发送等待状态
*/
private void sendWaitState(AbsTask task) {
if (task != null) {
task.getTaskWrapper().setState(IEntity.STATE_WAIT);
task.getOutHandler().obtainMessage(ISchedulers.WAIT, task).sendToTarget();
}
}
@Override public void run() {
if (isDownloadCmd) {
findTaskData(1);
findTaskData(2);
} else {
findTaskData(3);
}
resumeWaitTask();
}
}

@ -18,27 +18,11 @@ package com.arialyy.aria.core.command;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.QueueMod; import com.arialyy.aria.core.common.QueueMod;
import com.arialyy.aria.core.download.DGTaskWrapper; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.task.AbsTask; import com.arialyy.aria.core.task.AbsTask;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper; import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.IOptionConstant;
import com.arialyy.aria.core.manager.TaskWrapperManager;
import com.arialyy.aria.core.queue.DGroupTaskQueue;
import com.arialyy.aria.core.queue.DTaskQueue;
import com.arialyy.aria.core.queue.UTaskQueue;
import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
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.NetUtils; import com.arialyy.aria.util.NetUtils;
import java.util.ArrayList;
import java.util.List;
/** /**
* Created by lyy on 2016/8/22. 开始命令 队列模型{@link QueueMod#NOW}{@link QueueMod#WAIT} * Created by lyy on 2016/8/22. 开始命令 队列模型{@link QueueMod#NOW}{@link QueueMod#WAIT}
@ -107,75 +91,6 @@ final class StartCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
* 当缓冲队列为null时查找数据库中所有等待中的任务 * 当缓冲队列为null时查找数据库中所有等待中的任务
*/ */
private void findAllWaitTask() { private void findAllWaitTask() {
new Thread(new WaitTaskThread()).start(); new Thread(new ResumeThread(isDownloadCmd, IEntity.STATE_WAIT)).start();
}
private class WaitTaskThread implements Runnable {
@Override public void run() {
if (isDownloadCmd) {
handleTask(findWaitData(1));
handleTask(findWaitData(2));
} else {
handleTask(findWaitData(3));
}
}
private List<AbsTaskWrapper> findWaitData(int type) {
List<AbsTaskWrapper> waitList = new ArrayList<>();
TaskWrapperManager tManager = TaskWrapperManager.getInstance();
if (type == 1) { // 普通下载任务
List<DownloadEntity> dEntities = DbEntity.findDatas(DownloadEntity.class,
"isGroupChild=? and state=?", "false", "3");
if (dEntities != null && !dEntities.isEmpty()) {
for (DownloadEntity e : dEntities) {
waitList.add(tManager.getNormalTaskWrapper(DTaskWrapper.class, e.getId()));
}
}
} else if (type == 2) { // 组合任务
List<DownloadGroupEntity> dEntities =
DbEntity.findDatas(DownloadGroupEntity.class, "state=?", "3");
if (dEntities != null && !dEntities.isEmpty()) {
for (DownloadGroupEntity e : dEntities) {
if (e.getTaskType() == ITaskWrapper.DG_HTTP) {
waitList.add(tManager.getGroupWrapper(DGTaskWrapper.class, e.getId()));
} else if (e.getTaskType() == ITaskWrapper.D_FTP_DIR) {
waitList.add(tManager.getGroupWrapper(DGTaskWrapper.class, e.getId()));
}
}
}
} else if (type == 3) { //普通上传任务
List<UploadEntity> dEntities = DbEntity.findDatas(UploadEntity.class, "state=?", "3");
if (dEntities != null && !dEntities.isEmpty()) {
for (UploadEntity e : dEntities) {
waitList.add(tManager.getNormalTaskWrapper(UTaskWrapper.class, e.getId()));
}
}
}
return waitList;
}
private void handleTask(List<AbsTaskWrapper> waitList) {
for (AbsTaskWrapper wrapper : waitList) {
if (wrapper.getEntity() == null) continue;
AbsTask task = getTask(wrapper.getKey());
if (task != null) continue;
if (wrapper instanceof DTaskWrapper) {
if (wrapper.getRequestType() == ITaskWrapper.D_FTP
|| wrapper.getRequestType() == ITaskWrapper.U_FTP) {
wrapper.getOptionParams()
.setParams(IOptionConstant.ftpUrlEntity,
CommonUtil.getFtpUrlInfo(wrapper.getEntity().getKey()));
}
mQueue = DTaskQueue.getInstance();
} else if (wrapper instanceof UTaskWrapper) {
mQueue = UTaskQueue.getInstance();
} else if (wrapper instanceof DGTaskWrapper) {
mQueue = DGroupTaskQueue.getInstance();
}
createTask(wrapper);
}
}
} }
} }

@ -19,6 +19,7 @@ import com.arialyy.aria.core.command.NormalCmdFactory;
import com.arialyy.aria.core.event.EventMsgUtil; import com.arialyy.aria.core.event.EventMsgUtil;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper; import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.command.CmdHelper; import com.arialyy.aria.core.command.CmdHelper;
import com.arialyy.aria.util.ALog;
/** /**
* 创建任务时使用的控制器 * 创建任务时使用的控制器

@ -133,18 +133,8 @@ public class CheckDEntityUtil implements ICheckEntityUtil {
private boolean checkPathConflicts(String filePath) { private boolean checkPathConflicts(String filePath) {
//设置文件保存路径,如果新文件路径和旧文件路径不同,则修改路径 //设置文件保存路径,如果新文件路径和旧文件路径不同,则修改路径
if (!filePath.equals(mEntity.getFilePath())) { if (!filePath.equals(mEntity.getFilePath())) {
//if (DbEntity.checkDataExist(DownloadEntity.class, "downloadPath=?", filePath)) {
// if (!mWrapper.isForceDownload()) {
// ALog.e(TAG, String.format("下载失败,保存路径【%s】已经被其它任务占用,请设置其它保存路径", filePath));
// return false;
// } else {
// ALog.w(TAG, String.format("保存路径【%s】已经被其它任务占用,当前任务将覆盖该路径的文件", filePath));
// RecordUtil.delTaskRecord(filePath, IRecordHandler.TYPE_DOWNLOAD);
// }
//}
// 检查路径冲突 // 检查路径冲突
if (!CheckUtil.checkAndHandlePathConflicts(mWrapper.isForceDownload(), filePath)) { if (!CheckUtil.checkDownloadPathConflicts(mWrapper.isForceDownload(), filePath)) {
return false; return false;
} }

@ -42,14 +42,17 @@ class DGTaskWrapperFactory implements IGroupWrapperFactory<DownloadGroupEntity,
} }
@Override public DGTaskWrapper getGroupWrapper(long taskId) { @Override public DGTaskWrapper getGroupWrapper(long taskId) {
DGTaskWrapper wrapper;
if (taskId == -1) { if (taskId == -1) {
return new DGTaskWrapper(new DownloadGroupEntity()); wrapper = new DGTaskWrapper(new DownloadGroupEntity());
} }else {
DownloadGroupEntity entity = getOrCreateHttpDGEntity(taskId); DownloadGroupEntity entity = getOrCreateHttpDGEntity(taskId);
DGTaskWrapper wrapper = new DGTaskWrapper(entity); wrapper = new DGTaskWrapper(entity);
if (entity.getSubEntities() != null && !entity.getSubEntities().isEmpty()) { if (entity.getSubEntities() != null && !entity.getSubEntities().isEmpty()) {
wrapper.setSubTaskWrapper(DbDataHelper.createDGSubTaskWrapper(entity)); wrapper.setSubTaskWrapper(DbDataHelper.createDGSubTaskWrapper(entity));
}
} }
wrapper.setRequestType(wrapper.getEntity().getTaskType());
return wrapper; return wrapper;
} }

@ -45,11 +45,14 @@ class DTaskWrapperFactory implements INormalTEFactory<DownloadEntity, DTaskWrapp
* 通过下载地址创建任务实体 * 通过下载地址创建任务实体
*/ */
@Override public DTaskWrapper create(long taskId) { @Override public DTaskWrapper create(long taskId) {
DTaskWrapper wrapper;
if (taskId == -1) { if (taskId == -1) {
return new DTaskWrapper(new DownloadEntity()); wrapper = new DTaskWrapper(new DownloadEntity());
} else {
wrapper = new DTaskWrapper(getEntity(taskId));
} }
wrapper.setRequestType(wrapper.getEntity().getTaskType());
return new DTaskWrapper(getEntity(taskId)); return wrapper;
} }
/** /**

@ -17,6 +17,7 @@ package com.arialyy.aria.core.manager;
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.util.ALog;
/** /**
* Created by Aria.Lao on 2017/11/1. 任务实体工厂 * Created by Aria.Lao on 2017/11/1. 任务实体工厂
@ -38,10 +39,15 @@ class UTaskWrapperFactory implements INormalTEFactory<UploadEntity, UTaskWrapper
} }
@Override public UTaskWrapper create(long taskId) { @Override public UTaskWrapper create(long taskId) {
UTaskWrapper wrapper;
if (taskId == -1) { if (taskId == -1) {
return new UTaskWrapper(new UploadEntity()); wrapper = new UTaskWrapper(new UploadEntity());
} else {
wrapper = new UTaskWrapper(getUploadEntity(taskId));
} }
return new UTaskWrapper(getUploadEntity(taskId));
wrapper.setRequestType(wrapper.getEntity().getTaskType());
return wrapper;
} }
/** /**

@ -16,7 +16,6 @@
package com.arialyy.aria.core.upload; package com.arialyy.aria.core.upload;
import android.text.TextUtils; import android.text.TextUtils;
import com.arialyy.aria.core.common.ErrorCode;
import com.arialyy.aria.core.inf.ICheckEntityUtil; import com.arialyy.aria.core.inf.ICheckEntityUtil;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CheckUtil; import com.arialyy.aria.util.CheckUtil;
@ -60,6 +59,11 @@ public class CheckUEntityUtil implements ICheckEntityUtil {
return false; return false;
} }
// 检查路径冲突
if (!CheckUtil.checkUploadPathConflicts(mWrapper.isForceUpload(), filePath)) {
return false;
}
File file = new File(mEntity.getFilePath()); File file = new File(mEntity.getFilePath());
if (!file.exists()) { if (!file.exists()) {
ALog.e(TAG, "上传失败,文件【" + filePath + "】不存在"); ALog.e(TAG, "上传失败,文件【" + filePath + "】不存在");
@ -69,6 +73,7 @@ public class CheckUEntityUtil implements ICheckEntityUtil {
ALog.e(TAG, "上传失败,文件【" + filePath + "】不能是文件夹"); ALog.e(TAG, "上传失败,文件【" + filePath + "】不能是文件夹");
return false; return false;
} }
return true; return true;
} }

@ -19,7 +19,8 @@ import androidx.annotation.CheckResult;
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.inf.Suggest; import com.arialyy.aria.core.inf.Suggest;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper; import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
/** /**
@ -33,7 +34,7 @@ public class FtpBuilderTarget extends AbsBuilderTarget<FtpBuilderTarget> {
FtpBuilderTarget(String filePath) { FtpBuilderTarget(String filePath) {
mConfigHandler = new UNormalConfigHandler<>(this, -1); mConfigHandler = new UNormalConfigHandler<>(this, -1);
mConfigHandler.setFilePath(filePath); mConfigHandler.setFilePath(filePath);
getTaskWrapper().setRequestType(AbsTaskWrapper.U_FTP); getTaskWrapper().setRequestType(ITaskWrapper.U_FTP);
} }
/** /**
@ -48,6 +49,14 @@ public class FtpBuilderTarget extends AbsBuilderTarget<FtpBuilderTarget> {
return this; return this;
} }
/**
* 如果文件路径被其它任务占用删除其它任务
*/
public FtpBuilderTarget forceUpload() {
((UTaskWrapper)getTaskWrapper()).setForceUpload(true);
return this;
}
/** /**
* 设置登陆字符串编码ftps等参数 * 设置登陆字符串编码ftps等参数
*/ */

@ -20,7 +20,7 @@ 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.inf.Suggest; import com.arialyy.aria.core.inf.Suggest;
import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper; import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
/** /**
@ -32,7 +32,7 @@ public class FtpNormalTarget extends AbsNormalTarget<FtpNormalTarget> {
FtpNormalTarget(long taskId) { FtpNormalTarget(long taskId) {
mConfigHandler = new UNormalConfigHandler<>(this, taskId); mConfigHandler = new UNormalConfigHandler<>(this, taskId);
getTaskWrapper().setRequestType(AbsTaskWrapper.U_FTP); getTaskWrapper().setRequestType(ITaskWrapper.U_FTP);
} }
/** /**

@ -19,6 +19,7 @@ import androidx.annotation.CheckResult;
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.inf.Suggest; import com.arialyy.aria.core.inf.Suggest;
import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper; import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
/** /**
@ -60,4 +61,12 @@ public class HttpBuilderTarget extends AbsBuilderTarget<HttpBuilderTarget> {
getTaskWrapper().getOptionParams().setParams(option); getTaskWrapper().getOptionParams().setParams(option);
return this; return this;
} }
/**
* 如果文件路径被其它任务占用删除其它任务
*/
public HttpBuilderTarget forceUpload() {
((UTaskWrapper) getTaskWrapper()).setForceUpload(true);
return this;
}
} }

@ -1,4 +1,9 @@
## 开发日志 ## 开发日志
+ v_3.7.6
- 增加强制上传的api`forceUpload()`
- 修复for循环上传文件出现的问题
- 移除创建任务的500ms间隔限制
- 修复多线程读写时可能出现的`database is locked`的问题
+ v_3.7.5 (2019/11/10) + v_3.7.5 (2019/11/10)
- fix bug https://github.com/AriaLyy/Aria/issues/500 - fix bug https://github.com/AriaLyy/Aria/issues/500
- fix bug https://github.com/AriaLyy/Aria/issues/508 - fix bug https://github.com/AriaLyy/Aria/issues/508

@ -74,7 +74,7 @@ public class FtpDirInfoThread extends AbsFtpInfoThread<DownloadGroupEntity, DGTa
entity.setConvertFileSize(CommonUtil.formatFileSize(ftpFile.getSize())); entity.setConvertFileSize(CommonUtil.formatFileSize(ftpFile.getSize()));
entity.setFileSize(ftpFile.getSize()); entity.setFileSize(ftpFile.getSize());
//if(CheckUtil.checkAndHandlePathConflicts(mTaskWrapper.is)) //if(CheckUtil.checkDownloadPathConflicts(mTaskWrapper.is))
entity.insert(); entity.insert();

@ -43,7 +43,7 @@ public class FtpRecordAdapter extends AbsRecordHandlerAdapter {
if (record.isBlock) { if (record.isBlock) {
helper.handleBlockRecord(); helper.handleBlockRecord();
} else { } else {
helper.handleMutilRecord(); helper.handleMultiRecord();
} }
} else if (record.threadNum == 1) { } else if (record.threadNum == 1) {
helper.handleSingleThreadRecord(); helper.handleSingleThreadRecord();
@ -77,9 +77,7 @@ public class FtpRecordAdapter extends AbsRecordHandlerAdapter {
int requestType = getWrapper().getRequestType(); int requestType = getWrapper().getRequestType();
if (requestType == ITaskWrapper.D_FTP || requestType == ITaskWrapper.D_FTP_DIR) { if (requestType == ITaskWrapper.D_FTP || requestType == ITaskWrapper.D_FTP_DIR) {
record.isBlock = threadNum > 1 && Configuration.getInstance().downloadCfg.isUseBlock(); record.isBlock = Configuration.getInstance().downloadCfg.isUseBlock();
// 线程数为1,或者使用了分块,则认为是使用动态长度文件
record.isOpenDynamicFile = threadNum == 1 || record.isBlock;
} else { } else {
record.isBlock = false; record.isBlock = false;
} }

@ -83,7 +83,7 @@ final class FtpDThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
return; return;
} }
if (getThreadConfig().isOpenDynamicFile) { if (getThreadConfig().isBlock) {
readDynamicFile(is); readDynamicFile(is);
} else { } else {
readNormal(is); readNormal(is);

@ -49,7 +49,7 @@ public class HttpRecordAdapter extends AbsRecordHandlerAdapter {
if (record.isBlock) { if (record.isBlock) {
helper.handleBlockRecord(); helper.handleBlockRecord();
} else { } else {
helper.handleMutilRecord(); helper.handleMultiRecord();
} }
} else if (!getWrapper().isSupportBP()) { } else if (!getWrapper().isSupportBP()) {
helper.handleNoSupportBPRecord(); helper.handleNoSupportBPRecord();
@ -87,9 +87,7 @@ public class HttpRecordAdapter extends AbsRecordHandlerAdapter {
int requestType = getWrapper().getRequestType(); int requestType = getWrapper().getRequestType();
if (requestType == ITaskWrapper.D_FTP || requestType == ITaskWrapper.D_FTP_DIR if (requestType == ITaskWrapper.D_FTP || requestType == ITaskWrapper.D_FTP_DIR
|| requestType == ITaskWrapper.D_HTTP || requestType == ITaskWrapper.DG_HTTP) { || requestType == ITaskWrapper.D_HTTP || requestType == ITaskWrapper.DG_HTTP) {
record.isBlock = threadNum > 1 && Configuration.getInstance().downloadCfg.isUseBlock(); record.isBlock = Configuration.getInstance().downloadCfg.isUseBlock();
// 线程数为1,或者使用了分块,则认为是使用动态长度文件
record.isOpenDynamicFile = threadNum == 1 || record.isBlock;
} else { } else {
record.isBlock = false; record.isBlock = false;
} }

@ -103,7 +103,7 @@ final class HttpDThreadTaskAdapter extends BaseHttpThreadTaskAdapter {
is = new BufferedInputStream(ConnectionHelp.convertInputStream(conn)); is = new BufferedInputStream(ConnectionHelp.convertInputStream(conn));
if (mTaskOption.isChunked()) { if (mTaskOption.isChunked()) {
readChunked(is); readChunked(is);
} else if (getThreadConfig().isOpenDynamicFile) { } else if (getThreadConfig().isBlock) {
readDynamicFile(is); readDynamicFile(is);
} else { } else {
//创建可设置位置的文件 //创建可设置位置的文件

@ -56,7 +56,7 @@ public class M3U8RecordAdapter extends AbsRecordHandlerAdapter {
long currentProgress = 0; long currentProgress = 0;
int completeNum = 0; int completeNum = 0;
File targetFile = new File(mTaskRecord.filePath); File targetFile = new File(mTaskRecord.filePath);
if (!targetFile.exists()){ if (!targetFile.exists()) {
FileUtil.createFile(targetFile); FileUtil.createFile(targetFile);
} }
@ -117,17 +117,15 @@ public class M3U8RecordAdapter extends AbsRecordHandlerAdapter {
record.filePath = getEntity().getFilePath(); record.filePath = getEntity().getFilePath();
record.threadRecords = new ArrayList<>(); record.threadRecords = new ArrayList<>();
record.threadNum = threadNum; record.threadNum = threadNum;
record.isBlock = true;
int requestType = getWrapper().getRequestType(); int requestType = getWrapper().getRequestType();
if (requestType == ITaskWrapper.M3U8_VOD) { if (requestType == ITaskWrapper.M3U8_VOD) {
record.taskType = TaskRecord.TYPE_M3U8_VOD; record.taskType = TaskRecord.TYPE_M3U8_VOD;
record.isOpenDynamicFile = true;
record.bandWidth = mOption.getBandWidth();
} else if (requestType == ITaskWrapper.M3U8_LIVE) { } else if (requestType == ITaskWrapper.M3U8_LIVE) {
record.taskType = TaskRecord.TYPE_M3U8_LIVE; record.taskType = TaskRecord.TYPE_M3U8_LIVE;
record.isOpenDynamicFile = true;
record.bandWidth = mOption.getBandWidth();
} }
record.bandWidth = mOption.getBandWidth();
return record; return record;
} }

@ -100,7 +100,7 @@ public class M3U8ThreadTaskAdapter extends AbsThreadTaskAdapter {
is = new BufferedInputStream(ConnectionHelp.convertInputStream(conn)); is = new BufferedInputStream(ConnectionHelp.convertInputStream(conn));
if (mHttpTaskOption.isChunked()) { if (mHttpTaskOption.isChunked()) {
readChunked(is); readChunked(is);
} else if (getThreadConfig().isOpenDynamicFile) { } else if (getThreadConfig().isBlock) {
readDynamicFile(is); readDynamicFile(is);
} }
} catch (MalformedURLException e) { } catch (MalformedURLException e) {

@ -177,7 +177,6 @@ public class M3U8LiveLoader extends BaseM3U8Loader {
config.url = tsUrl; config.url = tsUrl;
config.tempFile = new File(getTsFilePath(cacheDir, indexId)); config.tempFile = new File(getTsFilePath(cacheDir, indexId));
config.isBlock = mRecord.isBlock; config.isBlock = mRecord.isBlock;
config.isOpenDynamicFile = mRecord.isOpenDynamicFile;
config.taskWrapper = mTaskWrapper; config.taskWrapper = mTaskWrapper;
config.record = record; config.record = record;
config.stateHandler = mStateHandler; config.stateHandler = mStateHandler;

@ -436,7 +436,6 @@ public class M3U8VodLoader extends BaseM3U8Loader {
config.url = record.tsUrl; config.url = record.tsUrl;
config.tempFile = new File(BaseM3U8Loader.getTsFilePath(cacheDir, record.threadId)); config.tempFile = new File(BaseM3U8Loader.getTsFilePath(cacheDir, record.threadId));
config.isBlock = mRecord.isBlock; config.isBlock = mRecord.isBlock;
config.isOpenDynamicFile = mRecord.isOpenDynamicFile;
config.taskWrapper = mTaskWrapper; config.taskWrapper = mTaskWrapper;
config.record = record; config.record = record;
config.stateHandler = mStateHandler; config.stateHandler = mStateHandler;

@ -78,12 +78,6 @@ public class TaskRecord extends DbEntity {
*/ */
public boolean isBlock = false; public boolean isBlock = false;
/**
* 是否是使用虚拟文件下载的
* {@code true}{@code false}不是
*/
public boolean isOpenDynamicFile = false;
/** /**
* 线程类型 * 线程类型
* {@link #TYPE_HTTP_FTP}{@link #TYPE_M3U8_VOD} * {@link #TYPE_HTTP_FTP}{@link #TYPE_M3U8_VOD}

@ -125,7 +125,6 @@ public class RecordHandler implements IRecordHandler {
} }
mTaskWrapper.setNewTask(false); mTaskWrapper.setNewTask(false);
mTaskRecord = mAdapter.createTaskRecord(threadNum); mTaskRecord = mAdapter.createTaskRecord(threadNum);
mTaskRecord.isOpenDynamicFile = false;
mTaskRecord.isBlock = false; mTaskRecord.isBlock = false;
File tempFile = new File(getFilePath()); File tempFile = new File(getFilePath());
for (int i = 0; i < threadNum; i++) { for (int i = 0; i < threadNum; i++) {

@ -45,13 +45,13 @@ public class RecordHelper {
/** /**
* 处理非分块的多线程任务 * 处理非分块的多线程任务
*/ */
public void handleMutilRecord() { public void handleMultiRecord() {
// 默认线程分块长度 // 默认线程分块长度
long blockSize = mWrapper.getEntity().getFileSize() / mTaskRecord.threadRecords.size(); long blockSize = mWrapper.getEntity().getFileSize() / mTaskRecord.threadRecords.size();
File temp = new File(mTaskRecord.filePath); File temp = new File(mTaskRecord.filePath);
boolean fileExists = false; boolean fileExists = false;
if (!temp.exists()) { if (!temp.exists()) {
BufferedRandomAccessFile tempFile = null; BufferedRandomAccessFile tempFile;
try { try {
tempFile = new BufferedRandomAccessFile(temp, "rw"); tempFile = new BufferedRandomAccessFile(temp, "rw");
tempFile.setLength(mWrapper.getEntity().getFileSize()); tempFile.setLength(mWrapper.getEntity().getFileSize());
@ -145,10 +145,10 @@ public class RecordHelper {
tr.startLocation = 0; tr.startLocation = 0;
tr.isComplete = false; tr.isComplete = false;
tr.endLocation = mWrapper.getEntity().getFileSize(); tr.endLocation = mWrapper.getEntity().getFileSize();
} else if (mTaskRecord.isOpenDynamicFile) { } else if (mTaskRecord.isBlock) {
if (file.length() > mWrapper.getEntity().getFileSize()) { if (file.length() > mWrapper.getEntity().getFileSize()) {
ALog.i(TAG, String.format("文件【%s】错误,任务重新开始", file.getPath())); ALog.i(TAG, String.format("文件【%s】错误,任务重新开始", file.getPath()));
file.delete(); FileUtil.deleteFile(file);
tr.startLocation = 0; tr.startLocation = 0;
tr.isComplete = false; tr.isComplete = false;
tr.endLocation = mWrapper.getEntity().getFileSize(); tr.endLocation = mWrapper.getEntity().getFileSize();

@ -35,8 +35,6 @@ public class SubThreadConfig {
public ThreadRecord record; public ThreadRecord record;
// 状态处理器 // 状态处理器
public Handler stateHandler; public Handler stateHandler;
// 动态文件
public boolean isOpenDynamicFile;
// m3u8切片索引 // m3u8切片索引
public int peerIndex; public int peerIndex;
} }

@ -16,6 +16,7 @@
package com.arialyy.aria.core.download; package com.arialyy.aria.core.download;
import android.os.Parcel; import android.os.Parcel;
import android.text.TextUtils;
import com.arialyy.aria.core.common.AbsGroupEntity; import com.arialyy.aria.core.common.AbsGroupEntity;
import com.arialyy.aria.core.wrapper.ITaskWrapper; import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.orm.annotation.Ignore; import com.arialyy.aria.orm.annotation.Ignore;
@ -48,7 +49,12 @@ public class DownloadGroupEntity extends AbsGroupEntity {
} }
@Override public int getTaskType() { @Override public int getTaskType() {
return getKey().startsWith("ftp") ? ITaskWrapper.D_FTP_DIR : ITaskWrapper.DG_HTTP; if (getSubEntities() == null || getSubEntities().isEmpty() || TextUtils.isEmpty(
getSubEntities().get(0).getUrl())) {
return ITaskWrapper.ERROR;
}
return getSubEntities().get(0).getUrl().startsWith("ftp") ? ITaskWrapper.D_FTP_DIR
: ITaskWrapper.DG_HTTP;
} }
public DownloadGroupEntity() { public DownloadGroupEntity() {

@ -142,7 +142,6 @@ public class NormalLoader extends AbsLoader {
String.format(IRecordHandler.SUB_PATH, mTempFile.getPath(), record.threadId)) String.format(IRecordHandler.SUB_PATH, mTempFile.getPath(), record.threadId))
: mTempFile; : mTempFile;
config.isBlock = mRecord.isBlock; config.isBlock = mRecord.isBlock;
config.isOpenDynamicFile = mRecord.isOpenDynamicFile;
config.startThreadNum = startNum; config.startThreadNum = startNum;
config.taskWrapper = mTaskWrapper; config.taskWrapper = mTaskWrapper;
config.record = record; config.record = record;

@ -463,8 +463,6 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
if (mRecord != null) { if (mRecord != null) {
mRecord.isComplete = isComplete; mRecord.isComplete = isComplete;
if (mConfig.isBlock) { if (mConfig.isBlock) {
mRecord.startLocation = record;
} else if (mConfig.isOpenDynamicFile) {
mRecord.startLocation = mConfig.tempFile.length(); mRecord.startLocation = mConfig.tempFile.length();
} else { } else {
if (0 < record && record < mRecord.endLocation) { if (0 < record && record < mRecord.endLocation) {

@ -29,6 +29,11 @@ public class UTaskWrapper extends AbsTaskWrapper<UploadEntity> {
*/ */
private String tempUrl; private String tempUrl;
/**
* 如果文件路径被其它任务占用设置为true时删除其它任务
*/
private boolean forceUpload = false;
public UTaskWrapper(UploadEntity entity) { public UTaskWrapper(UploadEntity entity) {
super(entity); super(entity);
} }
@ -48,6 +53,14 @@ public class UTaskWrapper extends AbsTaskWrapper<UploadEntity> {
return getEntity().getKey(); return getEntity().getKey();
} }
public boolean isForceUpload() {
return forceUpload;
}
public void setForceUpload(boolean forceUpload) {
this.forceUpload = forceUpload;
}
@Override public UploadConfig getConfig() { @Override public UploadConfig getConfig() {
return Configuration.getInstance().uploadCfg; return Configuration.getInstance().uploadCfg;
} }

@ -17,6 +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.core.wrapper.ITaskWrapper;
import com.arialyy.aria.orm.annotation.Primary; import com.arialyy.aria.orm.annotation.Primary;
@ -58,7 +59,10 @@ public class UploadEntity extends AbsNormalEntity implements Parcelable {
} }
@Override public int getTaskType() { @Override public int getTaskType() {
return getUrl().startsWith("ftp") ? ITaskWrapper.D_FTP : ITaskWrapper.D_HTTP; if (TextUtils.isEmpty(getUrl())){
return ITaskWrapper.ERROR;
}
return getUrl().startsWith("ftp") ? ITaskWrapper.U_FTP : ITaskWrapper.U_HTTP;
} }
public UploadEntity() { public UploadEntity() {

@ -24,6 +24,7 @@ import com.arialyy.aria.core.event.ErrorEvent;
import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.ITaskOption; import com.arialyy.aria.core.inf.ITaskOption;
import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.ComponentUtil; import com.arialyy.aria.util.ComponentUtil;
/** /**

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

@ -76,9 +76,6 @@ final class SqlHelper extends SQLiteOpenHelper {
// 需要使用如下语句: // 需要使用如下语句:
db.execSQL("PRAGMA foreign_keys=ON;"); db.execSQL("PRAGMA foreign_keys=ON;");
} }
if (DBConfig.DEBUG) {
db.enableWriteAheadLogging();
}
} }
@Override public void onCreate(SQLiteDatabase db) { @Override public void onCreate(SQLiteDatabase db) {
@ -139,6 +136,7 @@ final class SqlHelper extends SQLiteOpenHelper {
SQLiteDatabase.CREATE_IF_NECESSARY); SQLiteDatabase.CREATE_IF_NECESSARY);
} }
} }
db.enableWriteAheadLogging();
return db; return db;
} }

@ -19,6 +19,7 @@ package com.arialyy.aria.util;
import android.text.TextUtils; import android.text.TextUtils;
import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadEntity;
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.orm.DbEntity; import com.arialyy.aria.orm.DbEntity;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.List; import java.util.List;
@ -37,7 +38,7 @@ public class CheckUtil {
* @param filePath 文件保存路径 * @param filePath 文件保存路径
* @return false 任务不再执行true 任务继续执行 * @return false 任务不再执行true 任务继续执行
*/ */
public static boolean checkAndHandlePathConflicts(boolean isForceDownload, String filePath) { public static boolean checkDownloadPathConflicts(boolean isForceDownload, String filePath) {
if (DbEntity.checkDataExist(DownloadEntity.class, "downloadPath=?", filePath)) { if (DbEntity.checkDataExist(DownloadEntity.class, "downloadPath=?", filePath)) {
if (!isForceDownload) { if (!isForceDownload) {
ALog.e(TAG, String.format("下载失败,保存路径【%s】已经被其它任务占用,请设置其它保存路径", filePath)); ALog.e(TAG, String.format("下载失败,保存路径【%s】已经被其它任务占用,请设置其它保存路径", filePath));
@ -51,6 +52,27 @@ public class CheckUtil {
return true; return true;
} }
/**
* 检查和处理路径冲突
*
* @param isForceUpload true如果路径冲突将删除其它任务的记录的
* @param filePath 文件保存路径
* @return false 任务不再执行true 任务继续执行
*/
public static boolean checkUploadPathConflicts(boolean isForceUpload, String filePath) {
if (DbEntity.checkDataExist(UploadEntity.class, "filePath=?", filePath)) {
if (!isForceUpload) {
ALog.e(TAG, String.format("上传失败,文件路径【%s】已经被其它任务占用,请设置其它保存路径", filePath));
return false;
} else {
ALog.w(TAG, String.format("文件路径【%s】已经被其它任务占用,当前任务将覆盖该路径的文件", filePath));
RecordUtil.delTaskRecord(filePath, IRecordHandler.TYPE_UPLOAD);
return true;
}
}
return true;
}
/** /**
* 检查成员类是否是静态和public * 检查成员类是否是静态和public
*/ */

@ -101,6 +101,9 @@ public class ComponentUtil {
public <T extends IUtil> T buildUtil(AbsTaskWrapper wrapper, IEventListener listener) { public <T extends IUtil> T buildUtil(AbsTaskWrapper wrapper, IEventListener listener) {
int requestType = wrapper.getRequestType(); int requestType = wrapper.getRequestType();
String className = null; String className = null;
if (requestType == 1){
throw new IllegalArgumentException("xxxx");
}
switch (requestType) { switch (requestType) {
case ITaskWrapper.M3U8_LIVE: case ITaskWrapper.M3U8_LIVE:
className = "com.arialyy.aria.m3u8.live.M3U8LiveUtil"; className = "com.arialyy.aria.m3u8.live.M3U8LiveUtil";

@ -50,17 +50,7 @@ public class ErrorHelp {
CommonUtil.getAppPath(AriaConfig.getInstance().getAPP()), CommonUtil.getAppPath(AriaConfig.getInstance().getAPP()),
getData("yyyy-MM-dd_HH_mm_ss")); getData("yyyy-MM-dd_HH_mm_ss"));
File log = new File(path); FileUtil.createFile(path);
if (!log.getParentFile().exists()) {
log.getParentFile().mkdirs();
}
if (!log.exists()) {
try {
log.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
return path; return path;
} }

@ -128,7 +128,7 @@ public class RecordUtil {
filePath = ((DownloadEntity) entity).getDownloadPath(); filePath = ((DownloadEntity) entity).getDownloadPath();
} else if (entity instanceof UploadEntity) { } else if (entity instanceof UploadEntity) {
type = IRecordHandler.TYPE_UPLOAD; type = IRecordHandler.TYPE_UPLOAD;
filePath = ((UploadEntity) entity).getFilePath(); filePath = entity.getFilePath();
} else { } else {
ALog.w(TAG, "删除记录失败,未知类型"); ALog.w(TAG, "删除记录失败,未知类型");
return; return;

@ -34,6 +34,7 @@ public class HttpDownloadModule extends BaseViewModule {
private final String defUrl = private final String defUrl =
"http://hzdown.muzhiwan.com/2017/05/08/nl.noio.kingdom_59104935e56f0.apk"; "http://hzdown.muzhiwan.com/2017/05/08/nl.noio.kingdom_59104935e56f0.apk";
//"https://ss1.baidu.com/-4o3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/sign=a9e671b9a551f3dedcb2bf64a4eff0ec/4610b912c8fcc3cef70d70409845d688d53f20f7.jpg";
//"http://9.9.9.205:5000/download/Cyberduck-6.9.4.30164.zip"; //"http://9.9.9.205:5000/download/Cyberduck-6.9.4.30164.zip";
//"http://202.98.201.103:7000/vrs/TPK/ZTC440402001Z.tpk"; //"http://202.98.201.103:7000/vrs/TPK/ZTC440402001Z.tpk";
private final String defFilePath = private final String defFilePath =
@ -51,6 +52,7 @@ public class HttpDownloadModule extends BaseViewModule {
//String url = //String url =
// "http://sdkdown.muzhiwan.com/openfile/2019/05/21/com.netease.tom.mzw_5ce3ef8754d05.apk"; // "http://sdkdown.muzhiwan.com/openfile/2019/05/21/com.netease.tom.mzw_5ce3ef8754d05.apk";
String url = "http://image.totwoo.com/totwoo-TOTWOO-v3.5.6.apk"; String url = "http://image.totwoo.com/totwoo-TOTWOO-v3.5.6.apk";
//String url = "https://ss1.baidu.com/-4o3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/sign=a9e671b9a551f3dedcb2bf64a4eff0ec/4610b912c8fcc3cef70d70409845d688d53f20f7.jpg";
String filePath = AppUtil.getConfigValue(context, HTTP_PATH_KEY, defFilePath); String filePath = AppUtil.getConfigValue(context, HTTP_PATH_KEY, defFilePath);
singDownloadInfo = Aria.download(context).getFirstDownloadEntity(url); singDownloadInfo = Aria.download(context).getFirstDownloadEntity(url);

@ -18,6 +18,7 @@ package com.arialyy.simple.core.upload;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -40,6 +41,8 @@ import com.arialyy.simple.databinding.ActivityFtpUploadBinding;
import com.arialyy.simple.util.AppUtil; import com.arialyy.simple.util.AppUtil;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/** /**
* Created by lyy on 2017/7/28. Ftp 文件上传demo * Created by lyy on 2017/7/28. Ftp 文件上传demo
@ -111,26 +114,26 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
public void onClick(View view) { public void onClick(View view) {
switch (view.getId()) { switch (view.getId()) {
case R.id.start: case R.id.start:
if (mTaskId == -1) { //if (mTaskId == -1) {
mTaskId = Aria.upload(this) // mTaskId = Aria.upload(this)
.loadFtp(mFilePath) // .loadFtp(mFilePath)
.setUploadUrl(mUrl) // .setUploadUrl(mUrl)
.option(getOption()) // .option(getOption())
.create(); // .create();
getBinding().setStateStr(getString(R.string.stop)); // getBinding().setStateStr(getString(R.string.stop));
break; // break;
} //}
if (Aria.upload(this).loadFtp(mTaskId).isRunning()) { //if (Aria.upload(this).loadFtp(mTaskId).isRunning()) {
Aria.upload(this).loadFtp(mTaskId).stop(); // Aria.upload(this).loadFtp(mTaskId).stop();
getBinding().setStateStr(getString(R.string.resume)); // getBinding().setStateStr(getString(R.string.resume));
} else { //} else {
Aria.upload(this) // Aria.upload(this)
.loadFtp(mTaskId) // .loadFtp(mTaskId)
.option(getOption()) // .option(getOption())
.resume(); // .resume();
getBinding().setStateStr(getString(R.string.stop)); // getBinding().setStateStr(getString(R.string.stop));
} //}
upload();
break; break;
case R.id.cancel: case R.id.cancel:
Aria.upload(this).loadFtp(mTaskId).cancel(); Aria.upload(this).loadFtp(mTaskId).cancel();
@ -140,6 +143,28 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
} }
} }
private void upload() {
List<String> paths = new ArrayList<>();
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/1.jpg");
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/2.jpg");
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/3.jpg");
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/4.jpg");
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/5.jpg");
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/6.jpg");
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/7.jpg");
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/8.jpg");
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/9.jpg");
paths.add(Environment.getExternalStorageDirectory().getPath() + "/Download/img/img/10.jpg");
for (String path : paths) {
Aria.upload(this)
.loadFtp(path)
.setUploadUrl(mUrl)
.option(getOption())
.forceUpload()
.create();
}
}
private FtpOption getOption() { private FtpOption getOption() {
FtpOption option = new FtpOption(); FtpOption option = new FtpOption();
option.login(user, pwd); option.login(user, pwd);

Loading…
Cancel
Save