Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27c889e171 | ||
|
|
0d93953cd9 | ||
|
|
f3d5e0135a | ||
|
|
d9ed7f87d2 | ||
|
|
3871d8f056 | ||
|
|
669aa6981c | ||
|
|
91daecd039 | ||
|
|
297cc99f2b | ||
|
|
f5f8e9b528 | ||
|
|
94c3e8bb58 | ||
|
|
ee5ee6e080 | ||
|
|
c4cc804c67 | ||
|
|
c9c00c38c6 | ||
|
|
846235a826 | ||
|
|
06dd6b35e0 | ||
|
|
944d69a1af | ||
|
|
1ee36e0bc1 | ||
|
|
0765ab67f7 |
39
.github/ISSUE_TEMPLATE/Custom.md
vendored
39
.github/ISSUE_TEMPLATE/Custom.md
vendored
@@ -1,35 +1,26 @@
|
||||
---
|
||||
name: 问题描述
|
||||
about: 请详细描述你遇到的问题
|
||||
about: 提交问题前,请先阅读文档和搜索issue
|
||||
|
||||
---
|
||||
|
||||
<!-- 请详细描述以下信息,即使是一个简单的bug,没有充足的信息,作者却需要花费大量的时间去查找可能的原因!! -->
|
||||
|
||||
## 预期行为
|
||||
|
||||
|
||||
## 当前行为
|
||||
|
||||
|
||||
## 可能的解决方案
|
||||
<!-- 不是强制性的,针对该错误的修复/原因的建议-->
|
||||
|
||||
|
||||
## 重现步骤
|
||||
<!-- 请提供明确的步骤 -->
|
||||
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4.
|
||||
|
||||
|
||||
## 错误日志
|
||||
|
||||
<!-- 提交问题前,请先阅读文档和搜索相应问题的issue -->
|
||||
|
||||
## 版本
|
||||
* 框架版本
|
||||
|
||||
* 系统版本
|
||||
|
||||
## 错误日志
|
||||
<!-- 请提供详细的错误日志 -->
|
||||
|
||||
|
||||
## 重现步骤
|
||||
<!-- 请提供明确的步骤 -->
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -92,5 +92,6 @@ public class RegularExpression {
|
||||
/**
|
||||
* IP
|
||||
*/
|
||||
public static String IP = "\\d+\\.\\d+\\.\\d+\\.\\d+";
|
||||
public static String IP =
|
||||
"([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}";
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ android {
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
testImplementation 'junit:junit:4.12'
|
||||
implementation "androidx.appcompat:appcompat:${rootProject.ext.XAppcompatVersion}"
|
||||
// implementation "androidx.appcompat:appcompat:${rootProject.ext.XAppcompatVersion}"
|
||||
api project(':AriaAnnotations')
|
||||
api project(path: ':PublicComponent')
|
||||
api project(path: ':HttpComponent')
|
||||
|
||||
@@ -23,8 +23,6 @@ import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.widget.PopupWindow;
|
||||
import com.arialyy.aria.core.command.CommandManager;
|
||||
import com.arialyy.aria.core.common.QueueMod;
|
||||
@@ -76,7 +74,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
*/
|
||||
private Map<String, List<String>> mSubClass = new ConcurrentHashMap<>();
|
||||
private static Context APP;
|
||||
private Handler mAriaHandler;
|
||||
private DelegateWrapper mDbWrapper;
|
||||
private AriaConfig mConfig;
|
||||
|
||||
@@ -98,9 +95,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
}
|
||||
|
||||
public static AriaManager getInstance() {
|
||||
if (INSTANCE == null) {
|
||||
throw new NullPointerException("请使用AriaManager.init(context)初始化管理器");
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@@ -171,13 +165,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized Handler getAriaHandler() {
|
||||
if (mAriaHandler == null) {
|
||||
mAriaHandler = new Handler(Looper.getMainLooper());
|
||||
}
|
||||
return mAriaHandler;
|
||||
}
|
||||
|
||||
public Map<String, AbsReceiver> getReceiver() {
|
||||
return mReceivers;
|
||||
}
|
||||
@@ -295,7 +282,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
RecordUtil.delTaskRecord(key, IRecordHandler.TYPE_DOWNLOAD, removeFile, true);
|
||||
break;
|
||||
case 2:
|
||||
RecordUtil.delGroupTaskRecord(key, removeFile);
|
||||
RecordUtil.delGroupTaskRecordByHash(key, removeFile);
|
||||
break;
|
||||
case 3:
|
||||
RecordUtil.delTaskRecord(key, IRecordHandler.TYPE_UPLOAD);
|
||||
@@ -303,19 +290,31 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
}
|
||||
}
|
||||
|
||||
private IReceiver putReceiver(@ReceiverType String type, Object obj) {
|
||||
private IReceiver putReceiver(String type, Object obj) {
|
||||
final String key = getKey(type, obj);
|
||||
IReceiver receiver = mReceivers.get(key);
|
||||
boolean needRmReceiver = false;
|
||||
// 监控Dialog、fragment、popupWindow的生命周期
|
||||
final WidgetLiftManager widgetLiftManager = new WidgetLiftManager();
|
||||
Context subParenActivity = null;
|
||||
|
||||
if (obj instanceof Dialog) {
|
||||
needRmReceiver = widgetLiftManager.handleDialogLift((Dialog) obj);
|
||||
subParenActivity = ((Dialog) obj).getOwnerActivity();
|
||||
} else if (obj instanceof PopupWindow) {
|
||||
needRmReceiver = widgetLiftManager.handlePopupWindowLift((PopupWindow) obj);
|
||||
subParenActivity = ((PopupWindow) obj).getContentView().getContext();
|
||||
} else if (isDialogFragment(obj.getClass())) {
|
||||
needRmReceiver = widgetLiftManager.handleDialogFragmentLift(getDialog(obj));
|
||||
subParenActivity = getFragmentActivity(obj);
|
||||
} else if (isFragment(obj.getClass())) {
|
||||
subParenActivity = getFragmentActivity(obj);
|
||||
}
|
||||
|
||||
if (subParenActivity instanceof Activity) {
|
||||
relateSubClass(type, obj, (Activity) subParenActivity);
|
||||
}
|
||||
|
||||
if (receiver == null) {
|
||||
AbsReceiver absReceiver =
|
||||
type.equals(ReceiverType.DOWNLOAD) ? new DownloadReceiver() : new UploadReceiver();
|
||||
@@ -328,30 +327,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
return receiver;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据功能类型和控件类型获取对应的key
|
||||
*
|
||||
* @param type {@link ReceiverType}
|
||||
* @param obj 观察者对象
|
||||
* @return {@link #createKey(String, Object)}
|
||||
*/
|
||||
private String getKey(@ReceiverType String type, Object obj) {
|
||||
if (isFragment(obj.getClass())) {
|
||||
relateSubClass(type, obj, getFragmentActivity(obj));
|
||||
} else if (obj instanceof Dialog) {
|
||||
Activity activity = ((Dialog) obj).getOwnerActivity();
|
||||
if (activity != null) {
|
||||
relateSubClass(type, obj, activity);
|
||||
}
|
||||
} else if (obj instanceof PopupWindow) {
|
||||
Context context = ((PopupWindow) obj).getContentView().getContext();
|
||||
if (context instanceof Activity) {
|
||||
relateSubClass(type, obj, (Activity) context);
|
||||
}
|
||||
}
|
||||
return createKey(type, obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取fragment的activity
|
||||
*
|
||||
@@ -434,14 +409,17 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
* @param sub Fragment或dialog类
|
||||
* @param activity activity寄主类
|
||||
*/
|
||||
private void relateSubClass(@ReceiverType String type, Object sub, Activity activity) {
|
||||
String key = createKey(type, activity);
|
||||
List<String> list = mSubClass.get(key);
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
mSubClass.put(key, list);
|
||||
private void relateSubClass(String type, Object sub, Activity activity) {
|
||||
String key = getKey(type, activity);
|
||||
List<String> subClass = mSubClass.get(key);
|
||||
if (subClass == null) {
|
||||
subClass = new ArrayList<>();
|
||||
mSubClass.put(key, subClass);
|
||||
}
|
||||
subClass.add(getKey(type, sub));
|
||||
if (mReceivers.get(key) == null) { // 将activity填充进去
|
||||
mReceivers.put(key, new DownloadReceiver());
|
||||
}
|
||||
list.add(createKey(type, sub));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -452,7 +430,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
* @return key的格式为:{@code String.format("%s_%s_%s", obj.getClass().getName(), type,
|
||||
* obj.hashCode());}
|
||||
*/
|
||||
private String createKey(@ReceiverType String type, Object obj) {
|
||||
private String getKey(String type, Object obj) {
|
||||
return String.format("%s_%s_%s", obj.getClass().getName(), type, obj.hashCode());
|
||||
}
|
||||
|
||||
|
||||
@@ -73,8 +73,16 @@ final class WidgetLiftManager {
|
||||
|
||||
/**
|
||||
* 处理对话框取消或dismiss
|
||||
*
|
||||
* @return true 设置了dialog的销毁事件。false 没有设置dialog的销毁事件
|
||||
*/
|
||||
boolean handleDialogLift(Dialog dialog) {
|
||||
if (dialog == null) {
|
||||
ALog.w(TAG,
|
||||
"dialog 为空,没有设置自动销毁事件,为了防止内存泄露,请在dismiss方法中调用Aria.download(this).unRegister();来注销事件\n"
|
||||
+ "如果你使用的是DialogFragment,那么你需要在onDestroy()中进行销毁Aria事件操作");
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
Field dismissField = CommonUtil.getField(dialog.getClass(), "mDismissMessage");
|
||||
Message dismissMsg = (Message) dismissField.get(dialog);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.command;
|
||||
|
||||
import com.arialyy.aria.core.task.ITask;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
|
||||
/**
|
||||
@@ -25,8 +26,7 @@ public abstract class AbsCmdFactory<TASK_ENTITY extends AbsTaskWrapper, CMD exte
|
||||
|
||||
/**
|
||||
* @param entity 下载实体
|
||||
* @param taskType {@link ICmd#TASK_TYPE_DOWNLOAD}、{@link ICmd#TASK_TYPE_DOWNLOAD_GROUP}、{@link
|
||||
* ICmd#TASK_TYPE_UPLOAD}
|
||||
* {@link ITask#DOWNLOAD}、{@link ITask#DOWNLOAD_GROUP}、{@link ITask#UPLOAD}
|
||||
*/
|
||||
public abstract CMD createCmd(TASK_ENTITY entity, int type, int taskType);
|
||||
}
|
||||
|
||||
@@ -157,14 +157,6 @@ public abstract class AbsNormalCmd<T extends AbsTaskWrapper> extends AbsCmd<T> {
|
||||
mQueue.resumeTask(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动指定任务
|
||||
*
|
||||
* @param task 指定任务
|
||||
*/
|
||||
void startTask(AbsTask task) {
|
||||
mQueue.startTask(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从队列中获取任务
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.command;
|
||||
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
@@ -41,7 +42,7 @@ final class HighestPriorityCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T>
|
||||
|
||||
@Override public void executeCmd() {
|
||||
if (!canExeCmd) return;
|
||||
if (!NetUtils.isConnected(AriaManager.getInstance().getAPP())){
|
||||
if (!NetUtils.isConnected(AriaConfig.getInstance().getAPP())){
|
||||
ALog.e(TAG, "启动任务失败,网络未连接");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.arialyy.aria.core.command;
|
||||
|
||||
import com.arialyy.aria.core.task.ITask;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
|
||||
/**
|
||||
@@ -83,8 +84,7 @@ public class NormalCmdFactory extends AbsCmdFactory<AbsTaskWrapper, AbsNormalCmd
|
||||
* @param entity 下载实体
|
||||
* @param type 命令类型{@link #TASK_CREATE}、{@link #TASK_START}、{@link #TASK_CANCEL}、{@link
|
||||
* #TASK_STOP}、{@link #TASK_HIGHEST_PRIORITY}、{@link #TASK_STOP_ALL}、{@link #TASK_RESUME_ALL}
|
||||
* @param taskType {@link ICmd#TASK_TYPE_DOWNLOAD}、{@link ICmd#TASK_TYPE_DOWNLOAD_GROUP}、{@link
|
||||
* ICmd#TASK_TYPE_UPLOAD}
|
||||
* @param taskType {@link ITask#DOWNLOAD}、{@link ITask#DOWNLOAD_GROUP}、{@link ITask#UPLOAD}
|
||||
*/
|
||||
public AbsNormalCmd createCmd(AbsTaskWrapper entity, int type, int taskType) {
|
||||
switch (type) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,30 +15,11 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.command;
|
||||
|
||||
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.DTaskWrapper;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.DownloadGroupEntity;
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
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.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 com.arialyy.aria.util.NetUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* Created by AriaL on 2017/6/13.
|
||||
@@ -50,18 +31,16 @@ import java.util.concurrent.Executors;
|
||||
*/
|
||||
final class ResumeAllCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
|
||||
|
||||
|
||||
ResumeAllCmd(T entity, int taskType) {
|
||||
super(entity, taskType);
|
||||
}
|
||||
|
||||
@Override public void executeCmd() {
|
||||
if (!NetUtils.isConnected(AriaManager.getInstance().getAPP())) {
|
||||
if (!NetUtils.isConnected(AriaConfig.getInstance().getAPP())) {
|
||||
ALog.w(TAG, "恢复任务失败,网络未连接");
|
||||
return;
|
||||
}
|
||||
new Thread(new ResumeThread(isDownloadCmd, IEntity.STATE_COMPLETE)).start();
|
||||
new Thread(new ResumeThread(isDownloadCmd,
|
||||
String.format("state!=%s", IEntity.STATE_COMPLETE))).start();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -47,11 +47,11 @@ public class ResumeThread implements Runnable {
|
||||
private String TAG = CommonUtil.getClassName(getClass());
|
||||
private List<AbsTaskWrapper> mWaitList = new ArrayList<>();
|
||||
private boolean isDownloadCmd;
|
||||
private int excludeState;
|
||||
private String sqlCondition;
|
||||
|
||||
ResumeThread(boolean isDownload, int excludeState) {
|
||||
ResumeThread(boolean isDownload, String sqlCondition) {
|
||||
this.isDownloadCmd = isDownload;
|
||||
this.excludeState = excludeState;
|
||||
this.sqlCondition = sqlCondition;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,8 +63,8 @@ public class ResumeThread implements Runnable {
|
||||
if (type == 1) {
|
||||
List<DownloadEntity> entities =
|
||||
DbEntity.findDatas(DownloadEntity.class,
|
||||
"isGroupChild=? AND state!=? ORDER BY stopTime DESC", "false",
|
||||
String.valueOf(excludeState));
|
||||
String.format("NOT(isGroupChild) AND NOT(isComplete) AND %s ORDER BY stopTime DESC",
|
||||
sqlCondition));
|
||||
if (entities != null && !entities.isEmpty()) {
|
||||
for (DownloadEntity entity : entities) {
|
||||
addResumeEntity(TaskWrapperManager.getInstance()
|
||||
@@ -73,8 +73,9 @@ public class ResumeThread implements Runnable {
|
||||
}
|
||||
} else if (type == 2) {
|
||||
List<DownloadGroupEntity> entities =
|
||||
DbEntity.findDatas(DownloadGroupEntity.class, "state!=? ORDER BY stopTime DESC",
|
||||
String.valueOf(excludeState));
|
||||
DbEntity.findDatas(DownloadGroupEntity.class,
|
||||
String.format("NOT(isComplete) AND %s ORDER BY stopTime DESC",
|
||||
sqlCondition));
|
||||
if (entities != null && !entities.isEmpty()) {
|
||||
for (DownloadGroupEntity entity : entities) {
|
||||
addResumeEntity(
|
||||
@@ -84,8 +85,9 @@ public class ResumeThread implements Runnable {
|
||||
}
|
||||
} else if (type == 3) {
|
||||
List<UploadEntity> entities =
|
||||
DbEntity.findDatas(UploadEntity.class, "state!=? ORDER BY stopTime DESC",
|
||||
String.valueOf(excludeState));
|
||||
DbEntity.findDatas(UploadEntity.class,
|
||||
String.format("NOT(isComplete) AND %s ORDER BY stopTime DESC",
|
||||
sqlCondition));
|
||||
if (entities != null && !entities.isEmpty()) {
|
||||
for (UploadEntity entity : entities) {
|
||||
addResumeEntity(TaskWrapperManager.getInstance()
|
||||
@@ -125,7 +127,7 @@ public class ResumeThread implements Runnable {
|
||||
queue = DGroupTaskQueue.getInstance();
|
||||
}
|
||||
|
||||
if (queue == null){
|
||||
if (queue == null) {
|
||||
ALog.e(TAG, "任务类型错误");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.arialyy.aria.core.command;
|
||||
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.common.QueueMod;
|
||||
import com.arialyy.aria.core.inf.IEntity;
|
||||
import com.arialyy.aria.core.task.AbsTask;
|
||||
@@ -27,25 +27,36 @@ import com.arialyy.aria.util.NetUtils;
|
||||
/**
|
||||
* Created by lyy on 2016/8/22. 开始命令 队列模型{@link QueueMod#NOW}、{@link QueueMod#WAIT}
|
||||
*/
|
||||
final class StartCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
|
||||
final public class StartCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
|
||||
|
||||
private boolean newStart = false;
|
||||
|
||||
StartCmd(T entity, int taskType) {
|
||||
super(entity, taskType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即执行任务
|
||||
*
|
||||
* @param newStart true 立即执行任务,无论执行队列是否满了
|
||||
*/
|
||||
public void setNewStart(boolean newStart) {
|
||||
this.newStart = newStart;
|
||||
}
|
||||
|
||||
@Override public void executeCmd() {
|
||||
if (!canExeCmd) return;
|
||||
if (!NetUtils.isConnected(AriaManager.getInstance().getAPP())) {
|
||||
if (!NetUtils.isConnected(AriaConfig.getInstance().getAPP())) {
|
||||
ALog.e(TAG, "启动任务失败,网络未连接");
|
||||
return;
|
||||
}
|
||||
String mod;
|
||||
int maxTaskNum = mQueue.getMaxTaskNum();
|
||||
AriaManager manager = AriaManager.getInstance();
|
||||
AriaConfig config = AriaConfig.getInstance();
|
||||
if (isDownloadCmd) {
|
||||
mod = manager.getDownloadConfig().getQueueMod();
|
||||
mod = config.getDConfig().getQueueMod();
|
||||
} else {
|
||||
mod = manager.getUploadConfig().getQueueMod();
|
||||
mod = config.getUConfig().getQueueMod();
|
||||
}
|
||||
|
||||
AbsTask task = getTask();
|
||||
@@ -71,7 +82,11 @@ final class StartCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
|
||||
startTask();
|
||||
}
|
||||
} else {
|
||||
sendWaitState(task);
|
||||
if (newStart) {
|
||||
startTask();
|
||||
} else {
|
||||
sendWaitState(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -91,6 +106,7 @@ final class StartCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
|
||||
* 当缓冲队列为null时,查找数据库中所有等待中的任务
|
||||
*/
|
||||
private void findAllWaitTask() {
|
||||
new Thread(new ResumeThread(isDownloadCmd, IEntity.STATE_WAIT)).start();
|
||||
new Thread(
|
||||
new ResumeThread(isDownloadCmd, String.format("state=%s", IEntity.STATE_WAIT))).start();
|
||||
}
|
||||
}
|
||||
@@ -15,12 +15,12 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.common;
|
||||
|
||||
import com.arialyy.aria.core.common.controller.IStartFeature;
|
||||
import com.arialyy.aria.core.common.controller.BuilderController;
|
||||
import com.arialyy.aria.core.common.controller.IStartFeature;
|
||||
import com.arialyy.aria.core.inf.AbsTarget;
|
||||
|
||||
/**
|
||||
* 处理第一次下载
|
||||
* 处理第一次创建的任务
|
||||
*/
|
||||
public abstract class AbsBuilderTarget<TARGET extends AbsBuilderTarget> extends AbsTarget<TARGET>
|
||||
implements IStartFeature {
|
||||
@@ -34,6 +34,23 @@ public abstract class AbsBuilderTarget<TARGET extends AbsBuilderTarget> extends
|
||||
return mStartController;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否忽略权限检查
|
||||
*/
|
||||
public TARGET ignoreCheckPermissions() {
|
||||
getController().ignoreCheckPermissions();
|
||||
return (TARGET) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 忽略文件占用,不管文件路径是否被其它任务占用,都执行上传\下载任务
|
||||
* 需要注意的是:如果文件被其它任务占用,并且还调用了该方法,将自动删除占用了该文件路径的任务
|
||||
*/
|
||||
public TARGET ignoreFilePathOccupy() {
|
||||
getController().ignoreFilePathOccupy();
|
||||
return (TARGET) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加任务
|
||||
*
|
||||
|
||||
@@ -31,6 +31,14 @@ import com.arialyy.aria.util.RecordUtil;
|
||||
public abstract class AbsNormalTarget<TARGET extends AbsNormalTarget> extends AbsTarget<TARGET>
|
||||
implements INormalFeature {
|
||||
|
||||
/**
|
||||
* 是否忽略权限检查
|
||||
*/
|
||||
public TARGET ignoreCheckPermissions() {
|
||||
getController().ignoreCheckPermissions();
|
||||
return (TARGET) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务是否在执行
|
||||
*
|
||||
@@ -150,7 +158,17 @@ public abstract class AbsNormalTarget<TARGET extends AbsNormalTarget> extends Ab
|
||||
*/
|
||||
@Override
|
||||
public void resume() {
|
||||
getController().resume();
|
||||
resume(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 正常来说,当执行队列满时,调用恢复任务接口,只能将任务放到缓存队列中。
|
||||
* 如果希望调用恢复接口,马上进入执行队列,需要使用该方法
|
||||
*
|
||||
* @param newStart true 立即将任务恢复到执行队列中
|
||||
*/
|
||||
@Override public void resume(boolean newStart) {
|
||||
getController().resume(newStart);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -184,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
|
||||
|
||||
@@ -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();
|
||||
@@ -70,7 +73,7 @@ public class FtpOption extends BaseOption {
|
||||
*
|
||||
* @param protocol {@link ProtocolType}
|
||||
*/
|
||||
public FtpOption setProtocol(@ProtocolType String protocol) {
|
||||
public FtpOption setProtocol(String protocol) {
|
||||
if (TextUtils.isEmpty(protocol)) {
|
||||
ALog.e(TAG, "设置协议失败,协议信息为空");
|
||||
return this;
|
||||
@@ -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;
|
||||
|
||||
@@ -16,11 +16,6 @@
|
||||
package com.arialyy.aria.core.common;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import androidx.annotation.CheckResult;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.arialyy.aria.core.download.target.HttpBuilderTarget;
|
||||
import com.arialyy.aria.core.inf.IOptionConstant;
|
||||
import com.arialyy.aria.core.inf.Suggest;
|
||||
import com.arialyy.aria.core.processor.IHttpFileLenAdapter;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CheckUtil;
|
||||
@@ -50,7 +45,6 @@ public class HttpOption extends BaseOption {
|
||||
*
|
||||
* @param requestEnum {@link RequestEnum}
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TO_CONTROLLER)
|
||||
public HttpOption setRequestType(RequestEnum requestEnum) {
|
||||
this.requestEnum = requestEnum;
|
||||
return this;
|
||||
@@ -97,7 +91,7 @@ public class HttpOption extends BaseOption {
|
||||
* @param key header对应的key
|
||||
* @param value header对应的value
|
||||
*/
|
||||
public HttpOption addHeader(@NonNull String key, @NonNull String value) {
|
||||
public HttpOption addHeader(String key, String value) {
|
||||
if (TextUtils.isEmpty(key)) {
|
||||
ALog.w(TAG, "设置header失败,header对应的key不能为null");
|
||||
return this;
|
||||
@@ -118,7 +112,7 @@ public class HttpOption extends BaseOption {
|
||||
*
|
||||
* @param headers 一组http header数据
|
||||
*/
|
||||
public HttpOption addHeaders(@NonNull Map<String, String> headers) {
|
||||
public HttpOption addHeaders(Map<String, String> headers) {
|
||||
if (headers.size() == 0) {
|
||||
ALog.w(TAG, "设置header失败,map没有header数据");
|
||||
return this;
|
||||
|
||||
@@ -75,50 +75,23 @@ public class ProxyHelper {
|
||||
return result;
|
||||
}
|
||||
result = new HashSet<>();
|
||||
try {
|
||||
if (getClass().getClassLoader()
|
||||
.loadClass(className.concat(TaskEnum.DOWNLOAD_GROUP.proxySuffix))
|
||||
!= null) {
|
||||
result.add(PROXY_TYPE_DOWNLOAD_GROUP);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
//e.printStackTrace();
|
||||
if (checkProxyExist(className, TaskEnum.DOWNLOAD_GROUP.proxySuffix)) {
|
||||
result.add(PROXY_TYPE_DOWNLOAD_GROUP);
|
||||
}
|
||||
try {
|
||||
if (getClass().getClassLoader().loadClass(className.concat(TaskEnum.DOWNLOAD.proxySuffix))
|
||||
!= null) {
|
||||
result.add(PROXY_TYPE_DOWNLOAD);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
//e.printStackTrace();
|
||||
if (checkProxyExist(className, TaskEnum.DOWNLOAD.proxySuffix)) {
|
||||
result.add(PROXY_TYPE_DOWNLOAD);
|
||||
}
|
||||
|
||||
try {
|
||||
if (getClass().getClassLoader().loadClass(className.concat(TaskEnum.UPLOAD.proxySuffix))
|
||||
!= null) {
|
||||
result.add(PROXY_TYPE_UPLOAD);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
//e.printStackTrace();
|
||||
if (checkProxyExist(className, TaskEnum.UPLOAD.proxySuffix)) {
|
||||
result.add(PROXY_TYPE_UPLOAD);
|
||||
}
|
||||
|
||||
try {
|
||||
if (getClass().getClassLoader().loadClass(className.concat(TaskEnum.M3U8_PEER.proxySuffix))
|
||||
!= null) {
|
||||
result.add(PROXY_TYPE_M3U8_PEER);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
//e.printStackTrace();
|
||||
if (checkProxyExist(className, TaskEnum.M3U8_PEER.proxySuffix)) {
|
||||
result.add(PROXY_TYPE_M3U8_PEER);
|
||||
}
|
||||
|
||||
try {
|
||||
if (getClass().getClassLoader()
|
||||
.loadClass(className.concat(TaskEnum.DOWNLOAD_GROUP_SUB.proxySuffix))
|
||||
!= null) {
|
||||
result.add(PROXY_TYPE_DOWNLOAD_GROUP_SUB);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
//e.printStackTrace();
|
||||
if (checkProxyExist(className, TaskEnum.DOWNLOAD_GROUP_SUB.proxySuffix)) {
|
||||
result.add(PROXY_TYPE_DOWNLOAD_GROUP_SUB);
|
||||
}
|
||||
|
||||
if (!result.isEmpty()) {
|
||||
@@ -126,4 +99,20 @@ public class ProxyHelper {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean checkProxyExist(String className, String proxySuffix) {
|
||||
String clsName = className.concat(proxySuffix);
|
||||
|
||||
try {
|
||||
if (getClass().getClassLoader().loadClass(clsName) != null) {
|
||||
return true;
|
||||
}
|
||||
if (Class.forName(clsName) != null) {
|
||||
return true;
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -19,21 +19,21 @@ import android.Manifest;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.download.CheckDEntityUtil;
|
||||
import com.arialyy.aria.core.download.CheckDGEntityUtil;
|
||||
import com.arialyy.aria.core.download.CheckFtpDirEntityUtil;
|
||||
import com.arialyy.aria.core.download.DGTaskWrapper;
|
||||
import com.arialyy.aria.core.download.DTaskWrapper;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.core.inf.ICheckEntityUtil;
|
||||
import com.arialyy.aria.core.task.ITask;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import com.arialyy.aria.core.listener.ISchedulers;
|
||||
import com.arialyy.aria.core.scheduler.TaskSchedulers;
|
||||
import com.arialyy.aria.core.task.ITask;
|
||||
import com.arialyy.aria.core.upload.CheckUEntityUtil;
|
||||
import com.arialyy.aria.core.upload.UTaskWrapper;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import java.lang.reflect.Constructor;
|
||||
@@ -43,9 +43,25 @@ 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;
|
||||
/**
|
||||
* 是否忽略权限检查 true 忽略权限检查
|
||||
*/
|
||||
private boolean ignoreCheckPermissions = false;
|
||||
private int action = ACTION_DEF;
|
||||
|
||||
FeatureController(AbsTaskWrapper wrapper) {
|
||||
mTaskWrapper = wrapper;
|
||||
@@ -87,6 +103,24 @@ public abstract class FeatureController {
|
||||
return null;
|
||||
}
|
||||
|
||||
void setAction(int action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否忽略权限检查
|
||||
*/
|
||||
public void ignoreCheckPermissions() {
|
||||
this.ignoreCheckPermissions = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 强制执行任务,不管文件路径是否被占用
|
||||
*/
|
||||
public void ignoreFilePathOccupy() {
|
||||
mTaskWrapper.setIgnoreFilePathOccupy(true);
|
||||
}
|
||||
|
||||
protected AbsTaskWrapper getTaskWrapper() {
|
||||
return mTaskWrapper;
|
||||
}
|
||||
@@ -111,7 +145,7 @@ public abstract class FeatureController {
|
||||
* 如果检查实体失败,将错误回调
|
||||
*/
|
||||
boolean checkConfig() {
|
||||
if (!checkPermission()) {
|
||||
if (!ignoreCheckPermissions && !checkPermission()) {
|
||||
return false;
|
||||
}
|
||||
boolean b = checkEntity();
|
||||
@@ -134,21 +168,21 @@ public abstract class FeatureController {
|
||||
*/
|
||||
private boolean checkPermission() {
|
||||
|
||||
if (AriaManager.getInstance()
|
||||
if (AriaConfig.getInstance()
|
||||
.getAPP()
|
||||
.checkCallingOrSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
ALog.e(TAG, "启动失败,缺少权限:Manifest.permission.WRITE_EXTERNAL_STORAGE");
|
||||
return false;
|
||||
}
|
||||
if (AriaManager.getInstance()
|
||||
if (AriaConfig.getInstance()
|
||||
.getAPP()
|
||||
.checkCallingOrSelfPermission(Manifest.permission.INTERNET)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
ALog.e(TAG, "启动失败,缺少权限:Manifest.permission.INTERNET");
|
||||
return false;
|
||||
}
|
||||
if (AriaManager.getInstance()
|
||||
if (AriaConfig.getInstance()
|
||||
.getAPP()
|
||||
.checkCallingOrSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
@@ -162,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();
|
||||
}
|
||||
|
||||
@@ -30,6 +30,14 @@ public interface INormalFeature {
|
||||
*/
|
||||
void resume();
|
||||
|
||||
/**
|
||||
* 正常来说,当执行队列满时,调用恢复任务接口,只能将任务放到缓存队列中。
|
||||
* 如果希望调用恢复接口,马上进入执行队列,需要使用该方法
|
||||
*
|
||||
* @param newStart true 立即将任务恢复到执行队列中
|
||||
*/
|
||||
void resume(boolean newStart);
|
||||
|
||||
/**
|
||||
* 删除任务
|
||||
*/
|
||||
@@ -51,7 +59,7 @@ public interface INormalFeature {
|
||||
/**
|
||||
* 重新下载
|
||||
*/
|
||||
void reStart();
|
||||
long reStart();
|
||||
|
||||
/**
|
||||
* 保存数据
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
package com.arialyy.aria.core.common.controller;
|
||||
|
||||
import com.arialyy.aria.core.command.CancelCmd;
|
||||
import com.arialyy.aria.core.command.CmdHelper;
|
||||
import com.arialyy.aria.core.command.NormalCmdFactory;
|
||||
import com.arialyy.aria.core.command.StartCmd;
|
||||
import com.arialyy.aria.core.event.EventMsgUtil;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.core.command.CmdHelper;
|
||||
|
||||
/**
|
||||
* 启动控制器
|
||||
@@ -37,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,
|
||||
@@ -49,10 +51,24 @@ public final class NormalController extends FeatureController implements INormal
|
||||
*/
|
||||
@Override
|
||||
public void resume() {
|
||||
resume(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 正常来说,当执行队列满时,调用恢复任务接口,只能将任务放到缓存队列中。
|
||||
* 如果希望调用恢复接口,马上进入执行队列,需要使用该方法
|
||||
*
|
||||
* @param newStart true 立即将任务恢复到执行队列中
|
||||
*/
|
||||
@Override public void resume(boolean newStart) {
|
||||
setAction(ACTION_RESUME);
|
||||
if (checkConfig()) {
|
||||
StartCmd cmd =
|
||||
(StartCmd) CmdHelper.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_START,
|
||||
checkTaskType());
|
||||
cmd.setNewStart(newStart);
|
||||
EventMsgUtil.getDefault()
|
||||
.post(CmdHelper.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_START,
|
||||
checkTaskType()));
|
||||
.post(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,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()
|
||||
@@ -91,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,
|
||||
@@ -104,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 {
|
||||
|
||||
@@ -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;
|
||||
@@ -23,6 +24,7 @@ import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CheckUtil;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.aria.util.FileUtil;
|
||||
import com.arialyy.aria.util.RecordUtil;
|
||||
import java.io.File;
|
||||
|
||||
@@ -33,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();
|
||||
}
|
||||
@@ -65,8 +69,7 @@ public class CheckDEntityUtil implements ICheckEntityUtil {
|
||||
File file = new File(mWrapper.getTempFilePath());
|
||||
Object bw = mWrapper.getM3U8Params().getParam(IOptionConstant.bandWidth);
|
||||
int bandWidth = bw == null ? 0 : (int) bw;
|
||||
// 缓存文件夹格式:问文件夹/.文件名_码率
|
||||
String cacheDir = String.format("%s/.%s_%s", file.getParent(), file.getName(), bandWidth);
|
||||
String cacheDir = FileUtil.getTsCacheDir(file.getPath(), bandWidth);
|
||||
|
||||
mWrapper.getM3U8Params().setParams(IOptionConstant.cacheDir, cacheDir);
|
||||
M3U8Entity m3U8Entity = mEntity.getM3U8Entity();
|
||||
@@ -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框架将采用第一个获取到的码率");
|
||||
}
|
||||
@@ -134,7 +140,7 @@ public class CheckDEntityUtil implements ICheckEntityUtil {
|
||||
//设置文件保存路径,如果新文件路径和旧文件路径不同,则修改路径
|
||||
if (!filePath.equals(mEntity.getFilePath())) {
|
||||
// 检查路径冲突
|
||||
if (!CheckUtil.checkDownloadPathConflicts(mWrapper.isForceDownload(), filePath)) {
|
||||
if (!CheckUtil.checkDPathConflicts(mWrapper.isIgnoreFilePathOccupy(), filePath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -151,11 +157,11 @@ public class CheckDEntityUtil implements ICheckEntityUtil {
|
||||
File oldFile = new File(mEntity.getFilePath());
|
||||
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()));
|
||||
} 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()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,13 @@
|
||||
package com.arialyy.aria.core.download;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import com.arialyy.aria.core.common.ErrorCode;
|
||||
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;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CheckUtil;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.aria.util.RecordUtil;
|
||||
import java.io.File;
|
||||
@@ -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();
|
||||
}
|
||||
@@ -70,10 +73,9 @@ public class CheckDGEntityUtil implements ICheckEntityUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((mEntity.getDirPath() == null || !mEntity.getDirPath().equals(mWrapper.getDirPathTemp()))
|
||||
&& DbEntity.checkDataExist(DownloadGroupEntity.class, "dirPath=?",
|
||||
// 检查路径冲突
|
||||
if (mWrapper.isNewTask() && !CheckUtil.checkDGPathConflicts(mWrapper.isIgnoreFilePathOccupy(),
|
||||
mWrapper.getDirPathTemp())) {
|
||||
ALog.e(TAG, String.format("文件夹路径【%s】已被其它任务占用,请重新设置文件夹路径", mWrapper.getDirPathTemp()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -130,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;
|
||||
}
|
||||
@@ -175,7 +179,7 @@ public class CheckDGEntityUtil implements ICheckEntityUtil {
|
||||
return;
|
||||
}
|
||||
|
||||
RecordUtil.modifyTaskRecord(oldPath, newPath);
|
||||
RecordUtil.modifyTaskRecord(oldPath, newPath, mEntity.getTaskType());
|
||||
entity.setFilePath(newPath);
|
||||
entity.setFileName(newName);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -15,9 +15,8 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.download;
|
||||
|
||||
import androidx.annotation.CheckResult;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.arialyy.annotations.TaskEnum;
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import com.arialyy.aria.core.command.CancelAllCmd;
|
||||
import com.arialyy.aria.core.command.CmdHelper;
|
||||
@@ -64,7 +63,7 @@ public class DownloadReceiver extends AbsReceiver {
|
||||
*/
|
||||
@Deprecated
|
||||
public DownloadReceiver setMaxSpeed(int maxSpeed) {
|
||||
AriaManager.getInstance().getDownloadConfig().setMaxSpeed(maxSpeed);
|
||||
AriaConfig.getInstance().getDConfig().setMaxSpeed(maxSpeed);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -73,8 +72,7 @@ public class DownloadReceiver extends AbsReceiver {
|
||||
*
|
||||
* @param url 下载地址
|
||||
*/
|
||||
@CheckResult
|
||||
public HttpBuilderTarget load(@NonNull String url) {
|
||||
public HttpBuilderTarget load(String url) {
|
||||
ComponentUtil.getInstance().checkComponentExist(ComponentUtil.COMPONENT_TYPE_HTTP);
|
||||
return DTargetFactory.getInstance()
|
||||
.generateBuilderTarget(HttpBuilderTarget.class, url);
|
||||
@@ -86,7 +84,6 @@ public class DownloadReceiver extends AbsReceiver {
|
||||
* @param taskId 任务id,可从{@link AbsBuilderTarget#create()}、{@link AbsBuilderTarget#add()}、{@link
|
||||
* AbsEntity#getId()}读取任务id
|
||||
*/
|
||||
@CheckResult
|
||||
public HttpNormalTarget load(long taskId) {
|
||||
ComponentUtil.getInstance().checkComponentExist(ComponentUtil.COMPONENT_TYPE_HTTP);
|
||||
return DTargetFactory.getInstance()
|
||||
@@ -98,7 +95,6 @@ public class DownloadReceiver extends AbsReceiver {
|
||||
*
|
||||
* @param urls 组合任务只任务列被,如果任务组的中的下载地址改变了,则任务从新的一个任务组
|
||||
*/
|
||||
@CheckResult
|
||||
public GroupBuilderTarget loadGroup(List<String> urls) {
|
||||
ComponentUtil.getInstance().checkComponentExist(ComponentUtil.COMPONENT_TYPE_HTTP);
|
||||
return DTargetFactory.getInstance().generateGroupBuilderTarget(urls);
|
||||
@@ -110,7 +106,7 @@ public class DownloadReceiver extends AbsReceiver {
|
||||
* @param taskId 任务id,可从{@link AbsBuilderTarget#create()}、{@link AbsBuilderTarget#add()}、{@link
|
||||
* * AbsEntity#getId()}读取任务id
|
||||
*/
|
||||
@CheckResult
|
||||
|
||||
public GroupNormalTarget loadGroup(long taskId) {
|
||||
ComponentUtil.getInstance().checkComponentExist(ComponentUtil.COMPONENT_TYPE_HTTP);
|
||||
return DTargetFactory.getInstance()
|
||||
@@ -120,8 +116,8 @@ public class DownloadReceiver extends AbsReceiver {
|
||||
/**
|
||||
* 加载ftp单任务下载地址,用于任务第一次下载,如果需要控制任务停止或删除等操作,请使用{@link #loadFtp(long)}
|
||||
*/
|
||||
@CheckResult
|
||||
public FtpBuilderTarget loadFtp(@NonNull String url) {
|
||||
|
||||
public FtpBuilderTarget loadFtp(String url) {
|
||||
ComponentUtil.getInstance().checkComponentExist(ComponentUtil.COMPONENT_TYPE_FTP);
|
||||
return DTargetFactory.getInstance()
|
||||
.generateBuilderTarget(FtpBuilderTarget.class, url);
|
||||
@@ -133,7 +129,7 @@ public class DownloadReceiver extends AbsReceiver {
|
||||
* @param taskId 任务id,可从{@link AbsBuilderTarget#create()}、{@link AbsBuilderTarget#add()}、{@link
|
||||
* AbsEntity#getId()}读取任务id
|
||||
*/
|
||||
@CheckResult
|
||||
|
||||
public FtpNormalTarget loadFtp(long taskId) {
|
||||
ComponentUtil.getInstance().checkComponentExist(ComponentUtil.COMPONENT_TYPE_FTP);
|
||||
return DTargetFactory.getInstance()
|
||||
@@ -143,8 +139,8 @@ public class DownloadReceiver extends AbsReceiver {
|
||||
/**
|
||||
* 加载ftp文件夹下载地址,用于任务第一次下载,如果需要控制任务停止或删除等操作,请使用{@link #loadFtpDir(long)}
|
||||
*/
|
||||
@CheckResult
|
||||
public FtpDirBuilderTarget loadFtpDir(@NonNull String dirUrl) {
|
||||
|
||||
public FtpDirBuilderTarget loadFtpDir(String dirUrl) {
|
||||
ComponentUtil.getInstance().checkComponentExist(ComponentUtil.COMPONENT_TYPE_FTP);
|
||||
return DTargetFactory.getInstance().generateDirBuilderTarget(dirUrl);
|
||||
}
|
||||
@@ -155,7 +151,7 @@ public class DownloadReceiver extends AbsReceiver {
|
||||
* @param taskId 任务id,可从{@link AbsBuilderTarget#create()}、{@link AbsBuilderTarget#add()}、{@link
|
||||
* AbsEntity#getId()}读取任务id
|
||||
*/
|
||||
@CheckResult
|
||||
|
||||
public FtpDirNormalTarget loadFtpDir(long taskId) {
|
||||
ComponentUtil.getInstance().checkComponentExist(ComponentUtil.COMPONENT_TYPE_FTP);
|
||||
return DTargetFactory.getInstance()
|
||||
@@ -287,10 +283,10 @@ public class DownloadReceiver extends AbsReceiver {
|
||||
* @return 如果实体不存在,返回null
|
||||
*/
|
||||
public DownloadGroupEntity getGroupEntity(List<String> urls) {
|
||||
if (CheckUtil.checkDownloadUrlsIsEmpty(urls)){
|
||||
if (CheckUtil.checkDownloadUrlsIsEmpty(urls)) {
|
||||
return null;
|
||||
}
|
||||
return DbDataHelper.getDGEntity(CommonUtil.getMd5Code(urls));
|
||||
return DbDataHelper.getDGEntityByHash(CommonUtil.getMd5Code(urls));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,7 +299,7 @@ public class DownloadReceiver extends AbsReceiver {
|
||||
if (!CheckUtil.checkUrl(url)) {
|
||||
return null;
|
||||
}
|
||||
return DbDataHelper.getDGEntity(url);
|
||||
return DbDataHelper.getDGEntityByHash(url);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.arialyy.aria.core.download.m3u8;
|
||||
|
||||
import com.arialyy.aria.core.common.BaseOption;
|
||||
import com.arialyy.aria.core.processor.IBandWidthUrlConverter;
|
||||
import com.arialyy.aria.core.processor.IKeyUrlConverter;
|
||||
import com.arialyy.aria.core.processor.ITsMergeHandler;
|
||||
import com.arialyy.aria.util.CheckUtil;
|
||||
import com.arialyy.aria.util.ComponentUtil;
|
||||
@@ -31,12 +32,22 @@ public class M3U8Option<OP extends M3U8Option> extends BaseOption {
|
||||
private int bandWidth;
|
||||
private ITsMergeHandler mergeHandler;
|
||||
private IBandWidthUrlConverter bandWidthUrlConverter;
|
||||
private IKeyUrlConverter keyUrlConverter;
|
||||
private boolean ignoreFailureTs = false;
|
||||
|
||||
M3U8Option() {
|
||||
super();
|
||||
ComponentUtil.getInstance().checkComponentExist(ComponentUtil.COMPONENT_TYPE_M3U8);
|
||||
}
|
||||
|
||||
/**
|
||||
* 忽略下载失败的ts切片,即使有失败的切片,下载完成后也要合并所有切片,并进入complete回调
|
||||
*/
|
||||
public OP ignoreFailureTs() {
|
||||
this.ignoreFailureTs = true;
|
||||
return (OP) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成m3u8索引文件
|
||||
* 注意:创建索引文件,{@link #merge(boolean)}方法设置与否都不再合并文件
|
||||
@@ -88,4 +99,15 @@ public class M3U8Option<OP extends M3U8Option> extends BaseOption {
|
||||
this.bandWidthUrlConverter = bandWidthUrlConverter;
|
||||
return (OP) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* M3U8 密钥url转换器,对于某些服务器,密钥的下载地址是被加密的,因此需要使用该方法将被加密的密钥解密成可被识别的http地址
|
||||
*
|
||||
* @param keyUrlConverter {@link IKeyUrlConverter}
|
||||
*/
|
||||
public OP setKeyUrlConverter(IKeyUrlConverter keyUrlConverter) {
|
||||
CheckUtil.checkMemberClass(keyUrlConverter.getClass());
|
||||
this.keyUrlConverter = keyUrlConverter;
|
||||
return (OP) this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
package com.arialyy.aria.core.download.target;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import androidx.annotation.CheckResult;
|
||||
import com.arialyy.aria.core.common.AbsNormalTarget;
|
||||
import com.arialyy.aria.core.common.ErrorCode;
|
||||
import com.arialyy.aria.core.download.DGTaskWrapper;
|
||||
import com.arialyy.aria.core.download.DownloadGroupEntity;
|
||||
import com.arialyy.aria.core.event.ErrorEvent;
|
||||
@@ -66,7 +64,6 @@ abstract class AbsGroupConfigHandler<TARGET extends AbsTarget> implements IConfi
|
||||
*
|
||||
* @return 子任务管理器
|
||||
*/
|
||||
@CheckResult
|
||||
SubTaskManager getSubTaskManager() {
|
||||
if (mSubTaskManager == null) {
|
||||
mSubTaskManager = new SubTaskManager(getTaskWrapper());
|
||||
@@ -89,7 +86,6 @@ abstract class AbsGroupConfigHandler<TARGET extends AbsTarget> implements IConfi
|
||||
return task != null && task.isRunning();
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
TARGET setDirPath(String dirPath) {
|
||||
mWrapper.setDirPathTemp(dirPath);
|
||||
return mTarget;
|
||||
|
||||
@@ -93,7 +93,7 @@ class DNormalConfigHandler<TARGET extends AbsTarget> implements IConfigHandler {
|
||||
}
|
||||
|
||||
void setForceDownload(boolean forceDownload) {
|
||||
getWrapper().setForceDownload(forceDownload);
|
||||
getWrapper().setIgnoreFilePathOccupy(forceDownload);
|
||||
}
|
||||
|
||||
void setUrl(String url) {
|
||||
|
||||
@@ -15,12 +15,9 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.download.target;
|
||||
|
||||
import androidx.annotation.CheckResult;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.arialyy.aria.core.common.AbsBuilderTarget;
|
||||
import com.arialyy.aria.core.common.FtpOption;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.inf.Suggest;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
|
||||
@@ -34,12 +31,13 @@ public class FtpBuilderTarget extends AbsBuilderTarget<FtpBuilderTarget> {
|
||||
mConfigHandler = new DNormalConfigHandler<>(this, -1);
|
||||
mConfigHandler.setUrl(url);
|
||||
getTaskWrapper().setRequestType(ITaskWrapper.D_FTP);
|
||||
getEntity().setTaskType(ITaskWrapper.D_FTP);
|
||||
getTaskWrapper().setNewTask(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置登陆、字符串编码、ftps等参数
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public FtpBuilderTarget option(FtpOption option) {
|
||||
if (option == null) {
|
||||
throw new NullPointerException("ftp 任务配置为空");
|
||||
@@ -55,8 +53,7 @@ public class FtpBuilderTarget extends AbsBuilderTarget<FtpBuilderTarget> {
|
||||
* 1、如果保存路径是该文件的保存路径,如:/mnt/sdcard/file.zip,则使用路径中的文件名file.zip
|
||||
* 2、如果保存路径是文件夹路径,如:/mnt/sdcard/,则使用FTP服务器该文件的文件名
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public FtpBuilderTarget setFilePath(@NonNull String filePath) {
|
||||
public FtpBuilderTarget setFilePath(String filePath) {
|
||||
int lastIndex = mConfigHandler.getUrl().lastIndexOf("/");
|
||||
getEntity().setFileName(mConfigHandler.getUrl().substring(lastIndex + 1));
|
||||
mConfigHandler.setTempFilePath(filePath);
|
||||
@@ -70,9 +67,10 @@ public class FtpBuilderTarget extends AbsBuilderTarget<FtpBuilderTarget> {
|
||||
*
|
||||
* @param filePath 路径必须为文件路径,不能为文件夹路径
|
||||
* @param forceDownload {@code true}强制下载,不考虑文件路径是否被占用
|
||||
* @deprecated 使用 {@link #ignoreFilePathOccupy()}
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public FtpBuilderTarget setFilePath(@NonNull String filePath, boolean forceDownload) {
|
||||
@Deprecated
|
||||
public FtpBuilderTarget setFilePath(String filePath, boolean forceDownload) {
|
||||
mConfigHandler.setTempFilePath(filePath);
|
||||
mConfigHandler.setForceDownload(forceDownload);
|
||||
return this;
|
||||
|
||||
@@ -15,11 +15,9 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.download.target;
|
||||
|
||||
import androidx.annotation.CheckResult;
|
||||
import com.arialyy.aria.core.common.AbsBuilderTarget;
|
||||
import com.arialyy.aria.core.common.FtpOption;
|
||||
import com.arialyy.aria.core.download.DownloadGroupEntity;
|
||||
import com.arialyy.aria.core.inf.Suggest;
|
||||
import com.arialyy.aria.core.manager.SubTaskManager;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
|
||||
@@ -35,6 +33,7 @@ public class FtpDirBuilderTarget extends AbsBuilderTarget<FtpDirBuilderTarget> {
|
||||
this.url = url;
|
||||
mConfigHandler = new FtpDirConfigHandler<>(this, -1);
|
||||
getEntity().setGroupHash(url);
|
||||
getTaskWrapper().setNewTask(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,7 +55,6 @@ public class FtpDirBuilderTarget extends AbsBuilderTarget<FtpDirBuilderTarget> {
|
||||
*
|
||||
* @param dirPath 任务组保存文件夹路径
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public FtpDirBuilderTarget setDirPath(String dirPath) {
|
||||
return mConfigHandler.setDirPath(dirPath);
|
||||
}
|
||||
@@ -64,7 +62,6 @@ public class FtpDirBuilderTarget extends AbsBuilderTarget<FtpDirBuilderTarget> {
|
||||
/**
|
||||
* 设置任务组别名
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public FtpDirBuilderTarget setGroupAlias(String alias) {
|
||||
mConfigHandler.setGroupAlias(alias);
|
||||
return this;
|
||||
@@ -73,7 +70,6 @@ public class FtpDirBuilderTarget extends AbsBuilderTarget<FtpDirBuilderTarget> {
|
||||
/**
|
||||
* 设置登陆、字符串编码、ftps等参数
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public FtpDirBuilderTarget option(FtpOption option) {
|
||||
if (option == null) {
|
||||
throw new NullPointerException("ftp 任务配置为空");
|
||||
@@ -92,7 +88,6 @@ public class FtpDirBuilderTarget extends AbsBuilderTarget<FtpDirBuilderTarget> {
|
||||
*
|
||||
* @return 子任务管理器
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public SubTaskManager getSubTaskManager() {
|
||||
return mConfigHandler.getSubTaskManager();
|
||||
}
|
||||
|
||||
@@ -33,11 +33,12 @@ class FtpDirConfigHandler<TARGET extends AbsTarget> extends AbsGroupConfigHandle
|
||||
}
|
||||
|
||||
private void init() {
|
||||
getTaskWrapper().setRequestType(AbsTaskWrapper.D_FTP_DIR);
|
||||
getTaskWrapper().setRequestType(ITaskWrapper.D_FTP_DIR);
|
||||
List<DTaskWrapper> wrappers = getTaskWrapper().getSubTaskWrapper();
|
||||
if (!wrappers.isEmpty()) {
|
||||
for (DTaskWrapper subWrapper : wrappers) {
|
||||
subWrapper.setRequestType(ITaskWrapper.D_FTP);
|
||||
subWrapper.getEntity().setTaskType(ITaskWrapper.D_FTP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,9 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.download.target;
|
||||
|
||||
import androidx.annotation.CheckResult;
|
||||
import com.arialyy.aria.core.common.AbsNormalTarget;
|
||||
import com.arialyy.aria.core.common.FtpOption;
|
||||
import com.arialyy.aria.core.download.DownloadGroupEntity;
|
||||
import com.arialyy.aria.core.inf.Suggest;
|
||||
import com.arialyy.aria.core.manager.SubTaskManager;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
|
||||
@@ -32,6 +30,7 @@ public class FtpDirNormalTarget extends AbsNormalTarget<FtpDirNormalTarget> {
|
||||
|
||||
FtpDirNormalTarget(long taskId) {
|
||||
mConfigHandler = new FtpDirConfigHandler<>(this, taskId);
|
||||
getTaskWrapper().setNewTask(false);
|
||||
}
|
||||
|
||||
@Override public boolean isRunning() {
|
||||
@@ -61,7 +60,6 @@ public class FtpDirNormalTarget extends AbsNormalTarget<FtpDirNormalTarget> {
|
||||
*
|
||||
* @param dirPath 任务组保存文件夹路径
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public FtpDirNormalTarget modifyDirPath(String dirPath) {
|
||||
return mConfigHandler.setDirPath(dirPath);
|
||||
}
|
||||
@@ -69,7 +67,6 @@ public class FtpDirNormalTarget extends AbsNormalTarget<FtpDirNormalTarget> {
|
||||
/**
|
||||
* 设置登陆、字符串编码、ftps等参数
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public FtpDirNormalTarget option(FtpOption option) {
|
||||
if (option == null) {
|
||||
throw new NullPointerException("ftp 任务配置为空");
|
||||
@@ -88,7 +85,6 @@ public class FtpDirNormalTarget extends AbsNormalTarget<FtpDirNormalTarget> {
|
||||
*
|
||||
* @return 子任务管理器
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public SubTaskManager getSubTaskManager() {
|
||||
return mConfigHandler.getSubTaskManager();
|
||||
}
|
||||
|
||||
@@ -15,12 +15,9 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.download.target;
|
||||
|
||||
import androidx.annotation.CheckResult;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.arialyy.aria.core.common.AbsNormalTarget;
|
||||
import com.arialyy.aria.core.common.FtpOption;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.inf.Suggest;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
|
||||
@@ -34,12 +31,12 @@ public class FtpNormalTarget extends AbsNormalTarget<FtpNormalTarget> {
|
||||
FtpNormalTarget(long taskId) {
|
||||
mConfigHandler = new DNormalConfigHandler<>(this, taskId);
|
||||
getTaskWrapper().setRequestType(ITaskWrapper.D_FTP);
|
||||
getTaskWrapper().setNewTask(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置登陆、字符串编码、ftps等参数
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public FtpNormalTarget option(FtpOption option) {
|
||||
if (option == null) {
|
||||
throw new NullPointerException("ftp 任务配置为空");
|
||||
@@ -55,8 +52,7 @@ public class FtpNormalTarget extends AbsNormalTarget<FtpNormalTarget> {
|
||||
* 1、如果保存路径是该文件的保存路径,如:/mnt/sdcard/file.zip,则使用路径中的文件名file.zip
|
||||
* 2、如果保存路径是文件夹路径,如:/mnt/sdcard/,则使用FTP服务器该文件的文件名
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public FtpNormalTarget modifyFilePath(@NonNull String filePath) {
|
||||
public FtpNormalTarget modifyFilePath(String filePath) {
|
||||
int lastIndex = mConfigHandler.getUrl().lastIndexOf("/");
|
||||
getEntity().setFileName(mConfigHandler.getUrl().substring(lastIndex + 1));
|
||||
mConfigHandler.setTempFilePath(filePath);
|
||||
@@ -66,7 +62,6 @@ public class FtpNormalTarget extends AbsNormalTarget<FtpNormalTarget> {
|
||||
/**
|
||||
* 更新下载地址
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public FtpNormalTarget updateUrl(String newUrl) {
|
||||
return mConfigHandler.updateUrl(newUrl);
|
||||
}
|
||||
|
||||
@@ -15,11 +15,9 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.download.target;
|
||||
|
||||
import androidx.annotation.CheckResult;
|
||||
import com.arialyy.aria.core.common.AbsBuilderTarget;
|
||||
import com.arialyy.aria.core.common.HttpOption;
|
||||
import com.arialyy.aria.core.download.DGTaskWrapper;
|
||||
import com.arialyy.aria.core.inf.Suggest;
|
||||
import com.arialyy.aria.core.manager.SubTaskManager;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
@@ -34,14 +32,14 @@ public class GroupBuilderTarget extends AbsBuilderTarget<GroupBuilderTarget> {
|
||||
|
||||
GroupBuilderTarget(List<String> urls) {
|
||||
mConfigHandler = new HttpGroupConfigHandler<>(this, -1);
|
||||
getTaskWrapper().setRequestType(ITaskWrapper.DG_HTTP);
|
||||
mConfigHandler.setGroupUrl(urls);
|
||||
getTaskWrapper().setRequestType(ITaskWrapper.DG_HTTP);
|
||||
getTaskWrapper().setNewTask(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置http请求参数,header等信息
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public GroupBuilderTarget option(HttpOption option) {
|
||||
if (option == null) {
|
||||
throw new NullPointerException("任务配置为空");
|
||||
@@ -58,7 +56,6 @@ public class GroupBuilderTarget extends AbsBuilderTarget<GroupBuilderTarget> {
|
||||
*
|
||||
* @param fileSize 任务组总大小
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public GroupBuilderTarget setFileSize(long fileSize) {
|
||||
if (fileSize <= 0) {
|
||||
ALog.e(TAG, "文件大小不能小于 0");
|
||||
@@ -77,7 +74,6 @@ public class GroupBuilderTarget extends AbsBuilderTarget<GroupBuilderTarget> {
|
||||
* 2、如果你的知道组合任务的总长度,请使用{@link #setFileSize(long)}设置组合任务的长度。
|
||||
* 3、由于网络或其它原因的存在,这种方式获取的组合任务大小有可能是不准确的。
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public GroupBuilderTarget unknownSize() {
|
||||
((DGTaskWrapper) getTaskWrapper()).setUnknownSize(true);
|
||||
return this;
|
||||
@@ -88,7 +84,6 @@ public class GroupBuilderTarget extends AbsBuilderTarget<GroupBuilderTarget> {
|
||||
*
|
||||
* @return 子任务管理器
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public SubTaskManager getSubTaskManager() {
|
||||
return mConfigHandler.getSubTaskManager();
|
||||
}
|
||||
@@ -98,7 +93,6 @@ public class GroupBuilderTarget extends AbsBuilderTarget<GroupBuilderTarget> {
|
||||
*
|
||||
* @deprecated {@link #setSubFileName(List)} 请使用该api
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
@Deprecated public GroupBuilderTarget setSubTaskFileName(List<String> subTaskFileName) {
|
||||
return setSubFileName(subTaskFileName);
|
||||
}
|
||||
@@ -106,7 +100,6 @@ public class GroupBuilderTarget extends AbsBuilderTarget<GroupBuilderTarget> {
|
||||
/**
|
||||
* 设置任务组别名
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public GroupBuilderTarget setGroupAlias(String alias) {
|
||||
mConfigHandler.setGroupAlias(alias);
|
||||
return this;
|
||||
@@ -131,7 +124,6 @@ public class GroupBuilderTarget extends AbsBuilderTarget<GroupBuilderTarget> {
|
||||
*
|
||||
* @param dirPath 任务组保存文件夹路径
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public GroupBuilderTarget setDirPath(String dirPath) {
|
||||
return mConfigHandler.setDirPath(dirPath);
|
||||
}
|
||||
@@ -139,7 +131,6 @@ public class GroupBuilderTarget extends AbsBuilderTarget<GroupBuilderTarget> {
|
||||
/**
|
||||
* 设置子任务文件名,该方法必须在{@link #setDirPath(String)}之后调用,否则不生效
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public GroupBuilderTarget setSubFileName(List<String> subTaskFileName) {
|
||||
return mConfigHandler.setSubFileName(subTaskFileName);
|
||||
}
|
||||
|
||||
@@ -15,10 +15,8 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.download.target;
|
||||
|
||||
import androidx.annotation.CheckResult;
|
||||
import com.arialyy.aria.core.common.AbsNormalTarget;
|
||||
import com.arialyy.aria.core.common.HttpOption;
|
||||
import com.arialyy.aria.core.inf.Suggest;
|
||||
import com.arialyy.aria.core.manager.SubTaskManager;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import java.util.List;
|
||||
@@ -33,12 +31,12 @@ public class GroupNormalTarget extends AbsNormalTarget<GroupNormalTarget> {
|
||||
GroupNormalTarget(long taskId) {
|
||||
mConfigHandler = new HttpGroupConfigHandler<>(this, taskId);
|
||||
getTaskWrapper().setRequestType(ITaskWrapper.DG_HTTP);
|
||||
getTaskWrapper().setNewTask(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置http请求参数,header等信息
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public GroupNormalTarget option(HttpOption option) {
|
||||
if (option == null) {
|
||||
throw new NullPointerException("任务配置为空");
|
||||
@@ -52,7 +50,6 @@ public class GroupNormalTarget extends AbsNormalTarget<GroupNormalTarget> {
|
||||
*
|
||||
* @return 子任务管理器
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public SubTaskManager getSubTaskManager() {
|
||||
return mConfigHandler.getSubTaskManager();
|
||||
}
|
||||
@@ -60,7 +57,6 @@ public class GroupNormalTarget extends AbsNormalTarget<GroupNormalTarget> {
|
||||
/**
|
||||
* 设置任务组别名
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public GroupNormalTarget setGroupAlias(String alias) {
|
||||
mConfigHandler.setGroupAlias(alias);
|
||||
return this;
|
||||
@@ -71,7 +67,6 @@ public class GroupNormalTarget extends AbsNormalTarget<GroupNormalTarget> {
|
||||
*
|
||||
* @param urls 新的组合任务下载地址列表
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public GroupNormalTarget updateUrls(List<String> urls) {
|
||||
return mConfigHandler.updateUrls(urls);
|
||||
}
|
||||
@@ -95,7 +90,6 @@ public class GroupNormalTarget extends AbsNormalTarget<GroupNormalTarget> {
|
||||
*
|
||||
* @param dirPath 任务组保存文件夹路径
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public GroupNormalTarget modifyDirPath(String dirPath) {
|
||||
return mConfigHandler.setDirPath(dirPath);
|
||||
}
|
||||
@@ -103,7 +97,6 @@ public class GroupNormalTarget extends AbsNormalTarget<GroupNormalTarget> {
|
||||
/**
|
||||
* 更新子任务文件名,该方法必须在{@link #modifyDirPath(String)}之后调用,否则不生效
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public GroupNormalTarget modifySubFileName(List<String> subTaskFileName) {
|
||||
return mConfigHandler.setSubFileName(subTaskFileName);
|
||||
}
|
||||
|
||||
@@ -15,19 +15,14 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.download.target;
|
||||
|
||||
import androidx.annotation.CheckResult;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.arialyy.aria.core.common.AbsBuilderTarget;
|
||||
import com.arialyy.aria.core.common.HttpOption;
|
||||
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.M3U8VodOption;
|
||||
import com.arialyy.aria.core.inf.IOptionConstant;
|
||||
import com.arialyy.aria.core.inf.Suggest;
|
||||
import com.arialyy.aria.core.processor.IHttpFileLenAdapter;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import com.arialyy.aria.util.CheckUtil;
|
||||
|
||||
public class HttpBuilderTarget extends AbsBuilderTarget<HttpBuilderTarget> {
|
||||
|
||||
@@ -35,13 +30,14 @@ public class HttpBuilderTarget extends AbsBuilderTarget<HttpBuilderTarget> {
|
||||
|
||||
HttpBuilderTarget(String url) {
|
||||
mConfigHandler = new DNormalConfigHandler<>(this, -1);
|
||||
getTaskWrapper().setRequestType(ITaskWrapper.D_HTTP);
|
||||
mConfigHandler.setUrl(url);
|
||||
getTaskWrapper().setRequestType(ITaskWrapper.D_HTTP);
|
||||
getTaskWrapper().setNewTask(true);
|
||||
((DownloadEntity)getEntity()).setTaskType(ITaskWrapper.D_HTTP);
|
||||
}
|
||||
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public HttpBuilderTarget m3u8VodOption(M3U8VodOption m3U8VodOption) {
|
||||
if (m3U8VodOption == null){
|
||||
if (m3U8VodOption == null) {
|
||||
throw new NullPointerException("m3u8任务设置为空");
|
||||
}
|
||||
getTaskWrapper().setRequestType(AbsTaskWrapper.M3U8_VOD);
|
||||
@@ -50,9 +46,8 @@ public class HttpBuilderTarget extends AbsBuilderTarget<HttpBuilderTarget> {
|
||||
return this;
|
||||
}
|
||||
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public HttpBuilderTarget m3u8LiveOption(M3U8LiveOption m3U8LiveOption) {
|
||||
if (m3U8LiveOption == null){
|
||||
if (m3U8LiveOption == null) {
|
||||
throw new NullPointerException("m3u8任务设置为空");
|
||||
}
|
||||
getTaskWrapper().setRequestType(AbsTaskWrapper.M3U8_LIVE);
|
||||
@@ -63,7 +58,6 @@ public class HttpBuilderTarget extends AbsBuilderTarget<HttpBuilderTarget> {
|
||||
/**
|
||||
* 设置http请求参数,header等信息
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public HttpBuilderTarget option(HttpOption option) {
|
||||
if (option == null) {
|
||||
throw new NullPointerException("任务配置为空");
|
||||
@@ -79,8 +73,7 @@ public class HttpBuilderTarget extends AbsBuilderTarget<HttpBuilderTarget> {
|
||||
*
|
||||
* @param filePath 路径必须为文件路径,不能为文件夹路径
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public HttpBuilderTarget setFilePath(@NonNull String filePath) {
|
||||
public HttpBuilderTarget setFilePath(String filePath) {
|
||||
mConfigHandler.setTempFilePath(filePath);
|
||||
return this;
|
||||
}
|
||||
@@ -92,9 +85,10 @@ public class HttpBuilderTarget extends AbsBuilderTarget<HttpBuilderTarget> {
|
||||
*
|
||||
* @param filePath 路径必须为文件路径,不能为文件夹路径
|
||||
* @param forceDownload {@code true}强制下载,不考虑文件路径是否被占用
|
||||
* @deprecated 使用 {@link #ignoreFilePathOccupy()}
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public HttpBuilderTarget setFilePath(@NonNull String filePath, boolean forceDownload) {
|
||||
@Deprecated
|
||||
public HttpBuilderTarget setFilePath(String filePath, boolean forceDownload) {
|
||||
mConfigHandler.setTempFilePath(filePath);
|
||||
mConfigHandler.setForceDownload(forceDownload);
|
||||
return this;
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.download.target;
|
||||
|
||||
import androidx.annotation.CheckResult;
|
||||
import com.arialyy.aria.core.download.DTaskWrapper;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.inf.AbsTarget;
|
||||
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;
|
||||
@@ -59,6 +59,7 @@ class HttpGroupConfigHandler<TARGET extends AbsTarget> extends AbsGroupConfigHan
|
||||
List<DownloadEntity> subEntities = DbDataHelper.createHttpSubTask(groupHash, mUrls);
|
||||
List<DTaskWrapper> wrappers = new ArrayList<>();
|
||||
for (DownloadEntity subEntity : subEntities) {
|
||||
subEntity.setTaskType(ITaskWrapper.D_HTTP);
|
||||
wrappers.add(new DTaskWrapper(subEntity));
|
||||
}
|
||||
getEntity().setUrls(urls);
|
||||
@@ -69,7 +70,6 @@ class HttpGroupConfigHandler<TARGET extends AbsTarget> extends AbsGroupConfigHan
|
||||
/**
|
||||
* 设置子任务文件名,该方法必须在{@link #setDirPath(String)}之后调用,否则不生效
|
||||
*/
|
||||
@CheckResult
|
||||
TARGET setSubFileName(List<String> subTaskFileName) {
|
||||
if (subTaskFileName == null || subTaskFileName.isEmpty()) {
|
||||
ALog.w(TAG, "修改子任务的文件名失败:列表为null");
|
||||
@@ -90,7 +90,6 @@ class HttpGroupConfigHandler<TARGET extends AbsTarget> extends AbsGroupConfigHan
|
||||
*
|
||||
* @param urls 新的组合任务下载地址列表
|
||||
*/
|
||||
@CheckResult
|
||||
TARGET updateUrls(List<String> urls) {
|
||||
if (urls == null || urls.isEmpty()) {
|
||||
throw new NullPointerException("下载地址列表为空");
|
||||
|
||||
@@ -15,14 +15,12 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.download.target;
|
||||
|
||||
import androidx.annotation.CheckResult;
|
||||
import com.arialyy.aria.core.common.AbsNormalTarget;
|
||||
import com.arialyy.aria.core.common.HttpOption;
|
||||
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.M3U8VodOption;
|
||||
import com.arialyy.aria.core.inf.Suggest;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
|
||||
/**
|
||||
@@ -35,9 +33,9 @@ public class HttpNormalTarget extends AbsNormalTarget<HttpNormalTarget> {
|
||||
HttpNormalTarget(long taskId) {
|
||||
mConfigHandler = new DNormalConfigHandler<>(this, taskId);
|
||||
getTaskWrapper().setRequestType(getTaskWrapper().getEntity().getTaskType());
|
||||
getTaskWrapper().setNewTask(false);
|
||||
}
|
||||
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public M3U8NormalTarget m3u8VodOption(M3U8VodOption m3U8VodOption) {
|
||||
if (m3U8VodOption == null) {
|
||||
throw new NullPointerException("m3u8任务设置为空");
|
||||
@@ -48,12 +46,10 @@ public class HttpNormalTarget extends AbsNormalTarget<HttpNormalTarget> {
|
||||
return new M3U8NormalTarget((DTaskWrapper) getTaskWrapper());
|
||||
}
|
||||
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public M3U8NormalTarget m3u8VodOption() {
|
||||
return new M3U8NormalTarget((DTaskWrapper) getTaskWrapper());
|
||||
}
|
||||
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public HttpNormalTarget m3u8LiveOption(M3U8LiveOption m3U8LiveOption) {
|
||||
if (m3U8LiveOption == null) {
|
||||
throw new NullPointerException("m3u8任务设置为空");
|
||||
@@ -66,7 +62,6 @@ public class HttpNormalTarget extends AbsNormalTarget<HttpNormalTarget> {
|
||||
/**
|
||||
* 设置http请求参数,header等信息
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public HttpNormalTarget option(HttpOption option) {
|
||||
if (option == null) {
|
||||
throw new NullPointerException("任务配置为空");
|
||||
@@ -80,7 +75,6 @@ public class HttpNormalTarget extends AbsNormalTarget<HttpNormalTarget> {
|
||||
* 如:原文件路径 /mnt/sdcard/test.zip
|
||||
* 如果需要将test.zip改为game.zip,只需要重新设置文件路径为:/mnt/sdcard/game.zip
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public HttpNormalTarget modifyFilePath(String filePath) {
|
||||
mConfigHandler.setTempFilePath(filePath);
|
||||
return this;
|
||||
@@ -96,7 +90,6 @@ public class HttpNormalTarget extends AbsNormalTarget<HttpNormalTarget> {
|
||||
/**
|
||||
* 更新下载地址
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public HttpNormalTarget updateUrl(String newUrl) {
|
||||
return mConfigHandler.updateUrl(newUrl);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ public class M3U8NormalTarget extends AbsNormalTarget<M3U8NormalTarget> {
|
||||
|
||||
M3U8NormalTarget(DTaskWrapper wrapper) {
|
||||
setTaskWrapper(wrapper);
|
||||
getTaskWrapper().setNewTask(false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,11 +15,8 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.download.target;
|
||||
|
||||
import androidx.annotation.CheckResult;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.arialyy.aria.core.common.AbsBuilderTarget;
|
||||
import com.arialyy.aria.core.inf.Suggest;
|
||||
import com.arialyy.aria.core.download.tcp.TcpDelegate;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
|
||||
/**
|
||||
@@ -33,6 +30,8 @@ public class TcpBuilderTarget extends AbsBuilderTarget<TcpBuilderTarget> {
|
||||
TcpBuilderTarget(String ip, int port) {
|
||||
mConfigHandler = new DNormalConfigHandler<>(this, -1);
|
||||
getTaskWrapper().setRequestType(ITaskWrapper.D_TCP);
|
||||
((DownloadEntity) getEntity()).setTaskType(ITaskWrapper.D_TCP);
|
||||
getTaskWrapper().setNewTask(true);
|
||||
}
|
||||
//
|
||||
///**
|
||||
@@ -50,24 +49,8 @@ public class TcpBuilderTarget extends AbsBuilderTarget<TcpBuilderTarget> {
|
||||
*
|
||||
* @param filePath 路径必须为文件路径,不能为文件夹路径
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public TcpBuilderTarget setFilePath(@NonNull String filePath) {
|
||||
public TcpBuilderTarget setFilePath(String filePath) {
|
||||
mConfigHandler.setTempFilePath(filePath);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置文件存储路径,如果需要修改新的文件名,修改路径便可。
|
||||
* 如:原文件路径 /mnt/sdcard/test.zip
|
||||
* 如果需要将test.zip改为game.zip,只需要重新设置文件路径为:/mnt/sdcard/game.zip
|
||||
*
|
||||
* @param filePath 路径必须为文件路径,不能为文件夹路径
|
||||
* @param forceDownload {@code true}强制下载,不考虑文件路径是否被占用
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public TcpBuilderTarget setFilePath(@NonNull String filePath, boolean forceDownload) {
|
||||
mConfigHandler.setTempFilePath(filePath);
|
||||
mConfigHandler.setForceDownload(forceDownload);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
package com.arialyy.aria.core.inf;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import androidx.annotation.CheckResult;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.core.common.controller.BuilderController;
|
||||
import com.arialyy.aria.core.common.controller.NormalController;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
|
||||
@@ -61,7 +60,6 @@ public abstract class AbsTarget<TARGET extends AbsTarget> {
|
||||
*
|
||||
* @param str 扩展数据
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public TARGET setExtendField(String str) {
|
||||
if (TextUtils.isEmpty(str)) return (TARGET) this;
|
||||
if (TextUtils.isEmpty(mEntity.getStr()) || !mEntity.getStr().equals(str)) {
|
||||
@@ -80,7 +78,6 @@ public abstract class AbsTarget<TARGET extends AbsTarget> {
|
||||
* BuilderController#add()}
|
||||
* 等操作任务的方法,那么你需要调用{@link NormalController#save()}才能将修改保存到数据库
|
||||
*/
|
||||
@CheckResult(suggest = "after use #create()、#stop()、#cancel()、#resume()、#save()?")
|
||||
public TARGET resetState() {
|
||||
getTaskWrapper().getEntity().setState(IEntity.STATE_WAIT);
|
||||
getTaskWrapper().setRefreshInfo(true);
|
||||
|
||||
@@ -49,5 +49,5 @@ public interface IReceiver {
|
||||
*
|
||||
* @return {@link ReceiverType}
|
||||
*/
|
||||
@ReceiverType String getType();
|
||||
String getType();
|
||||
}
|
||||
|
||||
@@ -15,19 +15,10 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.inf;
|
||||
|
||||
import androidx.annotation.StringDef;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* {@link AbsReceiver}类型
|
||||
*/
|
||||
@StringDef({
|
||||
ReceiverType.DOWNLOAD,
|
||||
ReceiverType.UPLOAD,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface ReceiverType {
|
||||
public interface ReceiverType {
|
||||
String DOWNLOAD = "download";
|
||||
String UPLOAD = "upload";
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import com.arialyy.aria.core.download.DTaskWrapper;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.inf.IEntity;
|
||||
import com.arialyy.aria.core.inf.IRecordHandler;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
@@ -71,7 +72,7 @@ class DTaskWrapperFactory implements INormalTEFactory<DownloadEntity, DTaskWrapp
|
||||
|
||||
if (!entity.isComplete()) {
|
||||
TaskRecord record =
|
||||
TaskRecord.findFirst(TaskRecord.class, "filePath=?", entity.getDownloadPath());
|
||||
TaskRecord.findFirst(TaskRecord.class, "filePath=?", entity.getFilePath());
|
||||
if (record == null) {
|
||||
resetEntity(entity);
|
||||
} else {
|
||||
@@ -87,7 +88,7 @@ class DTaskWrapperFactory implements INormalTEFactory<DownloadEntity, DTaskWrapp
|
||||
resetEntity(entity);
|
||||
}
|
||||
} else if (!file.exists()
|
||||
&& record.taskType != TaskRecord.TYPE_M3U8_VOD) { // 非分块文件需要判断文件是否存在
|
||||
&& record.taskType != ITaskWrapper.M3U8_VOD) { // 非分块文件需要判断文件是否存在
|
||||
resetEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.manager;
|
||||
|
||||
import androidx.collection.LruCache;
|
||||
import android.util.LruCache;
|
||||
import com.arialyy.aria.core.download.DGTaskWrapper;
|
||||
import com.arialyy.aria.core.download.DTaskWrapper;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.core.upload.UTaskWrapper;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
package com.arialyy.aria.core.queue;
|
||||
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.download.DGTaskWrapper;
|
||||
import com.arialyy.aria.core.task.DownloadGroupTask;
|
||||
import com.arialyy.aria.core.event.DGMaxNumEvent;
|
||||
import com.arialyy.aria.core.event.Event;
|
||||
import com.arialyy.aria.core.event.EventMsgUtil;
|
||||
import com.arialyy.aria.core.scheduler.TaskSchedulers;
|
||||
import com.arialyy.aria.core.task.DownloadGroupTask;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
|
||||
/**
|
||||
@@ -57,7 +57,7 @@ public class DGroupTaskQueue
|
||||
}
|
||||
|
||||
@Override public int getMaxTaskNum() {
|
||||
return AriaManager.getInstance().getDGroupConfig().getMaxTaskNum();
|
||||
return AriaConfig.getInstance().getDConfig().getMaxTaskNum();
|
||||
}
|
||||
|
||||
@Override public DownloadGroupTask createTask(DGTaskWrapper wrapper) {
|
||||
@@ -74,6 +74,6 @@ public class DGroupTaskQueue
|
||||
}
|
||||
|
||||
@Override public int getOldMaxNum() {
|
||||
return AriaManager.getInstance().getDGroupConfig().oldMaxTaskNum;
|
||||
return AriaConfig.getInstance().getDGConfig().oldMaxTaskNum;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
|
||||
package com.arialyy.aria.core.queue;
|
||||
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.download.DTaskWrapper;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.aria.core.event.DMaxNumEvent;
|
||||
import com.arialyy.aria.core.event.Event;
|
||||
import com.arialyy.aria.core.event.EventMsgUtil;
|
||||
import com.arialyy.aria.core.inf.TaskSchedulerType;
|
||||
import com.arialyy.aria.core.scheduler.TaskSchedulers;
|
||||
import com.arialyy.aria.core.task.DownloadTask;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
@@ -60,7 +60,7 @@ public class DTaskQueue extends AbsTaskQueue<DownloadTask, DTaskWrapper> {
|
||||
}
|
||||
|
||||
@Override public int getOldMaxNum() {
|
||||
return AriaManager.getInstance().getDownloadConfig().oldMaxTaskNum;
|
||||
return AriaConfig.getInstance().getDConfig().oldMaxTaskNum;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,7 +81,7 @@ public class DTaskQueue extends AbsTaskQueue<DownloadTask, DTaskWrapper> {
|
||||
}
|
||||
}
|
||||
}
|
||||
int maxSize = AriaManager.getInstance().getDownloadConfig().getMaxTaskNum();
|
||||
int maxSize = AriaConfig.getInstance().getDConfig().getMaxTaskNum();
|
||||
int currentSize = mExecutePool.size();
|
||||
if (currentSize == 0 || currentSize < maxSize) {
|
||||
startTask(task);
|
||||
@@ -126,6 +126,6 @@ public class DTaskQueue extends AbsTaskQueue<DownloadTask, DTaskWrapper> {
|
||||
}
|
||||
|
||||
@Override public int getMaxTaskNum() {
|
||||
return AriaManager.getInstance().getDownloadConfig().getMaxTaskNum();
|
||||
return AriaConfig.getInstance().getDConfig().getMaxTaskNum();
|
||||
}
|
||||
}
|
||||
@@ -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从队列中删除任务
|
||||
*
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.arialyy.aria.core.queue;
|
||||
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import com.arialyy.aria.core.event.Event;
|
||||
import com.arialyy.aria.core.event.EventMsgUtil;
|
||||
@@ -55,11 +56,11 @@ public class UTaskQueue extends AbsTaskQueue<UploadTask, UTaskWrapper> {
|
||||
}
|
||||
|
||||
@Override public int getOldMaxNum() {
|
||||
return AriaManager.getInstance().getUploadConfig().oldMaxTaskNum;
|
||||
return AriaConfig.getInstance().getUConfig().oldMaxTaskNum;
|
||||
}
|
||||
|
||||
@Override public int getMaxTaskNum() {
|
||||
return AriaManager.getInstance().getUploadConfig().getMaxTaskNum();
|
||||
return AriaConfig.getInstance().getUConfig().getMaxTaskNum();
|
||||
}
|
||||
|
||||
@Override public UploadTask createTask(UTaskWrapper wrapper) {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.queue.pool;
|
||||
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import com.arialyy.aria.core.task.AbsTask;
|
||||
|
||||
@@ -26,6 +27,6 @@ class DGLoadExecutePool<TASK extends AbsTask> extends DLoadExecutePool<TASK> {
|
||||
private final String TAG = "DGLoadExecutePool";
|
||||
|
||||
@Override protected int getMaxSize() {
|
||||
return AriaManager.getInstance().getDGroupConfig().getMaxTaskNum();
|
||||
return AriaConfig.getInstance().getDGConfig().getMaxTaskNum();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.queue.pool;
|
||||
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.task.AbsTask;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
@@ -30,7 +30,7 @@ class DLoadExecutePool<TASK extends AbsTask> extends BaseExecutePool<TASK> {
|
||||
private final String TAG = "DownloadExecutePool";
|
||||
|
||||
@Override protected int getMaxSize() {
|
||||
return AriaManager.getInstance().getDownloadConfig().getMaxTaskNum();
|
||||
return AriaConfig.getInstance().getDConfig().getMaxTaskNum();
|
||||
}
|
||||
|
||||
@Override public boolean putTask(TASK task) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.queue.pool;
|
||||
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.task.AbsTask;
|
||||
|
||||
/**
|
||||
@@ -23,6 +23,6 @@ import com.arialyy.aria.core.task.AbsTask;
|
||||
*/
|
||||
public class UploadExecutePool<TASK extends AbsTask> extends BaseExecutePool<TASK> {
|
||||
@Override protected int getMaxSize() {
|
||||
return AriaManager.getInstance().getUploadConfig().getMaxTaskNum();
|
||||
return AriaConfig.getInstance().getUConfig().getMaxTaskNum();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.scheduler;
|
||||
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.task.ITask;
|
||||
import com.arialyy.aria.core.manager.TaskWrapperManager;
|
||||
import com.arialyy.aria.core.queue.ITaskQueue;
|
||||
import com.arialyy.aria.core.task.ITask;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import java.util.ArrayList;
|
||||
@@ -42,7 +42,6 @@ class FailureTaskHandler<TASK extends ITask> {
|
||||
private TaskSchedulers mSchedulers;
|
||||
private final ReentrantLock LOCK = new ReentrantLock();
|
||||
private Condition mCondition = LOCK.newCondition();
|
||||
private AriaManager mAriaManager;
|
||||
|
||||
static FailureTaskHandler init(TaskSchedulers schedulers) {
|
||||
if (INSTANCE == null) {
|
||||
@@ -57,7 +56,6 @@ class FailureTaskHandler<TASK extends ITask> {
|
||||
|
||||
private FailureTaskHandler(TaskSchedulers schedulers) {
|
||||
mSchedulers = schedulers;
|
||||
mAriaManager = AriaManager.getInstance();
|
||||
new Thread(new Runnable() {
|
||||
@Override public void run() {
|
||||
while (true) {
|
||||
@@ -82,35 +80,46 @@ class FailureTaskHandler<TASK extends ITask> {
|
||||
}
|
||||
|
||||
private void retryTask(final TASK task) {
|
||||
long interval = task.getTaskWrapper().getConfig().getReTryInterval();
|
||||
final int num = task.getTaskWrapper().getConfig().getReTryNum();
|
||||
final ITaskQueue queue = mSchedulers.getQueue(task.getTaskType());
|
||||
mAriaManager.getAriaHandler().postDelayed(new Runnable() {
|
||||
@Override public void run() {
|
||||
AbsEntity entity = task.getTaskWrapper().getEntity();
|
||||
if (entity.getFailNum() <= num) {
|
||||
ALog.d(TAG, String.format("任务【%s】开始重试", task.getTaskName()));
|
||||
queue.reTryStart(task);
|
||||
} else {
|
||||
queue.removeTaskFormQueue(task.getKey());
|
||||
mSchedulers.startNextTask(queue, task.getSchedulerType());
|
||||
TaskWrapperManager.getInstance().removeTaskWrapper(task.getTaskWrapper());
|
||||
}
|
||||
mExeQueue.remove(task);
|
||||
int index = mHashList.indexOf(task.hashCode());
|
||||
if (index != -1) {
|
||||
mHashList.remove(index);
|
||||
}
|
||||
if (LOCK.isLocked()) {
|
||||
try {
|
||||
LOCK.lock();
|
||||
mCondition.signalAll();
|
||||
} finally {
|
||||
LOCK.unlock();
|
||||
if (task.isNeedRetry()){
|
||||
long interval = task.getTaskWrapper().getConfig().getReTryInterval();
|
||||
final int num = task.getTaskWrapper().getConfig().getReTryNum();
|
||||
AriaConfig.getInstance().getAriaHandler().postDelayed(new Runnable() {
|
||||
@Override public void run() {
|
||||
AbsEntity entity = task.getTaskWrapper().getEntity();
|
||||
if (entity.getFailNum() <= num) {
|
||||
ALog.d(TAG, String.format("任务【%s】开始重试", task.getTaskName()));
|
||||
queue.reTryStart(task);
|
||||
} else {
|
||||
queue.removeTaskFormQueue(task.getKey());
|
||||
mSchedulers.startNextTask(queue, task.getSchedulerType());
|
||||
TaskWrapperManager.getInstance().removeTaskWrapper(task.getTaskWrapper());
|
||||
}
|
||||
next(task);
|
||||
}
|
||||
}, interval);
|
||||
}else {
|
||||
queue.removeTaskFormQueue(task.getKey());
|
||||
mSchedulers.startNextTask(queue, task.getSchedulerType());
|
||||
TaskWrapperManager.getInstance().removeTaskWrapper(task.getTaskWrapper());
|
||||
next(task);
|
||||
}
|
||||
}
|
||||
|
||||
private void next(TASK task){
|
||||
mExeQueue.remove(task);
|
||||
int index = mHashList.indexOf(task.hashCode());
|
||||
if (index != -1) {
|
||||
mHashList.remove(index);
|
||||
}
|
||||
if (LOCK.isLocked()) {
|
||||
try {
|
||||
LOCK.lock();
|
||||
mCondition.signalAll();
|
||||
} finally {
|
||||
LOCK.unlock();
|
||||
}
|
||||
}, interval);
|
||||
}
|
||||
}
|
||||
|
||||
void offer(TASK task) {
|
||||
|
||||
@@ -19,7 +19,7 @@ import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Message;
|
||||
import com.arialyy.annotations.TaskEnum;
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.common.AbsNormalEntity;
|
||||
import com.arialyy.aria.core.group.GroupSendParams;
|
||||
@@ -53,10 +53,10 @@ public class TaskSchedulers<TASK extends ITask> implements ISchedulers {
|
||||
private static FailureTaskHandler mFailureTaskHandler;
|
||||
|
||||
private Map<String, Map<TaskEnum, ISchedulerListener>> mObservers = new ConcurrentHashMap<>();
|
||||
private AriaManager mAriaManager;
|
||||
private AriaConfig mAriaConfig;
|
||||
|
||||
private TaskSchedulers() {
|
||||
mAriaManager = AriaManager.getInstance();
|
||||
mAriaConfig = AriaConfig.getInstance();
|
||||
}
|
||||
|
||||
public static TaskSchedulers getInstance() {
|
||||
@@ -230,11 +230,11 @@ public class TaskSchedulers<TASK extends ITask> implements ISchedulers {
|
||||
}
|
||||
}
|
||||
|
||||
boolean canSend = mAriaManager.getAppConfig().isUseBroadcast();
|
||||
boolean canSend = mAriaConfig.getAConfig().isUseBroadcast();
|
||||
if (canSend) {
|
||||
Intent intent = new Intent(ISchedulers.ARIA_TASK_INFO_ACTION);
|
||||
intent.putExtras(data);
|
||||
mAriaManager.getAPP().sendBroadcast(intent);
|
||||
mAriaConfig.getAPP().sendBroadcast(intent);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -284,9 +284,9 @@ public class TaskSchedulers<TASK extends ITask> implements ISchedulers {
|
||||
}
|
||||
}
|
||||
|
||||
boolean canSend = mAriaManager.getAppConfig().isUseBroadcast();
|
||||
boolean canSend = mAriaConfig.getAConfig().isUseBroadcast();
|
||||
if (canSend) {
|
||||
mAriaManager.getAPP().sendBroadcast(
|
||||
mAriaConfig.getAPP().sendBroadcast(
|
||||
createData(msg.what, ITask.DOWNLOAD_GROUP_SUB, params.entity));
|
||||
}
|
||||
|
||||
@@ -353,13 +353,13 @@ public class TaskSchedulers<TASK extends ITask> implements ISchedulers {
|
||||
startNextTask(getQueue(taskType), TaskSchedulerType.TYPE_DEFAULT);
|
||||
|
||||
// 发送广播
|
||||
boolean canSend = mAriaManager.getAppConfig().isUseBroadcast();
|
||||
boolean canSend = mAriaConfig.getAConfig().isUseBroadcast();
|
||||
if (canSend) {
|
||||
Intent intent = new Intent(ISchedulers.ARIA_TASK_INFO_ACTION);
|
||||
Bundle b = new Bundle();
|
||||
b.putInt(ISchedulers.TASK_TYPE, taskType);
|
||||
b.putInt(ISchedulers.TASK_STATE, ISchedulers.FAIL);
|
||||
mAriaManager.getAPP().sendBroadcast(intent);
|
||||
mAriaConfig.getAPP().sendBroadcast(intent);
|
||||
}
|
||||
|
||||
// 处理回调
|
||||
@@ -470,16 +470,16 @@ public class TaskSchedulers<TASK extends ITask> implements ISchedulers {
|
||||
* 发送普通任务的广播
|
||||
*/
|
||||
private void sendNormalBroadcast(int state, TASK task) {
|
||||
boolean canSend = mAriaManager.getAppConfig().isUseBroadcast();
|
||||
boolean canSend = mAriaConfig.getAConfig().isUseBroadcast();
|
||||
if (!canSend) {
|
||||
return;
|
||||
}
|
||||
int type = task.getTaskType();
|
||||
if (type == ITask.DOWNLOAD || type == ITask.DOWNLOAD_GROUP) {
|
||||
mAriaManager.getAPP().sendBroadcast(
|
||||
mAriaConfig.getAPP().sendBroadcast(
|
||||
createData(state, type, task.getTaskWrapper().getEntity()));
|
||||
} else if (type == ITask.UPLOAD) {
|
||||
mAriaManager.getAPP().sendBroadcast(
|
||||
mAriaConfig.getAPP().sendBroadcast(
|
||||
createData(state, type, task.getTaskWrapper().getEntity()));
|
||||
} else {
|
||||
ALog.w(TAG, "发送广播失败,没有对应的任务");
|
||||
@@ -519,9 +519,9 @@ public class TaskSchedulers<TASK extends ITask> implements ISchedulers {
|
||||
}
|
||||
|
||||
int num = task.getTaskWrapper().getConfig().getReTryNum();
|
||||
boolean isNotNetRetry = mAriaManager.getAppConfig().isNotNetRetry();
|
||||
boolean isNotNetRetry = mAriaConfig.getAConfig().isNotNetRetry();
|
||||
|
||||
if ((!NetUtils.isConnected(mAriaManager.getAPP()) && !isNotNetRetry)
|
||||
if ((!NetUtils.isConnected(mAriaConfig.getAPP()) && !isNotNetRetry)
|
||||
|| task.getTaskWrapper().getEntity().getFailNum() > num) {
|
||||
queue.removeTaskFormQueue(task.getKey());
|
||||
startNextTask(queue, task.getSchedulerType());
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -58,9 +60,9 @@ public class CheckUEntityUtil implements ICheckEntityUtil {
|
||||
ALog.e(TAG, "上传失败,文件路径【" + filePath + "】不合法");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查路径冲突
|
||||
if (!CheckUtil.checkUploadPathConflicts(mWrapper.isForceUpload(), filePath)) {
|
||||
// 任务是新任务,并且路径冲突就不会继续执行
|
||||
if (mWrapper.isNewTask() && !CheckUtil.checkUPathConflicts(
|
||||
mWrapper.isIgnoreFilePathOccupy(), filePath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
package com.arialyy.aria.core.upload;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import androidx.annotation.CheckResult;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.arialyy.annotations.TaskEnum;
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import com.arialyy.aria.core.command.CancelAllCmd;
|
||||
import com.arialyy.aria.core.command.CmdHelper;
|
||||
@@ -58,7 +57,7 @@ public class UploadReceiver extends AbsReceiver {
|
||||
*/
|
||||
@Deprecated
|
||||
public UploadReceiver setMaxSpeed(int maxSpeed) {
|
||||
AriaManager.getInstance().getUploadConfig().setMaxSpeed(maxSpeed);
|
||||
AriaConfig.getInstance().getUConfig().setMaxSpeed(maxSpeed);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -67,8 +66,8 @@ public class UploadReceiver extends AbsReceiver {
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
*/
|
||||
@CheckResult
|
||||
public HttpBuilderTarget load(@NonNull String filePath) {
|
||||
|
||||
public HttpBuilderTarget load(String filePath) {
|
||||
ComponentUtil.getInstance().checkComponentExist(ComponentUtil.COMPONENT_TYPE_HTTP);
|
||||
CheckUtil.checkUploadPathIsEmpty(filePath);
|
||||
return UTargetFactory.getInstance()
|
||||
@@ -81,7 +80,7 @@ public class UploadReceiver extends AbsReceiver {
|
||||
* @param taskId 任务id,可从{@link AbsBuilderTarget#create()}、{@link AbsBuilderTarget#add()}、{@link
|
||||
* AbsEntity#getId()}读取任务id
|
||||
*/
|
||||
@CheckResult
|
||||
|
||||
public HttpNormalTarget load(long taskId) {
|
||||
ComponentUtil.getInstance().checkComponentExist(ComponentUtil.COMPONENT_TYPE_HTTP);
|
||||
return UTargetFactory.getInstance()
|
||||
@@ -93,8 +92,8 @@ public class UploadReceiver extends AbsReceiver {
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
*/
|
||||
@CheckResult
|
||||
public FtpBuilderTarget loadFtp(@NonNull String filePath) {
|
||||
|
||||
public FtpBuilderTarget loadFtp(String filePath) {
|
||||
ComponentUtil.getInstance().checkComponentExist(ComponentUtil.COMPONENT_TYPE_FTP);
|
||||
CheckUtil.checkUploadPathIsEmpty(filePath);
|
||||
return UTargetFactory.getInstance()
|
||||
@@ -107,7 +106,7 @@ public class UploadReceiver extends AbsReceiver {
|
||||
* @param taskId 任务id,可从{@link AbsBuilderTarget#create()}、{@link AbsBuilderTarget#add()}、{@link
|
||||
* AbsEntity#getId()}读取任务id
|
||||
*/
|
||||
@CheckResult
|
||||
|
||||
public FtpNormalTarget loadFtp(long taskId) {
|
||||
ComponentUtil.getInstance().checkComponentExist(ComponentUtil.COMPONENT_TYPE_FTP);
|
||||
return UTargetFactory.getInstance()
|
||||
|
||||
@@ -15,11 +15,9 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.upload.target;
|
||||
|
||||
import androidx.annotation.CheckResult;
|
||||
import com.arialyy.aria.core.common.AbsBuilderTarget;
|
||||
import com.arialyy.aria.core.common.FtpOption;
|
||||
import com.arialyy.aria.core.inf.Suggest;
|
||||
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.util.CommonUtil;
|
||||
|
||||
@@ -35,6 +33,7 @@ public class FtpBuilderTarget extends AbsBuilderTarget<FtpBuilderTarget> {
|
||||
mConfigHandler = new UNormalConfigHandler<>(this, -1);
|
||||
mConfigHandler.setFilePath(filePath);
|
||||
getTaskWrapper().setRequestType(ITaskWrapper.U_FTP);
|
||||
((UploadEntity)getEntity()).setTaskType(ITaskWrapper.U_FTP);
|
||||
getTaskWrapper().setNewTask(true);
|
||||
}
|
||||
|
||||
@@ -43,7 +42,6 @@ public class FtpBuilderTarget extends AbsBuilderTarget<FtpBuilderTarget> {
|
||||
*
|
||||
* @param tempUrl 上传路径
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public FtpBuilderTarget setUploadUrl(String tempUrl) {
|
||||
url = tempUrl;
|
||||
mConfigHandler.setTempUrl(tempUrl);
|
||||
@@ -52,16 +50,18 @@ public class FtpBuilderTarget extends AbsBuilderTarget<FtpBuilderTarget> {
|
||||
|
||||
/**
|
||||
* 如果文件路径被其它任务占用,删除其它任务
|
||||
*
|
||||
* @deprecated 使用 {@link #ignoreFilePathOccupy()}
|
||||
*/
|
||||
@Deprecated
|
||||
public FtpBuilderTarget forceUpload() {
|
||||
((UTaskWrapper)getTaskWrapper()).setForceUpload(true);
|
||||
getTaskWrapper().setIgnoreFilePathOccupy(true);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置登陆、字符串编码、ftps等参数
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public FtpBuilderTarget option(FtpOption option) {
|
||||
if (option == null) {
|
||||
throw new NullPointerException("ftp 任务配置为空");
|
||||
|
||||
@@ -15,10 +15,8 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.upload.target;
|
||||
|
||||
import androidx.annotation.CheckResult;
|
||||
import com.arialyy.aria.core.common.AbsNormalTarget;
|
||||
import com.arialyy.aria.core.common.FtpOption;
|
||||
import com.arialyy.aria.core.inf.Suggest;
|
||||
import com.arialyy.aria.core.upload.UploadEntity;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
@@ -33,12 +31,12 @@ public class FtpNormalTarget extends AbsNormalTarget<FtpNormalTarget> {
|
||||
FtpNormalTarget(long taskId) {
|
||||
mConfigHandler = new UNormalConfigHandler<>(this, taskId);
|
||||
getTaskWrapper().setRequestType(ITaskWrapper.U_FTP);
|
||||
getTaskWrapper().setNewTask(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置登陆、字符串编码、ftps等参数
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public FtpNormalTarget option(FtpOption option) {
|
||||
if (option == null) {
|
||||
throw new NullPointerException("ftp 任务配置为空");
|
||||
|
||||
@@ -15,12 +15,10 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.upload.target;
|
||||
|
||||
import androidx.annotation.CheckResult;
|
||||
import com.arialyy.aria.core.common.AbsBuilderTarget;
|
||||
import com.arialyy.aria.core.common.HttpOption;
|
||||
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.upload.UploadEntity;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/2/28.
|
||||
@@ -30,12 +28,13 @@ public class HttpBuilderTarget extends AbsBuilderTarget<HttpBuilderTarget> {
|
||||
private UNormalConfigHandler<HttpBuilderTarget> mConfigHandler;
|
||||
|
||||
HttpBuilderTarget(String filePath) {
|
||||
|
||||
mConfigHandler = new UNormalConfigHandler<>(this, -1);
|
||||
mConfigHandler.setFilePath(filePath);
|
||||
//http暂时不支持断点上传
|
||||
getTaskWrapper().setSupportBP(false);
|
||||
getTaskWrapper().setRequestType(AbsTaskWrapper.U_HTTP);
|
||||
getTaskWrapper().setRequestType(ITaskWrapper.U_HTTP);
|
||||
((UploadEntity) getEntity()).setTaskType(ITaskWrapper.U_HTTP);
|
||||
getTaskWrapper().setNewTask(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -43,7 +42,6 @@ public class HttpBuilderTarget extends AbsBuilderTarget<HttpBuilderTarget> {
|
||||
*
|
||||
* @param tempUrl 上传路径
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public HttpBuilderTarget setUploadUrl(String tempUrl) {
|
||||
mConfigHandler.setTempUrl(tempUrl);
|
||||
return this;
|
||||
@@ -52,7 +50,6 @@ public class HttpBuilderTarget extends AbsBuilderTarget<HttpBuilderTarget> {
|
||||
/**
|
||||
* 设置http请求参数,header等信息
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public HttpBuilderTarget option(HttpOption option) {
|
||||
|
||||
if (option == null) {
|
||||
@@ -64,9 +61,12 @@ public class HttpBuilderTarget extends AbsBuilderTarget<HttpBuilderTarget> {
|
||||
|
||||
/**
|
||||
* 如果文件路径被其它任务占用,删除其它任务
|
||||
*
|
||||
* @deprecated 使用 {@link #ignoreFilePathOccupy()}
|
||||
*/
|
||||
@Deprecated
|
||||
public HttpBuilderTarget forceUpload() {
|
||||
((UTaskWrapper) getTaskWrapper()).setForceUpload(true);
|
||||
getTaskWrapper().setIgnoreFilePathOccupy(true);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,8 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.upload.target;
|
||||
|
||||
import androidx.annotation.CheckResult;
|
||||
import com.arialyy.aria.core.common.AbsNormalTarget;
|
||||
import com.arialyy.aria.core.common.HttpOption;
|
||||
import com.arialyy.aria.core.inf.Suggest;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
|
||||
@@ -33,6 +31,7 @@ public class HttpNormalTarget extends AbsNormalTarget<HttpNormalTarget> {
|
||||
mConfigHandler = new UNormalConfigHandler<>(this, taskId);
|
||||
getTaskWrapper().setSupportBP(false);
|
||||
getTaskWrapper().setRequestType(AbsTaskWrapper.U_HTTP);
|
||||
getTaskWrapper().setNewTask(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,7 +39,6 @@ public class HttpNormalTarget extends AbsNormalTarget<HttpNormalTarget> {
|
||||
*
|
||||
* @param tempUrl 上传路径
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public HttpNormalTarget setUploadUrl(String tempUrl) {
|
||||
mConfigHandler.setTempUrl(tempUrl);
|
||||
return this;
|
||||
@@ -49,7 +47,6 @@ public class HttpNormalTarget extends AbsNormalTarget<HttpNormalTarget> {
|
||||
/**
|
||||
* 设置http请求参数,header等信息
|
||||
*/
|
||||
@CheckResult(suggest = Suggest.TASK_CONTROLLER)
|
||||
public HttpNormalTarget option(HttpOption option) {
|
||||
if (option == null) {
|
||||
throw new NullPointerException("任务配置为空");
|
||||
|
||||
33
DEV_LOG.md
33
DEV_LOG.md
@@ -1,4 +1,37 @@
|
||||
## 开发日志
|
||||
+ v_3.8 (2019/12/17)
|
||||
- 移除androidx和support的依赖,现在无论是哪个版本的appcompat包都可以使用本框架
|
||||
- 修复一个在xml中使用fragment导致的内存泄漏问题
|
||||
- m3u8协议的key信息增加了`keyFormat`,`keyFormatVersion`字段
|
||||
- m3u8增加了`ignoreFailureTs`方法,忽略下载失败的ts切片
|
||||
- 修复在dialogFragment的`onCreateDialog()`注册导致的注解不生效问题
|
||||
- 修复组合任务初始化失败时,无法删除的问题
|
||||
- 修复`reStart()`后,无法停止的问题
|
||||
- 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)
|
||||
- fix bug https://github.com/AriaLyy/Aria/issues/543#issuecomment-559733124
|
||||
- fix bug https://github.com/AriaLyy/Aria/issues/542
|
||||
- fix bug https://github.com/AriaLyy/Aria/issues/547
|
||||
- 修复下载失败时,中断重试无效的问题
|
||||
- 增加忽略权限检查的api,`ignoreCheckPermissions()`
|
||||
- 增加通用的的忽略文件路径被占用的api,`isIgnoreFilePathOccupy()`
|
||||
+ v_3.7.9 (2019/11/28)
|
||||
- fix bug https://github.com/AriaLyy/Aria/issues/537
|
||||
+ v_3.7.8 (2019/11/28)
|
||||
- fix bug https://github.com/AriaLyy/Aria/issues/526
|
||||
- fix bug https://github.com/AriaLyy/Aria/issues/533
|
||||
- fix bug https://github.com/AriaLyy/Aria/issues/535
|
||||
- 修复ftp无法完成下载的问题
|
||||
- 修复一个非分块模式下,调用`updateUrl(newUrl)`后无法恢复下载的问题
|
||||
- 增加立即恢复任务的接口,正常来说,当执行队列满时,调用恢复任务接口,只能将任务放到缓存队列中。如果希望调用恢复接口,马上进入执行队列,需要调用`resume(true)`这个重载方法。
|
||||
- 增加M3U8加密密钥的下载地址转换器 https://github.com/AriaLyy/Aria/issues/522
|
||||
+ v_3.7.7 (2019/11/20)
|
||||
- 修复ftp无法完成下载的问题
|
||||
- 修复一个http下载崩溃的问题
|
||||
+ v_3.7.6 (2019/11/19)
|
||||
- fix bug https://github.com/AriaLyy/Aria/issues/505
|
||||
- fix bug https://github.com/AriaLyy/Aria/issues/516
|
||||
|
||||
@@ -25,8 +25,6 @@ android {
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
|
||||
implementation "androidx.appcompat:appcompat:${rootProject.ext.XAppcompatVersion}"
|
||||
|
||||
implementation project(path: ':PublicComponent')
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,13 @@
|
||||
*/
|
||||
package aria.apache.commons.net.ftp;
|
||||
|
||||
import aria.apache.commons.net.MalformedServerReplyException;
|
||||
import aria.apache.commons.net.SocketClient;
|
||||
import aria.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory;
|
||||
import aria.apache.commons.net.ftp.parser.FTPFileEntryParserFactory;
|
||||
import aria.apache.commons.net.ftp.parser.MLSxEntryParser;
|
||||
import aria.apache.commons.net.ftp.parser.ParserInitializationException;
|
||||
import aria.apache.commons.net.io.CRLFLineReader;
|
||||
import aria.apache.commons.net.io.CopyStreamAdapter;
|
||||
import aria.apache.commons.net.io.CopyStreamEvent;
|
||||
import aria.apache.commons.net.io.CopyStreamException;
|
||||
@@ -53,12 +58,6 @@ import java.util.Properties;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
import aria.apache.commons.net.MalformedServerReplyException;
|
||||
import aria.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory;
|
||||
import aria.apache.commons.net.ftp.parser.FTPFileEntryParserFactory;
|
||||
import aria.apache.commons.net.ftp.parser.MLSxEntryParser;
|
||||
import aria.apache.commons.net.io.CRLFLineReader;
|
||||
|
||||
/**
|
||||
* FTPClient encapsulates all the functionality necessary to store and
|
||||
* retrieve files from an FTP server. This class takes care of all
|
||||
@@ -2263,8 +2262,8 @@ public class FTPClient extends FTP implements Configurable {
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the feature map if not already created.
|
||||
*/
|
||||
* Create the feature map if not already created.
|
||||
*/
|
||||
private boolean initFeatureMap() throws IOException {
|
||||
if (__featuresMap == null) {
|
||||
// Don't create map here, because next line may throw exception
|
||||
@@ -2375,10 +2374,10 @@ public class FTPClient extends FTP implements Configurable {
|
||||
boolean success = FTPReply.isPositiveCompletion(sendCommand(FTPCmd.MLST, pathname));
|
||||
if (success) {
|
||||
String reply = getReplyStrings()[1];
|
||||
/* check the response makes sense.
|
||||
* Must have space before fact(s) and between fact(s) and filename
|
||||
* Fact(s) can be absent, so at least 3 chars are needed.
|
||||
*/
|
||||
/* check the response makes sense.
|
||||
* Must have space before fact(s) and between fact(s) and filename
|
||||
* Fact(s) can be absent, so at least 3 chars are needed.
|
||||
*/
|
||||
if (reply.length() < 3 || reply.charAt(0) != ' ') {
|
||||
throw new MalformedServerReplyException("Invalid server reply (MLST): '" + reply + "'");
|
||||
}
|
||||
|
||||
@@ -27,24 +27,21 @@ import aria.apache.commons.net.ftp.FTPSClient;
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.FtpUrlEntity;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.core.common.FtpConnectionMode;
|
||||
import com.arialyy.aria.core.inf.OnFileInfoCallback;
|
||||
import com.arialyy.aria.core.upload.UploadEntity;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.exception.AriaIOException;
|
||||
import com.arialyy.aria.exception.BaseException;
|
||||
import com.arialyy.aria.exception.FileNotFoundException;
|
||||
import com.arialyy.aria.exception.TaskException;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CheckUtil;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.aria.util.Regular;
|
||||
import com.arialyy.aria.util.SSLContextUtil;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
/**
|
||||
@@ -53,7 +50,7 @@ import javax.net.ssl.SSLContext;
|
||||
public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_WRAPPER extends AbsTaskWrapper<ENTITY>>
|
||||
implements Runnable {
|
||||
|
||||
private final String TAG = CommonUtil.getClassName(getClass());
|
||||
protected final String TAG = CommonUtil.getClassName(getClass());
|
||||
protected ENTITY mEntity;
|
||||
protected TASK_WRAPPER mTaskWrapper;
|
||||
protected FtpTaskOption mTaskOption;
|
||||
@@ -117,16 +114,16 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_WRAPPER ex
|
||||
}
|
||||
closeClient(client);
|
||||
|
||||
failDownload(new FileNotFoundException(TAG,
|
||||
failDownload(client,
|
||||
String.format("文件不存在,url: %s, remotePath:%s", mTaskOption.getUrlEntity().url,
|
||||
remotePath)), false);
|
||||
remotePath), null, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理拦截功能
|
||||
if (!onInterceptor(client, files)) {
|
||||
closeClient(client);
|
||||
ALog.d(TAG, "拦截器处理完成任务,任务将不再执行");
|
||||
ALog.d(TAG, "拦截器处理完成任务");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -139,9 +136,7 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_WRAPPER ex
|
||||
mTaskWrapper.setNewTask(true);
|
||||
} else {
|
||||
closeClient(client);
|
||||
failDownload(new AriaIOException(TAG,
|
||||
String.format("获取文件信息错误,url: %s, errorCode:%s, errorMsg:%s",
|
||||
mTaskOption.getUrlEntity().url, reply, client.getReplyString())), true);
|
||||
failDownload(client, "获取文件信息错误,url: " + mTaskOption.getUrlEntity().url, null, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -152,9 +147,11 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_WRAPPER ex
|
||||
onPreComplete(reply);
|
||||
mEntity.update();
|
||||
} catch (IOException e) {
|
||||
failDownload(new AriaIOException(TAG,
|
||||
String.format("FTP错误信息,code:%s,msg:%s", client.getReplyCode(), client.getReplyString()),
|
||||
e), true);
|
||||
e.printStackTrace();
|
||||
failDownload(client, "FTP错误信息", e, true);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
failDownload(client, "FTP错误信息", e, true);
|
||||
} finally {
|
||||
closeClient(client);
|
||||
}
|
||||
@@ -191,88 +188,83 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_WRAPPER ex
|
||||
/**
|
||||
* 创建FTP客户端
|
||||
*/
|
||||
private FTPClient createFtpClient() {
|
||||
private FTPClient createFtpClient() throws IOException, InterruptedException {
|
||||
FTPClient client = null;
|
||||
final FtpUrlEntity urlEntity = mTaskOption.getUrlEntity();
|
||||
try {
|
||||
Pattern p = Pattern.compile(Regular.REG_IP_V4);
|
||||
Matcher m = p.matcher(urlEntity.hostName);
|
||||
if (m.find() && m.groupCount() > 0) {
|
||||
client = newInstanceClient(urlEntity);
|
||||
client.setConnectTimeout(mConnectTimeOut); // 连接10s超时
|
||||
InetAddress ip = InetAddress.getByName(urlEntity.hostName);
|
||||
if (CheckUtil.checkIp(urlEntity.hostName)) {
|
||||
client = newInstanceClient(urlEntity);
|
||||
client.setConnectTimeout(mConnectTimeOut); // 连接10s超时
|
||||
InetAddress ip = InetAddress.getByName(urlEntity.hostName);
|
||||
|
||||
client = connect(client, new InetAddress[] { ip }, 0, Integer.parseInt(urlEntity.port));
|
||||
mTaskOption.getUrlEntity().validAddr = ip;
|
||||
} else {
|
||||
DNSQueryThread dnsThread = new DNSQueryThread(urlEntity.hostName);
|
||||
dnsThread.start();
|
||||
dnsThread.join(mConnectTimeOut);
|
||||
InetAddress[] ips = dnsThread.getIps();
|
||||
client = connect(newInstanceClient(urlEntity), ips, 0, Integer.parseInt(urlEntity.port));
|
||||
}
|
||||
|
||||
if (client == null) {
|
||||
failDownload(new AriaIOException(TAG,
|
||||
String.format("链接失败, url: %s", mTaskOption.getUrlEntity().url)), false);
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean loginSuccess = true;
|
||||
if (urlEntity.needLogin) {
|
||||
try {
|
||||
if (TextUtils.isEmpty(urlEntity.account)) {
|
||||
loginSuccess = client.login(urlEntity.user, urlEntity.password);
|
||||
} else {
|
||||
loginSuccess = client.login(urlEntity.user, urlEntity.password, urlEntity.account);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
ALog.e(TAG,
|
||||
new TaskException(TAG, String.format("登录失败,错误码为:%s, msg:%s", client.getReplyCode(),
|
||||
client.getReplyString()), e));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!loginSuccess) {
|
||||
failDownload(
|
||||
new TaskException(TAG, String.format("登录失败,错误码为:%s, msg:%s", client.getReplyCode(),
|
||||
client.getReplyString())),
|
||||
false);
|
||||
client.disconnect();
|
||||
return null;
|
||||
}
|
||||
|
||||
int reply = client.getReplyCode();
|
||||
if (!FTPReply.isPositiveCompletion(reply)) {
|
||||
client.disconnect();
|
||||
failDownload(new AriaIOException(TAG,
|
||||
String.format("无法连接到ftp服务器,filePath: %s, url: %s, errorCode: %s, errorMsg:%s",
|
||||
mEntity.getKey(), mTaskOption.getUrlEntity().url, reply,
|
||||
client.getReplyString())),
|
||||
true);
|
||||
return null;
|
||||
}
|
||||
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码
|
||||
charSet = "UTF-8";
|
||||
reply = client.sendCommand("OPTS UTF8", "ON");
|
||||
if (reply != FTPReply.COMMAND_IS_SUPERFLUOUS) {
|
||||
ALog.i(TAG, "D_FTP 服务器不支持开启UTF8编码,尝试使用Aria手动设置的编码");
|
||||
if (!TextUtils.isEmpty(mTaskOption.getCharSet())) {
|
||||
charSet = mTaskOption.getCharSet();
|
||||
}
|
||||
}
|
||||
client.setControlEncoding(charSet);
|
||||
client.setDataTimeout(10 * 1000);
|
||||
client.enterLocalPassiveMode();
|
||||
client.setFileType(FTP.BINARY_FILE_TYPE);
|
||||
} catch (IOException e) {
|
||||
closeClient(client);
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
closeClient(client);
|
||||
e.printStackTrace();
|
||||
client = connect(client, new InetAddress[] { ip }, 0, Integer.parseInt(urlEntity.port));
|
||||
mTaskOption.getUrlEntity().validAddr = ip;
|
||||
} else {
|
||||
DNSQueryThread dnsThread = new DNSQueryThread(urlEntity.hostName);
|
||||
dnsThread.start();
|
||||
dnsThread.join(mConnectTimeOut);
|
||||
InetAddress[] ips = dnsThread.getIps();
|
||||
client = connect(newInstanceClient(urlEntity), ips, 0, Integer.parseInt(urlEntity.port));
|
||||
}
|
||||
|
||||
if (client == null) {
|
||||
failDownload(client, String.format("链接失败, url: %s", mTaskOption.getUrlEntity().url), null,
|
||||
true);
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean loginSuccess = true;
|
||||
if (urlEntity.needLogin) {
|
||||
try {
|
||||
if (TextUtils.isEmpty(urlEntity.account)) {
|
||||
loginSuccess = client.login(urlEntity.user, urlEntity.password);
|
||||
} else {
|
||||
loginSuccess = client.login(urlEntity.user, urlEntity.password, urlEntity.account);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
ALog.e(TAG,
|
||||
new TaskException(TAG, String.format("登录失败,错误码为:%s, msg:%s", client.getReplyCode(),
|
||||
client.getReplyString()), e));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!loginSuccess) {
|
||||
failDownload(client, "登录失败", null, false);
|
||||
client.disconnect();
|
||||
return null;
|
||||
}
|
||||
|
||||
int reply = client.getReplyCode();
|
||||
if (!FTPReply.isPositiveCompletion(reply)) {
|
||||
failDownload(client, String.format("无法连接到ftp服务器,filePath: %s, url: %s", mEntity.getKey(),
|
||||
mTaskOption.getUrlEntity().url), null, true);
|
||||
client.disconnect();
|
||||
return null;
|
||||
}
|
||||
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码
|
||||
charSet = "UTF-8";
|
||||
reply = client.sendCommand("OPTS UTF8", "ON");
|
||||
if (reply != FTPReply.COMMAND_IS_SUPERFLUOUS) {
|
||||
ALog.i(TAG, "D_FTP 服务器不支持开启UTF8编码,尝试使用Aria手动设置的编码");
|
||||
if (!TextUtils.isEmpty(mTaskOption.getCharSet())) {
|
||||
charSet = mTaskOption.getCharSet();
|
||||
}
|
||||
}
|
||||
client.setControlEncoding(charSet);
|
||||
client.setDataTimeout(10 * 1000);
|
||||
if (mTaskOption.getConnMode() == FtpConnectionMode.DATA_CONNECTION_MODE_ACTIVITY) {
|
||||
client.enterLocalActiveMode();
|
||||
if (mTaskOption.getMinPort() != 0 && mTaskOption.getMaxPort() != 0) {
|
||||
client.setActivePortRange(mTaskOption.getMinPort(), mTaskOption.getMaxPort());
|
||||
}
|
||||
if (!TextUtils.isEmpty(mTaskOption.getActiveExternalIPAddress())) {
|
||||
client.setActiveExternalIPAddress(mTaskOption.getActiveExternalIPAddress());
|
||||
}
|
||||
} else {
|
||||
client.enterLocalPassiveMode();
|
||||
}
|
||||
client.setFileType(FTP.BINARY_FILE_TYPE);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
@@ -387,9 +379,18 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_WRAPPER ex
|
||||
protected void handleFile(String remotePath, FTPFile ftpFile) {
|
||||
}
|
||||
|
||||
protected void failDownload(BaseException e, boolean needRetry) {
|
||||
protected void failDownload(FTPClient client, String msg, Exception e, boolean needRetry) {
|
||||
if (mCallback != null) {
|
||||
mCallback.onFail(mEntity, e, needRetry);
|
||||
if (client == null) {
|
||||
msg = "创建ftp客户端失败";
|
||||
needRetry = false;
|
||||
} else {
|
||||
msg = String.format("%s, code: %s, msg: %s", msg, client.getReplyCode(),
|
||||
client.getReplyString());
|
||||
needRetry = needRetry && !CheckUtil.ftpIsBadRequest(client.getReplyCode());
|
||||
}
|
||||
|
||||
mCallback.onFail(mEntity, new AriaIOException(TAG, msg), needRetry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import aria.apache.commons.net.ftp.FTPClientConfig;
|
||||
import aria.apache.commons.net.ftp.FTPReply;
|
||||
import aria.apache.commons.net.ftp.FTPSClient;
|
||||
import com.arialyy.aria.core.FtpUrlEntity;
|
||||
import com.arialyy.aria.core.common.FtpConnectionMode;
|
||||
import com.arialyy.aria.core.common.SubThreadConfig;
|
||||
import com.arialyy.aria.core.task.AbsThreadTaskAdapter;
|
||||
import com.arialyy.aria.exception.AriaIOException;
|
||||
@@ -118,7 +119,17 @@ public abstract class BaseFtpThreadTaskAdapter extends AbsThreadTaskAdapter {
|
||||
client.setControlEncoding(charSet);
|
||||
client.setDataTimeout(getTaskConfig().getIOTimeOut());
|
||||
client.setConnectTimeout(getTaskConfig().getConnectTimeOut());
|
||||
client.enterLocalPassiveMode();
|
||||
if (mTaskOption.getConnMode() == FtpConnectionMode.DATA_CONNECTION_MODE_ACTIVITY) {
|
||||
client.enterLocalActiveMode();
|
||||
if (mTaskOption.getMinPort() != 0 && mTaskOption.getMaxPort() != 0) {
|
||||
client.setActivePortRange(mTaskOption.getMinPort(), mTaskOption.getMaxPort());
|
||||
}
|
||||
if (!TextUtils.isEmpty(mTaskOption.getActiveExternalIPAddress())) {
|
||||
client.setActiveExternalIPAddress(mTaskOption.getActiveExternalIPAddress());
|
||||
}
|
||||
} else {
|
||||
client.enterLocalPassiveMode();
|
||||
}
|
||||
client.setFileType(FTP.BINARY_FILE_TYPE);
|
||||
client.setControlKeepAliveTimeout(5000);
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.arialyy.aria.ftp;
|
||||
|
||||
import aria.apache.commons.net.ftp.FTPClient;
|
||||
import aria.apache.commons.net.ftp.FTPFile;
|
||||
import com.arialyy.aria.core.FtpUrlEntity;
|
||||
import com.arialyy.aria.core.common.CompleteInfo;
|
||||
@@ -24,8 +25,6 @@ import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.DownloadGroupEntity;
|
||||
import com.arialyy.aria.core.inf.OnFileInfoCallback;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.exception.BaseException;
|
||||
import com.arialyy.aria.util.CheckUtil;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.aria.util.RecordUtil;
|
||||
import java.nio.charset.Charset;
|
||||
@@ -74,7 +73,7 @@ public class FtpDirInfoThread extends AbsFtpInfoThread<DownloadGroupEntity, DGTa
|
||||
entity.setConvertFileSize(CommonUtil.formatFileSize(ftpFile.getSize()));
|
||||
entity.setFileSize(ftpFile.getSize());
|
||||
|
||||
//if(CheckUtil.checkDownloadPathConflicts(mTaskWrapper.is))
|
||||
//if(CheckUtil.checkDPathConflicts(mTaskWrapper.is))
|
||||
|
||||
entity.insert();
|
||||
|
||||
@@ -105,11 +104,11 @@ public class FtpDirInfoThread extends AbsFtpInfoThread<DownloadGroupEntity, DGTa
|
||||
subOption.setUploadInterceptor(mTaskOption.getUploadInterceptor());
|
||||
|
||||
subWrapper.setTaskOption(subOption);
|
||||
|
||||
}
|
||||
|
||||
@Override protected void failDownload(BaseException e, boolean needRetry) {
|
||||
super.failDownload(e, needRetry);
|
||||
@Override
|
||||
protected void failDownload(FTPClient client, String msg, Exception e, boolean needRetry) {
|
||||
super.failDownload(client, msg, e, needRetry);
|
||||
RecordUtil.delGroupTaskRecord(mTaskWrapper.getEntity(), true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public class FtpRecordAdapter extends AbsRecordHandlerAdapter {
|
||||
tr.threadId = threadId;
|
||||
tr.startLocation = startL;
|
||||
tr.isComplete = false;
|
||||
tr.threadType = TaskRecord.TYPE_HTTP_FTP;
|
||||
tr.threadType = getWrapper().getEntity().getTaskType();
|
||||
//最后一个线程的结束位置即为文件的总长度
|
||||
if (threadId == (record.threadNum - 1)) {
|
||||
endL = getEntity().getFileSize();
|
||||
@@ -81,7 +81,7 @@ public class FtpRecordAdapter extends AbsRecordHandlerAdapter {
|
||||
} else {
|
||||
record.isBlock = false;
|
||||
}
|
||||
record.taskType = TaskRecord.TYPE_HTTP_FTP;
|
||||
record.taskType = getWrapper().getEntity().getTaskType();
|
||||
record.isGroupRecord = getEntity().isGroupChild();
|
||||
if (record.isGroupRecord) {
|
||||
if (getEntity() instanceof DownloadEntity) {
|
||||
|
||||
@@ -17,9 +17,10 @@ package com.arialyy.aria.ftp;
|
||||
|
||||
import aria.apache.commons.net.ftp.FTPClientConfig;
|
||||
import com.arialyy.aria.core.FtpUrlEntity;
|
||||
import com.arialyy.aria.core.common.FtpConnectionMode;
|
||||
import com.arialyy.aria.core.inf.ITaskOption;
|
||||
import com.arialyy.aria.core.processor.FtpInterceptHandler;
|
||||
import com.arialyy.aria.core.processor.IFtpUploadInterceptor;
|
||||
import com.arialyy.aria.core.inf.ITaskOption;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.net.Proxy;
|
||||
|
||||
@@ -55,6 +56,54 @@ public class FtpTaskOption implements ITaskOption {
|
||||
*/
|
||||
private FTPClientConfig clientConfig;
|
||||
|
||||
/**
|
||||
* 连接模式,默认为被动模式
|
||||
* {@link FtpConnectionMode}
|
||||
*/
|
||||
private int connMode;
|
||||
|
||||
/**
|
||||
* 主动模式下的端口范围
|
||||
*/
|
||||
private int minPort, maxPort;
|
||||
|
||||
/**
|
||||
* 主动模式下,对外ip(可被Ftp服务器访问的ip)
|
||||
*/
|
||||
private String activeExternalIPAddress;
|
||||
|
||||
public String getActiveExternalIPAddress() {
|
||||
return activeExternalIPAddress;
|
||||
}
|
||||
|
||||
public void setActiveExternalIPAddress(String activeExternalIPAddress) {
|
||||
this.activeExternalIPAddress = activeExternalIPAddress;
|
||||
}
|
||||
|
||||
public int getMinPort() {
|
||||
return minPort;
|
||||
}
|
||||
|
||||
public void setMinPort(int minPort) {
|
||||
this.minPort = minPort;
|
||||
}
|
||||
|
||||
public int getMaxPort() {
|
||||
return maxPort;
|
||||
}
|
||||
|
||||
public void setMaxPort(int maxPort) {
|
||||
this.maxPort = maxPort;
|
||||
}
|
||||
|
||||
public int getConnMode() {
|
||||
return connMode;
|
||||
}
|
||||
|
||||
public void setConnMode(int connMode) {
|
||||
this.connMode = connMode;
|
||||
}
|
||||
|
||||
public FTPClientConfig getClientConfig() {
|
||||
return clientConfig;
|
||||
}
|
||||
|
||||
@@ -180,7 +180,9 @@ final class FtpDThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
|
||||
try {
|
||||
file =
|
||||
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()];
|
||||
int len;
|
||||
while (getThreadTask().isLive() && (len = is.read(buffer)) != -1) {
|
||||
|
||||
@@ -85,6 +85,8 @@ public class FtpDirDLoaderUtil extends AbsGroupUtil {
|
||||
* @param needCloneInfo 第一次下载,信息已经在{@link FtpDirInfoThread}中clone了
|
||||
*/
|
||||
private void startDownload(boolean needCloneInfo) {
|
||||
// ftp需要获取完成只任务信息才更新只任务数量
|
||||
getState().setSubSize(getWrapper().getSubTaskWrapper().size());
|
||||
try {
|
||||
LOCK.lock();
|
||||
condition.signalAll();
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.arialyy.aria.ftp.upload;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import com.arialyy.aria.util.BufferedRandomAccessFile;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -34,12 +33,12 @@ final class FtpFISAdapter extends InputStream {
|
||||
void onProgressCallback(byte[] buffer, int byteOffset, int byteCount) throws IOException;
|
||||
}
|
||||
|
||||
FtpFISAdapter(@NonNull BufferedRandomAccessFile is, @NonNull ProgressCallback callback) {
|
||||
FtpFISAdapter(BufferedRandomAccessFile is, ProgressCallback callback) {
|
||||
mIs = is;
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
FtpFISAdapter(@NonNull BufferedRandomAccessFile is) {
|
||||
FtpFISAdapter(BufferedRandomAccessFile is) {
|
||||
mIs = is;
|
||||
}
|
||||
|
||||
@@ -51,7 +50,7 @@ final class FtpFISAdapter extends InputStream {
|
||||
return mIs.read();
|
||||
}
|
||||
|
||||
@Override public int read(@NonNull byte[] buffer) throws IOException {
|
||||
@Override public int read(byte[] buffer) throws IOException {
|
||||
count = mIs.read(buffer);
|
||||
if (mCallback != null) {
|
||||
mCallback.onProgressCallback(buffer, 0, count);
|
||||
@@ -59,7 +58,7 @@ final class FtpFISAdapter extends InputStream {
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override public int read(@NonNull byte[] buffer, int byteOffset, int byteCount)
|
||||
@Override public int read(byte[] buffer, int byteOffset, int byteCount)
|
||||
throws IOException {
|
||||
count = mIs.read(buffer, byteOffset, byteCount);
|
||||
if (mCallback != null) {
|
||||
|
||||
@@ -22,11 +22,11 @@ import com.arialyy.aria.core.TaskRecord;
|
||||
import com.arialyy.aria.core.ThreadRecord;
|
||||
import com.arialyy.aria.core.common.CompleteInfo;
|
||||
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.UploadEntity;
|
||||
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.CommonUtil;
|
||||
import com.arialyy.aria.util.DbDataHelper;
|
||||
@@ -39,7 +39,6 @@ import java.util.List;
|
||||
* 单任务上传远程服务器文件信息
|
||||
*/
|
||||
class FtpUFileInfoThread extends AbsFtpInfoThread<UploadEntity, UTaskWrapper> {
|
||||
private static final String TAG = "FtpUploadFileInfoThread";
|
||||
static final int CODE_COMPLETE = 0xab1;
|
||||
private boolean isComplete = false;
|
||||
private String remotePath;
|
||||
@@ -59,10 +58,10 @@ class FtpUFileInfoThread extends AbsFtpInfoThread<UploadEntity, UTaskWrapper> {
|
||||
|
||||
@Override protected boolean onInterceptor(FTPClient client, FTPFile[] ftpFiles) {
|
||||
// 旧任务将不做处理,否则断点续传上传将失效
|
||||
if (!mTaskWrapper.isNewTask()) {
|
||||
ALog.d(TAG, "任务是旧任务,忽略该拦截器");
|
||||
return true;
|
||||
}
|
||||
//if (!mTaskWrapper.isNewTask()) {
|
||||
// ALog.d(TAG, "任务是旧任务,忽略该拦截器");
|
||||
// return true;
|
||||
//}
|
||||
try {
|
||||
IFtpUploadInterceptor interceptor = mTaskOption.getUploadInterceptor();
|
||||
if (interceptor != null) {
|
||||
@@ -78,7 +77,7 @@ class FtpUFileInfoThread extends AbsFtpInfoThread<UploadEntity, UTaskWrapper> {
|
||||
FtpInterceptHandler interceptHandler = interceptor.onIntercept(mEntity, files);
|
||||
|
||||
/*
|
||||
处理远端有同名文件的情况
|
||||
* 处理远端有同名文件的情况
|
||||
*/
|
||||
if (files.contains(mEntity.getFileName())) {
|
||||
if (interceptHandler.isCoverServerFile()) {
|
||||
@@ -94,6 +93,7 @@ class FtpUFileInfoThread extends AbsFtpInfoThread<UploadEntity, UTaskWrapper> {
|
||||
+ "/"
|
||||
+ interceptHandler.getNewFileName();
|
||||
mTaskOption.setNewFileName(interceptHandler.getNewFileName());
|
||||
|
||||
closeClient(client);
|
||||
run();
|
||||
return false;
|
||||
@@ -123,6 +123,9 @@ class FtpUFileInfoThread extends AbsFtpInfoThread<UploadEntity, UTaskWrapper> {
|
||||
if (ftpFile.getSize() == mEntity.getFileSize()) {
|
||||
isComplete = true;
|
||||
ALog.d(TAG, "FTP服务器上已存在该文件【" + ftpFile.getName() + "】");
|
||||
} else if (ftpFile.getSize() == 0) {
|
||||
mTaskWrapper.setNewTask(true);
|
||||
ALog.d(TAG, "FTP服务器上已存在该文件【" + ftpFile.getName() + "】,但文件长度为0,重新上传该文件");
|
||||
} else {
|
||||
ALog.w(TAG, "FTP服务器已存在未完成的文件【"
|
||||
+ ftpFile.getName()
|
||||
@@ -135,7 +138,8 @@ class FtpUFileInfoThread extends AbsFtpInfoThread<UploadEntity, UTaskWrapper> {
|
||||
mTaskWrapper.setNewTask(false);
|
||||
|
||||
// 修改记录
|
||||
TaskRecord record = DbDataHelper.getTaskRecord(mTaskWrapper.getKey());
|
||||
TaskRecord record = DbDataHelper.getTaskRecord(mTaskWrapper.getKey(),
|
||||
mTaskWrapper.getEntity().getTaskType());
|
||||
if (record == null) {
|
||||
record = new TaskRecord();
|
||||
record.fileName = mEntity.getFileName();
|
||||
|
||||
@@ -33,8 +33,8 @@ import java.io.UnsupportedEncodingException;
|
||||
* Created by Aria.Lao on 2017/7/28. D_FTP 单线程上传任务,需要FTP 服务器给用户打开append和write的权限
|
||||
*/
|
||||
class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
|
||||
private final String TAG = "FtpThreadTask";
|
||||
private String dir, remotePath;
|
||||
private boolean storeFail = false;
|
||||
|
||||
FtpUThreadTaskAdapter(SubThreadConfig config) {
|
||||
super(config);
|
||||
@@ -66,9 +66,9 @@ class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
|
||||
}
|
||||
|
||||
file =
|
||||
new BufferedRandomAccessFile(getThreadConfig().tempFile, "rwd", getTaskConfig().getBuffSize());
|
||||
if (getThreadRecord().startLocation != 0) {
|
||||
//file.skipBytes((int) getThreadConfig().START_LOCATION);
|
||||
new BufferedRandomAccessFile(getThreadConfig().tempFile, "rwd",
|
||||
getTaskConfig().getBuffSize());
|
||||
if (getThreadRecord().startLocation > 0) {
|
||||
file.seek(getThreadRecord().startLocation);
|
||||
}
|
||||
boolean complete = upload(client, file);
|
||||
@@ -79,6 +79,7 @@ class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
|
||||
String.format("任务【%s】线程__%s__上传完毕", getEntity().getKey(), getThreadRecord().threadId));
|
||||
complete();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
fail(new AriaIOException(TAG,
|
||||
String.format("上传失败,filePath: %s, uploadUrl: %s", getEntity().getFilePath(),
|
||||
getThreadConfig().url)), true);
|
||||
@@ -103,10 +104,8 @@ class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
|
||||
private void initPath() throws UnsupportedEncodingException {
|
||||
dir = CommonUtil.convertFtpChar(charSet, mTaskOption.getUrlEntity().remotePath);
|
||||
|
||||
String fileName =
|
||||
TextUtils.isEmpty(mTaskOption.getNewFileName()) ? CommonUtil.convertFtpChar(charSet,
|
||||
getEntity().getFileName())
|
||||
: CommonUtil.convertFtpChar(charSet, mTaskOption.getNewFileName());
|
||||
String fileName = TextUtils.isEmpty(mTaskOption.getNewFileName()) ? getEntity().getFileName()
|
||||
: mTaskOption.getNewFileName();
|
||||
|
||||
remotePath =
|
||||
CommonUtil.convertFtpChar(charSet,
|
||||
@@ -120,10 +119,11 @@ class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
|
||||
*/
|
||||
private boolean upload(final FTPClient client, final BufferedRandomAccessFile bis)
|
||||
throws IOException {
|
||||
|
||||
final FtpFISAdapter fa = new FtpFISAdapter(bis);
|
||||
storeFail = false;
|
||||
try {
|
||||
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;
|
||||
|
||||
@Override public void onFtpInputStream(FTPClient client, long totalBytesTransferred,
|
||||
@@ -139,23 +139,30 @@ class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
|
||||
progress(bytesTransferred);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
storeFail = true;
|
||||
try {
|
||||
fa.close();
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
closeClient(client);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
String msg = String.format("文件上传错误,错误码为:%s, msg:%s, filePath: %s", client.getReplyCode(),
|
||||
client.getReplyString(), getEntity().getFilePath());
|
||||
if (client.isConnected()) {
|
||||
client.disconnect();
|
||||
}
|
||||
closeClient(client);
|
||||
if (e.getMessage().contains("AriaIOException caught while copying")) {
|
||||
e.printStackTrace();
|
||||
} else {
|
||||
fail(new AriaIOException(TAG, msg, e), true);
|
||||
fail(new AriaIOException(TAG, msg, e), !storeFail);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (storeFail) {
|
||||
return false;
|
||||
}
|
||||
int reply = client.getReplyCode();
|
||||
if (!FTPReply.isPositiveCompletion(reply)) {
|
||||
if (reply != FTPReply.TRANSFER_ABORTED) {
|
||||
@@ -163,9 +170,7 @@ class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
|
||||
String.format("文件上传错误,错误码为:%s, msg:%s, filePath: %s", reply, client.getReplyString(),
|
||||
getEntity().getFilePath())), false);
|
||||
}
|
||||
if (client.isConnected()) {
|
||||
client.disconnect();
|
||||
}
|
||||
closeClient(client);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -10,7 +10,6 @@ android {
|
||||
versionCode rootProject.ext.versionCode
|
||||
versionName rootProject.ext.versionName
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
consumerProguardFiles 'consumer-rules.pro'
|
||||
}
|
||||
|
||||
@@ -25,9 +24,6 @@ android {
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
|
||||
implementation "androidx.appcompat:appcompat:${rootProject.ext.XAppcompatVersion}"
|
||||
|
||||
testImplementation 'junit:junit:4.12'
|
||||
implementation project(path: ':PublicComponent')
|
||||
}
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@ import com.arialyy.aria.core.common.CompleteInfo;
|
||||
import com.arialyy.aria.core.common.RequestEnum;
|
||||
import com.arialyy.aria.core.download.DTaskWrapper;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.processor.IHttpFileLenAdapter;
|
||||
import com.arialyy.aria.core.inf.OnFileInfoCallback;
|
||||
import com.arialyy.aria.core.processor.IHttpFileLenAdapter;
|
||||
import com.arialyy.aria.exception.AriaIOException;
|
||||
import com.arialyy.aria.exception.BaseException;
|
||||
import com.arialyy.aria.exception.TaskException;
|
||||
@@ -214,7 +214,7 @@ public class HttpFileInfoThread implements Runnable {
|
||||
} else {
|
||||
failDownload(new AriaIOException(TAG,
|
||||
String.format("任务下载失败,errorCode:%s, errorMsg: %s, url: %s", code,
|
||||
conn.getResponseMessage(), mEntity.getUrl())), true);
|
||||
conn.getResponseMessage(), mEntity.getUrl())), !CheckUtil.httpIsBadRequest(code));
|
||||
}
|
||||
if (end) {
|
||||
taskOption.setChunked(isChunked);
|
||||
@@ -277,7 +277,7 @@ public class HttpFileInfoThread implements Runnable {
|
||||
}
|
||||
mEntity.setFileName(newName);
|
||||
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.isComplete = false;
|
||||
|
||||
tr.threadType = TaskRecord.TYPE_HTTP_FTP;
|
||||
tr.threadType = getEntity().getTaskType();
|
||||
//最后一个线程的结束位置即为文件的总长度
|
||||
if (threadId == (record.threadNum - 1)) {
|
||||
endL = getEntity().getFileSize();
|
||||
@@ -91,7 +91,7 @@ public class HttpRecordAdapter extends AbsRecordHandlerAdapter {
|
||||
} else {
|
||||
record.isBlock = false;
|
||||
}
|
||||
record.taskType = TaskRecord.TYPE_HTTP_FTP;
|
||||
record.taskType = getEntity().getTaskType();
|
||||
record.isGroupRecord = getEntity().isGroupChild();
|
||||
if (record.isGroupRecord) {
|
||||
if (getEntity() instanceof DownloadEntity) {
|
||||
|
||||
@@ -73,6 +73,7 @@ public class DGroupLoaderUtil extends AbsGroupUtil {
|
||||
|
||||
@Override protected boolean onStart() {
|
||||
super.onStart();
|
||||
getState().setSubSize(getWrapper().getSubTaskWrapper().size());
|
||||
if (getState().getCompleteNum() == getState().getSubSize()) {
|
||||
mListener.onComplete();
|
||||
} else {
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.arialyy.aria.http.BaseHttpThreadTaskAdapter;
|
||||
import com.arialyy.aria.http.ConnectionHelp;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.BufferedRandomAccessFile;
|
||||
import com.arialyy.aria.util.FileUtil;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -111,7 +112,9 @@ final class HttpDThreadTaskAdapter extends BaseHttpThreadTaskAdapter {
|
||||
new BufferedRandomAccessFile(getThreadConfig().tempFile, "rwd",
|
||||
getTaskConfig().getBuffSize());
|
||||
//设置每条线程写入文件的位置
|
||||
file.seek(getThreadRecord().startLocation);
|
||||
if (getThreadRecord().startLocation > 0){
|
||||
file.seek(getThreadRecord().startLocation);
|
||||
}
|
||||
readNormal(is, file);
|
||||
handleComplete();
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ android {
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
|
||||
implementation "androidx.appcompat:appcompat:${rootProject.ext.XAppcompatVersion}"
|
||||
implementation project(path: ':HttpComponent')
|
||||
implementation project(path: ':PublicComponent')
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.arialyy.aria.m3u8;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import com.arialyy.aria.core.common.RecordHandler;
|
||||
import com.arialyy.aria.core.download.DTaskWrapper;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
@@ -59,6 +60,9 @@ public abstract class BaseM3U8Loader extends AbsLoader {
|
||||
|
||||
protected String getCacheDir() {
|
||||
String cacheDir = mM3U8Option.getCacheDir();
|
||||
if (TextUtils.isEmpty(cacheDir)) {
|
||||
cacheDir = FileUtil.getTsCacheDir(getEntity().getFilePath(), mM3U8Option.getBandWidth());
|
||||
}
|
||||
if (!new File(cacheDir).exists()) {
|
||||
FileUtil.createDir(cacheDir);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.M3U8Entity;
|
||||
import com.arialyy.aria.core.inf.OnFileInfoCallback;
|
||||
import com.arialyy.aria.core.processor.IBandWidthUrlConverter;
|
||||
import com.arialyy.aria.core.processor.IKeyUrlConverter;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import com.arialyy.aria.exception.M3U8Exception;
|
||||
@@ -127,7 +128,7 @@ final public class M3U8InfoThread implements Runnable {
|
||||
File indexFile = new File(indexPath);
|
||||
if (!indexFile.exists()) {
|
||||
FileUtil.createFile(indexPath);
|
||||
}else {
|
||||
} else {
|
||||
//FileUtil.deleteFile(indexPath);
|
||||
}
|
||||
fos = new FileOutputStream(indexFile);
|
||||
@@ -254,6 +255,10 @@ final public class M3U8InfoThread implements Runnable {
|
||||
m3U8Entity.keyUrl) + ".key";
|
||||
} else if (param.startsWith("IV")) {
|
||||
m3U8Entity.iv = param.split("=")[1];
|
||||
}else if (param.startsWith("KEYFORMAT")){
|
||||
m3U8Entity.keyFormat = param.split("=")[1];
|
||||
}else if (param.startsWith("KEYFORMATVERSIONS")){
|
||||
m3U8Entity.keyFormatVersion = param.split("=")[1];
|
||||
}
|
||||
}
|
||||
downloadKey(m3U8Entity);
|
||||
@@ -353,7 +358,18 @@ final public class M3U8InfoThread implements Runnable {
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
URL url = ConnectionHelp.handleUrl(info.keyUrl, mHttpOption);
|
||||
|
||||
IKeyUrlConverter keyUrlConverter = mM3U8Option.getKeyUrlConverter();
|
||||
String keyUrl = info.keyUrl;
|
||||
if (keyUrlConverter != null) {
|
||||
keyUrl = keyUrlConverter.convert(keyUrl);
|
||||
}
|
||||
if (TextUtils.isEmpty(keyUrl)){
|
||||
ALog.e(TAG, "m3u8密钥key url 为空");
|
||||
return;
|
||||
}
|
||||
|
||||
URL url = ConnectionHelp.handleUrl(keyUrl, mHttpOption);
|
||||
conn = ConnectionHelp.handleConnection(url, mHttpOption);
|
||||
ConnectionHelp.setConnectParam(mHttpOption, conn);
|
||||
conn.setConnectTimeout(mConnectTimeOut);
|
||||
|
||||
@@ -106,7 +106,7 @@ public class M3U8RecordAdapter extends AbsRecordHandlerAdapter {
|
||||
tr.threadId = threadId;
|
||||
tr.isComplete = false;
|
||||
tr.startLocation = 0;
|
||||
tr.threadType = TaskRecord.TYPE_M3U8_VOD;
|
||||
tr.threadType = getEntity().getTaskType();
|
||||
tr.tsUrl = mOption.getUrls().get(threadId);
|
||||
return tr;
|
||||
}
|
||||
@@ -118,20 +118,15 @@ public class M3U8RecordAdapter extends AbsRecordHandlerAdapter {
|
||||
record.threadRecords = new ArrayList<>();
|
||||
record.threadNum = threadNum;
|
||||
record.isBlock = true;
|
||||
|
||||
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.taskType = getEntity().getTaskType();
|
||||
record.bandWidth = mOption.getBandWidth();
|
||||
return record;
|
||||
}
|
||||
|
||||
@Override public int initTaskThreadNum() {
|
||||
if (getWrapper().getRequestType() == ITaskWrapper.M3U8_VOD) {
|
||||
return mOption.getUrls().size();
|
||||
return
|
||||
mOption.getUrls() == null || mOption.getUrls().isEmpty() ? 1 : mOption.getUrls().size();
|
||||
}
|
||||
if (getWrapper().getRequestType() == ITaskWrapper.M3U8_LIVE) {
|
||||
return 1;
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.arialyy.aria.m3u8;
|
||||
|
||||
import com.arialyy.aria.core.inf.ITaskOption;
|
||||
import com.arialyy.aria.core.processor.IBandWidthUrlConverter;
|
||||
import com.arialyy.aria.core.processor.IKeyUrlConverter;
|
||||
import com.arialyy.aria.core.processor.ILiveTsUrlConverter;
|
||||
import com.arialyy.aria.core.processor.ITsMergeHandler;
|
||||
import com.arialyy.aria.core.processor.IVodTsUrlConverter;
|
||||
@@ -103,6 +104,33 @@ public class M3U8TaskOption implements ITaskOption {
|
||||
*/
|
||||
private boolean generateIndexFile = false;
|
||||
|
||||
/**
|
||||
* 加密密钥的解密处理器
|
||||
*/
|
||||
private SoftReference<IKeyUrlConverter> keyUrlConverter;
|
||||
|
||||
/**
|
||||
* 忽略下载失败的ts切片。
|
||||
* true:即使有失败的切片,下载完成后也要合并所有切片,并进入complete回调
|
||||
*/
|
||||
private boolean ignoreFailureTs = false;
|
||||
|
||||
public boolean isIgnoreFailureTs() {
|
||||
return ignoreFailureTs;
|
||||
}
|
||||
|
||||
public void setIgnoreFailureTs(boolean ignoreFailureTs) {
|
||||
this.ignoreFailureTs = ignoreFailureTs;
|
||||
}
|
||||
|
||||
public IKeyUrlConverter getKeyUrlConverter() {
|
||||
return keyUrlConverter == null ? null : keyUrlConverter.get();
|
||||
}
|
||||
|
||||
public void setKeyUrlConverter(IKeyUrlConverter keyUrlConverter) {
|
||||
this.keyUrlConverter = new SoftReference<>(keyUrlConverter);
|
||||
}
|
||||
|
||||
public boolean isGenerateIndexFile() {
|
||||
return generateIndexFile;
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ public class M3U8LiveLoader extends BaseM3U8Loader {
|
||||
record.taskKey = mRecord.filePath;
|
||||
record.isComplete = false;
|
||||
record.tsUrl = tsUrl;
|
||||
record.threadType = TaskRecord.TYPE_M3U8_LIVE;
|
||||
record.threadType = getEntity().getTaskType();
|
||||
record.threadId = indexId;
|
||||
mRecord.threadRecords.add(record);
|
||||
|
||||
|
||||
@@ -221,9 +221,9 @@ public class M3U8VodLoader extends BaseM3U8Loader {
|
||||
}
|
||||
}
|
||||
mManager.updateStateCount();
|
||||
if (mCompleteNum <= 0){
|
||||
if (mCompleteNum <= 0) {
|
||||
mListener.onStart(0);
|
||||
}else {
|
||||
} else {
|
||||
int percent = mCompleteNum * 100 / mRecord.threadRecords.size();
|
||||
mListener.onResume(percent);
|
||||
}
|
||||
@@ -463,7 +463,8 @@ public class M3U8VodLoader extends BaseM3U8Loader {
|
||||
private int cancelNum = 0; // 已经取消的线程的数
|
||||
private int stopNum = 0; // 已经停止的线程数
|
||||
private int failNum = 0; // 失败的线程数
|
||||
private long progress; //当前总进度,百分比进度
|
||||
private long percent; //当前总进度,百分比进度
|
||||
private long progress;
|
||||
private TaskRecord taskRecord; // 任务记录
|
||||
private Looper looper;
|
||||
|
||||
@@ -480,6 +481,7 @@ public class M3U8VodLoader extends BaseM3U8Loader {
|
||||
}
|
||||
}
|
||||
this.listener = listener;
|
||||
progress = getEntity().getCurrentProgress();
|
||||
}
|
||||
|
||||
private void updateStateCount() {
|
||||
@@ -568,9 +570,9 @@ public class M3U8VodLoader extends BaseM3U8Loader {
|
||||
ALog.d(TAG, String.format("vod任务【%s】完成", mTempFile.getName()));
|
||||
|
||||
if (mM3U8Option.isGenerateIndexFile()) {
|
||||
if (generateIndexFile(false)){
|
||||
if (generateIndexFile(false)) {
|
||||
listener.onComplete();
|
||||
}else {
|
||||
} else {
|
||||
listener.onFail(false, new TaskException(TAG, "创建索引文件失败"));
|
||||
}
|
||||
} else if (mM3U8Option.isMergeFile()) {
|
||||
@@ -586,7 +588,7 @@ public class M3U8VodLoader extends BaseM3U8Loader {
|
||||
}
|
||||
break;
|
||||
case STATE_RUNNING:
|
||||
//progress += (long) msg.obj;
|
||||
progress += (long) msg.obj;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
@@ -610,7 +612,7 @@ public class M3U8VodLoader extends BaseM3U8Loader {
|
||||
int percent = completeNum * 100 / taskRecord.threadRecords.size();
|
||||
getEntity().setPercent(percent);
|
||||
getEntity().update();
|
||||
progress = percent;
|
||||
this.percent = percent;
|
||||
}
|
||||
|
||||
@Override public boolean isFail() {
|
||||
@@ -619,7 +621,11 @@ public class M3U8VodLoader extends BaseM3U8Loader {
|
||||
}
|
||||
|
||||
@Override public boolean isComplete() {
|
||||
return mCompleteNum == taskRecord.threadRecords.size() && !isJump;
|
||||
if (mM3U8Option.isIgnoreFailureTs()) {
|
||||
return mCompleteNum + failNum >= taskRecord.threadRecords.size() && !isJump;
|
||||
} else {
|
||||
return mCompleteNum == taskRecord.threadRecords.size() && !isJump;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public long getCurrentProgress() {
|
||||
|
||||
@@ -24,7 +24,6 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation "androidx.appcompat:appcompat:${rootProject.ext.XAppcompatVersion}"
|
||||
testImplementation 'junit:junit:4.12'
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkRequest;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import com.arialyy.aria.core.config.AppConfig;
|
||||
import com.arialyy.aria.core.config.Configuration;
|
||||
import com.arialyy.aria.core.config.DGroupConfig;
|
||||
@@ -56,6 +58,7 @@ public class AriaConfig {
|
||||
* 是否已经联网,true 已经联网
|
||||
*/
|
||||
private static boolean isConnectedNet = true;
|
||||
private Handler mAriaHandler;
|
||||
|
||||
private AriaConfig(Context context) {
|
||||
APP = context.getApplicationContext();
|
||||
@@ -105,6 +108,13 @@ public class AriaConfig {
|
||||
return mDGConfig;
|
||||
}
|
||||
|
||||
public synchronized Handler getAriaHandler() {
|
||||
if (mAriaHandler == null) {
|
||||
mAriaHandler = new Handler(Looper.getMainLooper());
|
||||
}
|
||||
return mAriaHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册网络监听,只有配置了检查网络{@link AppConfig#isNetCheck()}才会注册事件
|
||||
*/
|
||||
|
||||
@@ -92,7 +92,6 @@ public class FtpUrlEntity implements Cloneable {
|
||||
* 连接协议
|
||||
* {@link ProtocolType}
|
||||
*/
|
||||
@ProtocolType
|
||||
public String protocol = ProtocolType.Default;
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,20 +15,7 @@
|
||||
*/
|
||||
package com.arialyy.aria.core;
|
||||
|
||||
import androidx.annotation.StringDef;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@StringDef({
|
||||
ProtocolType.Default,
|
||||
ProtocolType.SSL,
|
||||
ProtocolType.SSLv3,
|
||||
ProtocolType.TLS,
|
||||
ProtocolType.TLSv1,
|
||||
ProtocolType.TLSv1_1,
|
||||
ProtocolType.TLSv1_2
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE) public @interface ProtocolType {
|
||||
public interface ProtocolType {
|
||||
String Default = "TLS";
|
||||
String SSL = "SSL";
|
||||
String SSLv3 = "SSLv3";
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.arialyy.aria.core.processor.FtpInterceptHandler;
|
||||
import com.arialyy.aria.core.processor.IBandWidthUrlConverter;
|
||||
import com.arialyy.aria.core.processor.IFtpUploadInterceptor;
|
||||
import com.arialyy.aria.core.processor.IHttpFileLenAdapter;
|
||||
import com.arialyy.aria.core.processor.IKeyUrlConverter;
|
||||
import com.arialyy.aria.core.processor.ILiveTsUrlConverter;
|
||||
import com.arialyy.aria.core.processor.ITsMergeHandler;
|
||||
import com.arialyy.aria.core.processor.IVodTsUrlConverter;
|
||||
@@ -61,6 +62,7 @@ public class TaskOptionParams {
|
||||
PROCESSORES.add(ILiveTsUrlConverter.class);
|
||||
PROCESSORES.add(ITsMergeHandler.class);
|
||||
PROCESSORES.add(IVodTsUrlConverter.class);
|
||||
PROCESSORES.add(IKeyUrlConverter.class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.arialyy.aria.core;
|
||||
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import com.arialyy.aria.orm.DbEntity;
|
||||
import com.arialyy.aria.orm.annotation.Ignore;
|
||||
import com.arialyy.aria.orm.annotation.NoNull;
|
||||
@@ -26,9 +27,9 @@ import java.util.List;
|
||||
* 任务上传或下载的任务记录
|
||||
*/
|
||||
public class TaskRecord extends DbEntity {
|
||||
public static final int TYPE_HTTP_FTP = 0;
|
||||
public static final int TYPE_M3U8_VOD = 1;
|
||||
public static final int TYPE_M3U8_LIVE = 2;
|
||||
//public static final int TYPE_HTTP_FTP = 0;
|
||||
//public static final int TYPE_M3U8_VOD = 1;
|
||||
//public static final int TYPE_M3U8_LIVE = 2;
|
||||
|
||||
@Ignore
|
||||
public List<ThreadRecord> threadRecords;
|
||||
@@ -41,7 +42,6 @@ public class TaskRecord extends DbEntity {
|
||||
/**
|
||||
* 任务文件路径
|
||||
*/
|
||||
@Unique
|
||||
public String filePath;
|
||||
|
||||
/**
|
||||
@@ -79,8 +79,8 @@ public class TaskRecord extends DbEntity {
|
||||
public boolean isBlock = false;
|
||||
|
||||
/**
|
||||
* 线程类型
|
||||
* {@link #TYPE_HTTP_FTP}、{@link #TYPE_M3U8_VOD}
|
||||
* 任务类型
|
||||
* {@link ITaskWrapper}
|
||||
*/
|
||||
public int taskType = 0;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.arialyy.aria.core;
|
||||
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
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;
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.arialyy.aria.core.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import com.arialyy.aria.orm.annotation.Default;
|
||||
|
||||
/**
|
||||
@@ -44,6 +45,20 @@ public abstract class AbsNormalEntity extends AbsEntity implements Parcelable {
|
||||
private boolean isRedirect = false; //是否重定向
|
||||
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() {
|
||||
return url;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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,
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.common;
|
||||
|
||||
/**
|
||||
* FTP 连接模式
|
||||
*/
|
||||
public interface FtpConnectionMode {
|
||||
/**
|
||||
* 被动模式
|
||||
*/
|
||||
int DATA_CONNECTION_MODE_PASV = 0;
|
||||
/**
|
||||
* 主动模式
|
||||
*/
|
||||
int DATA_CONNECTION_MODE_ACTIVITY = 1;
|
||||
}
|
||||
@@ -71,8 +71,11 @@ public class RecordHandler implements IRecordHandler {
|
||||
convertDb();
|
||||
} else {
|
||||
mAdapter.onPre();
|
||||
mTaskRecord = DbDataHelper.getTaskRecord(getFilePath());
|
||||
mTaskRecord = DbDataHelper.getTaskRecord(getFilePath(), mEntity.getTaskType());
|
||||
if (mTaskRecord == null) {
|
||||
if (!new File(getFilePath()).exists()){
|
||||
FileUtil.createFile(getFilePath());
|
||||
}
|
||||
initRecord(true);
|
||||
} else {
|
||||
File file = new File(mTaskRecord.filePath);
|
||||
|
||||
@@ -63,7 +63,8 @@ public class RecordHelper {
|
||||
fileExists = true;
|
||||
}
|
||||
// 处理文件被删除的情况
|
||||
if (fileExists) {
|
||||
if (!fileExists) {
|
||||
ALog.w(TAG, String.format("文件【%s】被删除,重新分配线程区间", mTaskRecord.filePath));
|
||||
for (int i = 0; i < mTaskRecord.threadNum; i++) {
|
||||
long startL = i * blockSize, endL = (i + 1) * blockSize;
|
||||
ThreadRecord tr = mTaskRecord.threadRecords.get(i);
|
||||
|
||||
@@ -15,17 +15,7 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.config;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@IntDef({
|
||||
ConfigType.DOWNLOAD,
|
||||
ConfigType.UPLOAD,
|
||||
ConfigType.APP,
|
||||
ConfigType.D_GROUP
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE) @interface ConfigType {
|
||||
public interface ConfigType {
|
||||
int DOWNLOAD = 1;
|
||||
int UPLOAD = 2;
|
||||
int APP = 3;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user