修复组合任务初始化失败时,无法删除的问题

修复`reStart()`后,无法停止的问题
ftp增加主动模式,开启主动模式:https://aria.laoyuyu.me/aria_doc/api/ftp_params.html
优化提示
This commit is contained in:
laoyuyu
2019-12-16 20:18:45 +08:00
parent f3d5e0135a
commit 0d93953cd9
33 changed files with 446 additions and 197 deletions

View File

@@ -15,9 +15,9 @@
*/
package com.arialyy.aria.core.command;
import com.arialyy.aria.core.inf.TaskSchedulerType;
import com.arialyy.aria.core.task.AbsTask;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.inf.TaskSchedulerType;
/**
* 重新开始任务命令
@@ -34,8 +34,8 @@ final class ReStartCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
task = createTask();
}
if (task != null) {
task.cancel(TaskSchedulerType.TYPE_CANCEL_AND_NOT_NOTIFY);
task.start(TaskSchedulerType.TYPE_START_AND_RESET_STATE);
mQueue.cancelTask(task, TaskSchedulerType.TYPE_CANCEL_AND_NOT_NOTIFY);
mQueue.startTask(task, TaskSchedulerType.TYPE_START_AND_RESET_STATE);
}
}
}

View File

@@ -202,8 +202,8 @@ public abstract class AbsNormalTarget<TARGET extends AbsNormalTarget> extends Ab
* 重新下载
*/
@Override
public void reStart() {
getController().reStart();
public long reStart() {
return getController().reStart();
}
@Override

View File

@@ -33,6 +33,9 @@ public class FtpOption extends BaseOption {
private String protocol, keyAlias, storePass, storePath;
private boolean isImplicit = true;
private IFtpUploadInterceptor uploadInterceptor;
private int connMode = FtpConnectionMode.DATA_CONNECTION_MODE_PASV;
private int minPort, maxPort;
private String activeExternalIPAddress;
public FtpOption() {
super();
@@ -143,6 +146,63 @@ public class FtpOption extends BaseOption {
return this;
}
/**
* 设置数据传输模式,默认为被动模式。
* 主动模式传输文件时客户端开启一个端口ftp服务器连接到客户端的该端口ftp服务器推送数据到客户端
* 被动模式传输文件时ftp服务器开启一个端口客户端连接到ftp服务器的这个端口客户端请求ftp服务器的数据
* 请注意主动模式是服务器主动连接到android如果使用住的模式请确保ftp服务器能ping通android
*
* @param connMode {@link FtpConnectionMode#DATA_CONNECTION_MODE_PASV},
* {@link FtpConnectionMode#DATA_CONNECTION_MODE_ACTIVITY}
*/
public FtpOption setConnectionMode(int connMode) {
if (connMode != FtpConnectionMode.DATA_CONNECTION_MODE_PASV
&& connMode != FtpConnectionMode.DATA_CONNECTION_MODE_ACTIVITY) {
ALog.e(TAG, "连接模式设置失败,默认启用被动模式");
return this;
}
this.connMode = connMode;
return this;
}
/**
* 主动模式下的端口范围
*/
public FtpOption setActivePortRange(int minPort, int maxPort) {
if (minPort > maxPort) {
ALog.e(TAG, "设置端口范围错误minPort > maxPort");
return this;
}
if (minPort <= 0 || minPort >= 65535) {
ALog.e(TAG, "端口范围错误");
return this;
}
if (maxPort >= 65535) {
ALog.e(TAG, "端口范围错误");
return this;
}
this.minPort = minPort;
this.maxPort = maxPort;
return this;
}
/**
* 主动模式下对外ip可被Ftp服务器访问的ip
*/
public FtpOption setActiveExternalIPAddress(String ip) {
if (TextUtils.isEmpty(ip)) {
ALog.e(TAG, "ip为空");
return this;
}
if (!CheckUtil.checkIp(ip)) {
ALog.e(TAG, "ip地址错误" + ip);
return this;
}
this.activeExternalIPAddress = ip;
return this;
}
public void setUrlEntity(FtpUrlEntity urlEntity) {
this.urlEntity = urlEntity;
urlEntity.needLogin = isNeedLogin;

View File

@@ -15,11 +15,10 @@
*/
package com.arialyy.aria.core.common.controller;
import com.arialyy.aria.core.command.CmdHelper;
import com.arialyy.aria.core.command.NormalCmdFactory;
import com.arialyy.aria.core.event.EventMsgUtil;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.command.CmdHelper;
import com.arialyy.aria.util.ALog;
/**
* 创建任务时使用的控制器
@@ -36,6 +35,7 @@ public final class BuilderController extends FeatureController implements IStart
* @return 正常添加返回任务id否则返回-1
*/
public long add() {
setAction(ACTION_ADD);
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CmdHelper.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_CREATE,
@@ -51,17 +51,18 @@ public final class BuilderController extends FeatureController implements IStart
* @return 正常启动返回任务id否则返回-1
*/
public long create() {
setAction(ACTION_CREATE);
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CmdHelper.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_START,
checkTaskType()));
return getEntity().getId();
}
return -1;
}
@Override public long setHighestPriority() {
setAction(ACTION_PRIORITY);
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CmdHelper.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_HIGHEST_PRIORITY,

View File

@@ -43,6 +43,17 @@ import java.lang.reflect.InvocationTargetException;
* 功能控制器
*/
public abstract class FeatureController {
private static final int ACTION_DEF = 0;
public static final int ACTION_CREATE = 1;
public static final int ACTION_RESUME = 2;
public static final int ACTION_STOP = 3;
public static final int ACTION_CANCEL = 4;
public static final int ACTION_ADD = 5;
public static final int ACTION_PRIORITY = 6;
public static final int ACTION_RETRY = 7;
public static final int ACTION_RESTART = 8;
public static final int ACTION_SAVE = 9;
private final String TAG;
private AbsTaskWrapper mTaskWrapper;
@@ -50,6 +61,7 @@ public abstract class FeatureController {
* 是否忽略权限检查 true 忽略权限检查
*/
private boolean ignoreCheckPermissions = false;
private int action = ACTION_DEF;
FeatureController(AbsTaskWrapper wrapper) {
mTaskWrapper = wrapper;
@@ -91,6 +103,10 @@ public abstract class FeatureController {
return null;
}
void setAction(int action) {
this.action = action;
}
/**
* 是否忽略权限检查
*/
@@ -180,15 +196,15 @@ public abstract class FeatureController {
private boolean checkEntity() {
ICheckEntityUtil checkUtil = null;
if (mTaskWrapper instanceof DTaskWrapper) {
checkUtil = CheckDEntityUtil.newInstance((DTaskWrapper) mTaskWrapper);
checkUtil = CheckDEntityUtil.newInstance((DTaskWrapper) mTaskWrapper, action);
} else if (mTaskWrapper instanceof DGTaskWrapper) {
if (mTaskWrapper.getRequestType() == ITaskWrapper.D_FTP_DIR) {
checkUtil = CheckFtpDirEntityUtil.newInstance((DGTaskWrapper) mTaskWrapper);
checkUtil = CheckFtpDirEntityUtil.newInstance((DGTaskWrapper) mTaskWrapper, action);
} else if (mTaskWrapper.getRequestType() == ITaskWrapper.DG_HTTP) {
checkUtil = CheckDGEntityUtil.newInstance((DGTaskWrapper) mTaskWrapper);
checkUtil = CheckDGEntityUtil.newInstance((DGTaskWrapper) mTaskWrapper, action);
}
} else if (mTaskWrapper instanceof UTaskWrapper) {
checkUtil = CheckUEntityUtil.newInstance((UTaskWrapper) mTaskWrapper);
checkUtil = CheckUEntityUtil.newInstance((UTaskWrapper) mTaskWrapper, action);
}
return checkUtil != null && checkUtil.checkEntity();
}

View File

@@ -59,7 +59,7 @@ public interface INormalFeature {
/**
* 重新下载
*/
void reStart();
long reStart();
/**
* 保存数据

View File

@@ -38,6 +38,7 @@ public final class NormalController extends FeatureController implements INormal
*/
@Override
public void stop() {
setAction(ACTION_STOP);
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CmdHelper.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_STOP,
@@ -60,6 +61,7 @@ public final class NormalController extends FeatureController implements INormal
* @param newStart true 立即将任务恢复到执行队列中
*/
@Override public void resume(boolean newStart) {
setAction(ACTION_RESUME);
if (checkConfig()) {
StartCmd cmd =
(StartCmd) CmdHelper.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_START,
@@ -75,11 +77,7 @@ public final class NormalController extends FeatureController implements INormal
*/
@Override
public void cancel() {
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CmdHelper.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_CANCEL,
checkTaskType()));
}
cancel(false);
}
/**
@@ -87,6 +85,7 @@ public final class NormalController extends FeatureController implements INormal
*/
@Override
public void reTry() {
setAction(ACTION_RETRY);
if (checkConfig()) {
int taskType = checkTaskType();
EventMsgUtil.getDefault()
@@ -105,6 +104,7 @@ public final class NormalController extends FeatureController implements INormal
*/
@Override
public void cancel(boolean removeFile) {
setAction(ACTION_CANCEL);
if (checkConfig()) {
CancelCmd cancelCmd =
(CancelCmd) CmdHelper.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_CANCEL,
@@ -118,15 +118,19 @@ public final class NormalController extends FeatureController implements INormal
* 重新下载
*/
@Override
public void reStart() {
public long reStart() {
setAction(ACTION_RESTART);
if (checkConfig()) {
EventMsgUtil.getDefault()
.post(CmdHelper.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_RESTART,
checkTaskType()));
return getEntity().getId();
}
return -1;
}
@Override public void save() {
setAction(ACTION_SAVE);
if (!checkConfig()) {
ALog.e(TAG, "保存修改失败");
} else {

View File

@@ -16,6 +16,7 @@
package com.arialyy.aria.core.download;
import android.text.TextUtils;
import com.arialyy.aria.core.common.controller.FeatureController;
import com.arialyy.aria.core.inf.ICheckEntityUtil;
import com.arialyy.aria.core.inf.IOptionConstant;
import com.arialyy.aria.core.inf.ITargetHandler;
@@ -34,12 +35,14 @@ public class CheckDEntityUtil implements ICheckEntityUtil {
private final String TAG = CommonUtil.getClassName(getClass());
private DTaskWrapper mWrapper;
private DownloadEntity mEntity;
private int action;
public static CheckDEntityUtil newInstance(DTaskWrapper wrapper) {
return new CheckDEntityUtil(wrapper);
public static CheckDEntityUtil newInstance(DTaskWrapper wrapper, int action) {
return new CheckDEntityUtil(wrapper, action);
}
private CheckDEntityUtil(DTaskWrapper wrapper) {
private CheckDEntityUtil(DTaskWrapper wrapper, int action) {
this.action = action;
mWrapper = wrapper;
mEntity = mWrapper.getEntity();
}
@@ -80,19 +83,22 @@ public class CheckDEntityUtil implements ICheckEntityUtil {
} else {
m3U8Entity.update();
}
if (mWrapper.getRequestType() == ITaskWrapper.M3U8_VOD) {
if (mWrapper.getRequestType() == ITaskWrapper.M3U8_VOD
&& action == FeatureController.ACTION_CREATE) {
if (mEntity.getFileSize() == 0) {
ALog.w(TAG,
"由于m3u8协议的特殊性质无法有效快速获取到正确到文件长度如果你需要显示文件中长度你需要自行设置文件长度.asM3U8().asVod().setFileSize(xxx)");
}
} else if (mWrapper.getRequestType() == ITaskWrapper.M3U8_LIVE) {
} else if (mWrapper.getRequestType() == ITaskWrapper.M3U8_LIVE
&& action != FeatureController.ACTION_CANCEL) {
if (file.exists()) {
ALog.w(TAG, "对于直播来说每次下载都是一个新文件所以你需要设置新都文件路径否则Aria框架将会覆盖已下载的文件");
file.delete();
}
}
if (mWrapper.getM3U8Params().getHandler(IOptionConstant.bandWidthUrlConverter) != null
if (action != FeatureController.ACTION_CANCEL
&& mWrapper.getM3U8Params().getHandler(IOptionConstant.bandWidthUrlConverter) != null
&& bandWidth == 0) {
ALog.w(TAG, "你已经设置了码率url转换器但是没有设置码率Aria框架将采用第一个获取到的码率");
}

View File

@@ -17,6 +17,7 @@ package com.arialyy.aria.core.download;
import android.text.TextUtils;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.common.controller.FeatureController;
import com.arialyy.aria.core.inf.ICheckEntityUtil;
import com.arialyy.aria.core.inf.IOptionConstant;
import com.arialyy.aria.orm.DbEntity;
@@ -41,12 +42,14 @@ public class CheckDGEntityUtil implements ICheckEntityUtil {
* 是否需要修改路径
*/
private boolean needModifyPath = false;
private int action;
public static CheckDGEntityUtil newInstance(DGTaskWrapper wrapper) {
return new CheckDGEntityUtil(wrapper);
public static CheckDGEntityUtil newInstance(DGTaskWrapper wrapper, int action) {
return new CheckDGEntityUtil(wrapper, action);
}
private CheckDGEntityUtil(DGTaskWrapper wrapper) {
private CheckDGEntityUtil(DGTaskWrapper wrapper, int action) {
this.action = action;
mWrapper = wrapper;
mEntity = mWrapper.getEntity();
}
@@ -129,7 +132,9 @@ public class CheckDGEntityUtil implements ICheckEntityUtil {
return false;
}
if (!mWrapper.isUnknownSize() && mEntity.getFileSize() == 0) {
if (action != FeatureController.ACTION_CANCEL
&& !mWrapper.isUnknownSize()
&& mEntity.getFileSize() == 0) {
ALog.e(TAG, "组合任务必须设置文件文件大小,默认需要强制设置文件大小。如果无法获取到总长度,请调用#unknownSize()来标志该组合任务");
return false;
}

View File

@@ -17,7 +17,6 @@ package com.arialyy.aria.core.download;
import android.text.TextUtils;
import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.common.ErrorCode;
import com.arialyy.aria.core.inf.ICheckEntityUtil;
import com.arialyy.aria.core.inf.IOptionConstant;
import com.arialyy.aria.orm.DbEntity;
@@ -28,12 +27,14 @@ public class CheckFtpDirEntityUtil implements ICheckEntityUtil {
private final String TAG = "CheckFtpDirEntityUtil";
private DGTaskWrapper mWrapper;
private DownloadGroupEntity mEntity;
private int action;
public static CheckFtpDirEntityUtil newInstance(DGTaskWrapper wrapper) {
return new CheckFtpDirEntityUtil(wrapper);
public static CheckFtpDirEntityUtil newInstance(DGTaskWrapper wrapper, int action) {
return new CheckFtpDirEntityUtil(wrapper, action);
}
private CheckFtpDirEntityUtil(DGTaskWrapper wrapper) {
private CheckFtpDirEntityUtil(DGTaskWrapper wrapper, int action) {
this.action = action;
mWrapper = wrapper;
mEntity = mWrapper.getEntity();
}

View File

@@ -16,10 +16,6 @@
package com.arialyy.aria.core.queue;
import com.arialyy.aria.core.task.DownloadGroupTask;
import com.arialyy.aria.core.task.DownloadTask;
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.TaskSchedulerType;
import com.arialyy.aria.core.manager.TaskWrapperManager;
@@ -29,7 +25,11 @@ import com.arialyy.aria.core.queue.pool.BaseExecutePool;
import com.arialyy.aria.core.queue.pool.DGLoadSharePool;
import com.arialyy.aria.core.queue.pool.DLoadSharePool;
import com.arialyy.aria.core.queue.pool.UploadSharePool;
import com.arialyy.aria.core.task.AbsTask;
import com.arialyy.aria.core.task.DownloadGroupTask;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.core.task.UploadTask;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.util.ALog;
/**
@@ -213,6 +213,10 @@ public abstract class AbsTaskQueue<TASK extends AbsTask, TASK_WRAPPER extends Ab
}
@Override public void startTask(TASK task) {
startTask(task, TaskSchedulerType.TYPE_DEFAULT);
}
@Override public void startTask(TASK task, int action) {
if (task == null) {
ALog.w(TAG, "create fail, task is null");
}
@@ -223,7 +227,7 @@ public abstract class AbsTaskQueue<TASK extends AbsTask, TASK_WRAPPER extends Ab
mCachePool.removeTask(task);
mExecutePool.putTask(task);
task.getTaskWrapper().getEntity().setFailNum(0);
task.start();
task.start(action);
}
@Override public void stopTask(TASK task) {
@@ -312,7 +316,11 @@ public abstract class AbsTaskQueue<TASK extends AbsTask, TASK_WRAPPER extends Ab
}
@Override public void cancelTask(TASK task) {
task.cancel();
cancelTask(task, TaskSchedulerType.TYPE_DEFAULT);
}
@Override public void cancelTask(TASK task, int action) {
task.cancel(action);
}
@Override public TASK getNextTask() {

View File

@@ -17,13 +17,14 @@
package com.arialyy.aria.core.queue;
import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.inf.TaskSchedulerType;
import com.arialyy.aria.core.task.DownloadGroupTask;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.task.ITask;
import com.arialyy.aria.core.task.UploadTask;
import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
/**
* Created by lyy on 2016/8/16. 任务功能接口
@@ -65,6 +66,13 @@ public interface ITaskQueue<TASK extends ITask, TASK_WRAPPER extends AbsTaskWrap
*/
void startTask(TASK task);
/**
* 开始任务
*
* @param action {@link TaskSchedulerType}
*/
void startTask(TASK task, int action);
/**
* 停止任务
*
@@ -73,12 +81,19 @@ public interface ITaskQueue<TASK extends ITask, TASK_WRAPPER extends AbsTaskWrap
void stopTask(TASK task);
/**
* 取消下载任务
* 取消任务
*
* @param task {@link DownloadTask}、{@link UploadTask}、{@link DownloadGroupTask}
*/
void cancelTask(TASK task);
/**
* 取消任务
*
* @param action {@link TaskSchedulerType}
*/
void cancelTask(TASK task, int action);
/**
* 通过key从队列中删除任务
*

View File

@@ -25,12 +25,14 @@ public class CheckUEntityUtil implements ICheckEntityUtil {
private final String TAG = "CheckUEntityUtil";
private UTaskWrapper mWrapper;
private UploadEntity mEntity;
private int action;
public static CheckUEntityUtil newInstance(UTaskWrapper wrapper) {
return new CheckUEntityUtil(wrapper);
public static CheckUEntityUtil newInstance(UTaskWrapper wrapper, int action) {
return new CheckUEntityUtil(wrapper, action);
}
private CheckUEntityUtil(UTaskWrapper wrapper) {
private CheckUEntityUtil(UTaskWrapper wrapper, int action) {
this.action = action;
mWrapper = wrapper;
mEntity = mWrapper.getEntity();
}