diff --git a/Aria/build.gradle b/Aria/build.gradle
index 7b8287a2..3d928fe3 100644
--- a/Aria/build.gradle
+++ b/Aria/build.gradle
@@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
android {
compileSdkVersion 23
- buildToolsVersion '25.0.2'
+ buildToolsVersion '25.0.3'
defaultConfig {
minSdkVersion 9
@@ -22,8 +22,7 @@ dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
- compile project(':AriaCompiler')
-// compile project(':AriaAnnotations')
+// compile project(':AriaCompiler')
+ compile project(':AriaAnnotations') //gradle 打包时打开这个
}
-//apply from: 'bintray-release.gradle'
-//apply from: 'jcenter.gradle'
+apply from: 'bintray-release.gradle'
diff --git a/Aria/jcenter.gradle b/Aria/jcenter.gradle
index efbb3ea1..8ce3129a 100644
--- a/Aria/jcenter.gradle
+++ b/Aria/jcenter.gradle
@@ -76,7 +76,7 @@ artifacts {
//################################# jcenter 上传配置 start #########################################
bintray {
// user = hasProperty("bintrayUser") ? getProperty("bintrayUser") : getProperty("BINTRAY_USER")
-// key = hasProperty("bintrayKey") ? getProperty("bintrayKey") : getProperty("BINTRAY_KEY")
+// groupName = hasProperty("bintrayKey") ? getProperty("bintrayKey") : getProperty("BINTRAY_KEY")
user = BINTRAY_USER
key = BINTRAY_KEY
configurations = ['archives']
diff --git a/Aria/src/main/java/com/arialyy/aria/core/Aria.java b/Aria/src/main/java/com/arialyy/aria/core/Aria.java
index 27e19d2e..5dc70cfe 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/Aria.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/Aria.java
@@ -59,62 +59,6 @@ import com.arialyy.aria.core.upload.UploadTask;
*
*/
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) public class Aria {
- /**
- * 不支持断点
- */
- public static final String ACTION_SUPPORT_BREAK_POINT = "ACTION_SUPPORT_BREAK_POINT";
- /**
- * 预处理完成
- */
- public static final String ACTION_PRE = "ACTION_PRE";
- /**
- * 下载开始前事件
- */
- public static final String ACTION_POST_PRE = "ACTION_POST_PRE";
- /**
- * 开始下载事件
- */
- public static final String ACTION_START = "ACTION_START";
- /**
- * 恢复下载事件
- */
- public static final String ACTION_RESUME = "ACTION_RESUME";
- /**
- * 正在下载事件
- */
- public static final String ACTION_RUNNING = "ACTION_RUNNING";
- /**
- * 停止下载事件
- */
- public static final String ACTION_STOP = "ACTION_STOP";
- /**
- * 取消下载事件
- */
- public static final String ACTION_CANCEL = "ACTION_CANCEL";
- /**
- * 下载完成事件
- */
- public static final String ACTION_COMPLETE = "ACTION_COMPLETE";
- /**
- * 下载失败事件
- */
- public static final String ACTION_FAIL = "ACTION_FAIL";
- /**
- * 下载实体
- */
- public static final String DOWNLOAD_ENTITY = "DOWNLOAD_ENTITY";
- /**
- * 上传实体
- */
- public static final String UPLOAD_ENTITY = "UPLOAD_ENTITY";
- /**
- * 位置
- */
- public static final String CURRENT_LOCATION = "CURRENT_LOCATION";
- /**
- * 速度
- */
- public static final String CURRENT_SPEED = "CURRENT_SPEED";
private Aria() {
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
index dacb0aea..41bb1525 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
@@ -29,14 +29,13 @@ import android.text.TextUtils;
import android.util.Log;
import android.widget.PopupWindow;
import com.arialyy.aria.core.download.DownloadReceiver;
-import com.arialyy.aria.core.inf.ICmd;
+import com.arialyy.aria.core.command.ICmd;
import com.arialyy.aria.core.inf.IReceiver;
import com.arialyy.aria.core.upload.UploadReceiver;
import com.arialyy.aria.orm.DbUtil;
import com.arialyy.aria.util.CommonUtil;
import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -86,6 +85,26 @@ import org.xml.sax.SAXException;
return mReceivers;
}
+ /**
+ * 设置上传任务的执行队列类型
+ *
+ * @param mod {@link com.arialyy.aria.core.QueueMod}
+ */
+ public AriaManager setUploadQueueMod(QueueMod mod) {
+ mUConfig.setQueueMod(mod.tag);
+ return this;
+ }
+
+ /**
+ * 设置下载任务的执行队列类型
+ *
+ * @param mod {@link com.arialyy.aria.core.QueueMod}
+ */
+ public AriaManager setDownloadQueueMod(QueueMod mod) {
+ mDConfig.setQueueMod(mod.tag);
+ return this;
+ }
+
/**
* 如果需要在代码中修改下载配置,请使用以下方法
*
diff --git a/Aria/src/main/java/com/arialyy/aria/core/ConfigHelper.java b/Aria/src/main/java/com/arialyy/aria/core/ConfigHelper.java
index e4c94262..d0df8509 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/ConfigHelper.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/ConfigHelper.java
@@ -54,9 +54,6 @@ class ConfigHelper extends DefaultHandler {
case "threadNum":
loadThreadNum(value);
break;
- case "openBroadcast":
- loadBroadcast(value);
- break;
case "maxTaskNum":
loadMaxQueue(value);
break;
@@ -86,16 +83,33 @@ class ConfigHelper extends DefaultHandler {
case "maxSpeed":
loadMaxSpeed(value);
break;
+ case "queueMod":
+ loadQueueMod(value);
+ break;
}
}
}
+ private void loadQueueMod(String value) {
+ String mod = "now";
+ if (!TextUtils.isEmpty(value) && (value.equalsIgnoreCase("now") || value.equalsIgnoreCase(
+ "wait"))) {
+ mod = value;
+ }
+ if (isDownloadConfig) {
+ mDownloadConfig.queueMod = mod;
+ }
+ if (isUploadConfig) {
+ mUploadConfig.queueMod = mod;
+ }
+ }
+
private void loadMaxSpeed(String value) {
double maxSpeed = 0.0;
if (!TextUtils.isEmpty(value)) {
maxSpeed = Double.parseDouble(value);
}
- if (isDownloadConfig){
+ if (isDownloadConfig) {
mDownloadConfig.msxSpeed = maxSpeed;
}
}
@@ -207,16 +221,6 @@ class ConfigHelper extends DefaultHandler {
}
}
- private void loadBroadcast(String value) {
- boolean open = Boolean.parseBoolean(value);
- if (isDownloadConfig) {
- mDownloadConfig.isOpenBreadCast = open;
- }
- if (isUploadConfig) {
- mUploadConfig.isOpenBreadCast = open;
- }
- }
-
private void loadThreadNum(String value) {
int num = 3;
if (!TextUtils.isEmpty(value)) {
diff --git a/Aria/src/main/java/com/arialyy/aria/core/QueueMod.java b/Aria/src/main/java/com/arialyy/aria/core/QueueMod.java
new file mode 100644
index 00000000..db9e7b6c
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/QueueMod.java
@@ -0,0 +1,31 @@
+package com.arialyy.aria.core;
+
+/**
+ * Created by Aria.Lao on 2017/6/21.
+ * 执行队列类型
+ */
+public enum QueueMod {
+ /**
+ * 等待模式,
+ * 如果执行队列已经满了,再对其它任务(TASK_A)使用start命令执行任务时
+ * 1、TASK_A添加到缓存队列中,当执行队列中的任务完成时,系统会将自动执行缓存队列中的TASK_A
+ * 2、如果再次对TASK_A使用start命令,TASK_A将会立刻执行
+ */
+ WAIT("wait"),
+
+ /**
+ * 立刻执行模式
+ * 如果执行队列已经满了,再次使用start命令执行任务时,该任务会添加到执行队列队尾,而原来执行队列的队首任务会停止
+ */
+ NOW("now");
+
+ String tag;
+
+ public String getTag() {
+ return tag;
+ }
+
+ QueueMod(String tag) {
+ this.tag = tag;
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmd.java
index 1107dbfd..d337a453 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmd.java
@@ -16,43 +16,20 @@
package com.arialyy.aria.core.command;
-import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
-import com.arialyy.aria.core.queue.DownloadTaskQueue;
import com.arialyy.aria.core.queue.ITaskQueue;
-import com.arialyy.aria.core.inf.ICmd;
-import com.arialyy.aria.core.queue.UploadTaskQueue;
-import com.arialyy.aria.core.upload.UploadTaskEntity;
-import com.arialyy.aria.util.CheckUtil;
-import com.arialyy.aria.util.CommonUtil;
/**
- * Created by lyy on 2016/8/22.
- * 下载命令
+ * Created by AriaL on 2017/6/29.
*/
-public abstract class AbsCmd implements ICmd {
- ITaskQueue mQueue;
- T mEntity;
- String TAG;
- String mTargetName;
+public abstract class AbsCmd implements ICmd{
+ protected ITaskQueue mQueue;
+ protected T mTaskEntity;
+ protected String TAG;
+ protected String mTargetName;
/**
- * 能否执行命令
+ * 是否是下载任务的命令
+ * {@code true} 下载任务的命令,{@code false} 上传任务的命令
*/
- boolean canExeCmd = true;
-
- /**
- * @param targetName 产生任务的对象名
- */
- AbsCmd(String targetName, T entity) {
- canExeCmd = CheckUtil.checkCmdEntity(entity,
- !(this instanceof CancelCmd) || !(this instanceof StopCmd));
- mTargetName = targetName;
- mEntity = entity;
- TAG = CommonUtil.getClassName(this);
- if (entity instanceof DownloadTaskEntity) {
- mQueue = DownloadTaskQueue.getInstance();
- } else if (entity instanceof UploadTaskEntity) {
- mQueue = UploadTaskQueue.getInstance();
- }
- }
-}
\ No newline at end of file
+ protected boolean isDownloadCmd = true;
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmdFactory.java b/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmdFactory.java
new file mode 100644
index 00000000..8ed0d498
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmdFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.arialyy.aria.core.command;
+
+import com.arialyy.aria.core.inf.AbsTaskEntity;
+
+/**
+ * Created by AriaL on 2017/6/29.
+ * 抽象命令工厂
+ */
+public abstract class AbsCmdFactory {
+
+ /**
+ * @param target 创建任务的对象
+ * @param entity 下载实体
+ */
+ public abstract CMD createCmd(String target, T entity, int type);
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/ICmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/ICmd.java
similarity index 90%
rename from Aria/src/main/java/com/arialyy/aria/core/inf/ICmd.java
rename to Aria/src/main/java/com/arialyy/aria/core/command/ICmd.java
index 482cfb0c..dc938037 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/inf/ICmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/ICmd.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.arialyy.aria.core.inf;
+package com.arialyy.aria.core.command;
/**
* Created by lyy on 2017/2/9.
@@ -23,5 +23,5 @@ public interface ICmd {
/**
* 执行命令
*/
- public abstract void executeCmd();
+ void executeCmd();
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/group/AbsGroupCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/group/AbsGroupCmd.java
new file mode 100644
index 00000000..5d24fa67
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/group/AbsGroupCmd.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.arialyy.aria.core.command.group;
+
+import com.arialyy.aria.core.command.AbsCmd;
+import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
+import com.arialyy.aria.core.download.DownloadTaskEntity;
+import com.arialyy.aria.core.inf.AbsTaskEntity;
+import com.arialyy.aria.core.queue.DownloadGroupTaskQueue;
+import com.arialyy.aria.core.queue.DownloadTaskQueue;
+import com.arialyy.aria.core.queue.UploadTaskQueue;
+import com.arialyy.aria.core.upload.UploadTaskEntity;
+import com.arialyy.aria.util.CommonUtil;
+
+/**
+ * Created by AriaL on 2017/6/29.
+ * 任务组命令
+ */
+abstract class AbsGroupCmd extends AbsCmd {
+
+ /**
+ * @param targetName 创建任务的对象名
+ */
+ AbsGroupCmd(String targetName, T entity) {
+ mTargetName = targetName;
+ mTaskEntity = entity;
+ TAG = CommonUtil.getClassName(this);
+ if (entity instanceof DownloadGroupTaskEntity) {
+ mQueue = DownloadGroupTaskQueue.getInstance();
+ isDownloadCmd = true;
+ }
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupCancelCmd.java
similarity index 56%
rename from Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java
rename to Aria/src/main/java/com/arialyy/aria/core/command/group/GroupCancelCmd.java
index 82821ea8..5b6e5cf9 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupCancelCmd.java
@@ -13,34 +13,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package com.arialyy.aria.core.command.group;
-package com.arialyy.aria.core.command;
-
-import android.text.TextUtils;
-import com.arialyy.aria.core.inf.ITask;
import com.arialyy.aria.core.inf.AbsTaskEntity;
/**
- * Created by lyy on 2016/8/22.
- * 开始命令
+ * Created by AriaL on 2017/6/29.
+ * 删除任务组
*/
-class StartCmd extends AbsCmd {
-
- StartCmd(String targetName, T entity) {
+class GroupCancelCmd extends AbsGroupCmd {
+ /**
+ * @param targetName 创建任务的对象名
+ */
+ GroupCancelCmd(String targetName, T entity) {
super(targetName, entity);
}
@Override public void executeCmd() {
- if (!canExeCmd) return;
- ITask task = mQueue.getTask(mEntity.getEntity());
- if (task == null) {
- task = mQueue.createTask(mTargetName, mEntity);
- }
- if (task != null) {
- if (!TextUtils.isEmpty(mTargetName)) {
- task.setTargetName(mTargetName);
- }
- mQueue.startTask(task);
- }
+
}
-}
\ No newline at end of file
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupCmdFactory.java b/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupCmdFactory.java
new file mode 100644
index 00000000..a818d688
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupCmdFactory.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.arialyy.aria.core.command.group;
+
+import com.arialyy.aria.core.AriaManager;
+import com.arialyy.aria.core.command.AbsCmdFactory;
+import com.arialyy.aria.core.inf.AbsTaskEntity;
+
+/**
+ * Created by AriaL on 2017/6/29.
+ */
+class GroupCmdFactory extends AbsCmdFactory {
+ /**
+ * 启动任务
+ */
+ public static final int TASK_START = 0xa1;
+ /**
+ * 停止任务
+ */
+ public static final int TASK_STOP = 0xa2;
+ /**
+ * 取消任务
+ */
+ public static final int TASK_CANCEL = 0xa3;
+
+ private static volatile GroupCmdFactory INSTANCE = null;
+
+ private GroupCmdFactory() {
+
+ }
+
+ public static GroupCmdFactory getInstance() {
+ if (INSTANCE == null) {
+ synchronized (AriaManager.LOCK) {
+ INSTANCE = new GroupCmdFactory();
+ }
+ }
+ return INSTANCE;
+ }
+
+ /**
+ * @param target 创建任务的对象
+ * @param entity 下载实体
+ * @param type 命令类型{@link #TASK_START}、{@link #TASK_CANCEL}、{@link #TASK_STOP}
+ */
+ public AbsGroupCmd createCmd(String target, T entity, int type) {
+ switch (type) {
+ case TASK_START:
+ return new GroupStartCmd<>(target, entity);
+ case TASK_STOP:
+ return new GroupStopCmd<>(target, entity);
+ case TASK_CANCEL:
+ return new GroupCancelCmd<>(target, entity);
+ default:
+ return null;
+ }
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStartCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStartCmd.java
new file mode 100644
index 00000000..4fde6115
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStartCmd.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.arialyy.aria.core.command.group;
+
+import android.text.TextUtils;
+import com.arialyy.aria.core.AriaManager;
+import com.arialyy.aria.core.QueueMod;
+import com.arialyy.aria.core.inf.AbsGroupTask;
+import com.arialyy.aria.core.inf.AbsTaskEntity;
+import com.arialyy.aria.core.inf.IEntity;
+
+/**
+ * Created by AriaL on 2017/6/29.
+ * 任务组开始命令,该命令负责开始下载或恢复下载的操作
+ */
+class GroupStartCmd extends AbsGroupCmd {
+ /**
+ * @param targetName 创建任务的对象名
+ */
+ GroupStartCmd(String targetName, T entity) {
+ super(targetName, entity);
+ }
+
+ @Override public void executeCmd() {
+ String mod;
+ int maxTaskNum;
+ AriaManager manager = AriaManager.getInstance(AriaManager.APP);
+ if (isDownloadCmd) {
+ mod = manager.getDownloadConfig().getQueueMod();
+ maxTaskNum = manager.getDownloadConfig().getMaxTaskNum();
+ } else {
+ mod = manager.getUploadConfig().getQueueMod();
+ maxTaskNum = manager.getUploadConfig().getMaxTaskNum();
+ }
+
+ AbsGroupTask task = (AbsGroupTask) mQueue.getTask(mTaskEntity.getEntity());
+ if (task == null) {
+ task = (AbsGroupTask) mQueue.createTask(mTargetName, mTaskEntity);
+ if (!TextUtils.isEmpty(mTargetName)) {
+ task.setTargetName(mTargetName);
+ }
+ // 任务不存在时,根据配置不同,对任务执行操作
+ if (mod.equals(QueueMod.NOW.getTag())) {
+ mQueue.startTask(task);
+ } else if (mod.equals(QueueMod.WAIT.getTag())) {
+ if (mQueue.getCurrentExePoolNum() < maxTaskNum) {
+ mQueue.startTask(task);
+ }
+ }
+ } else {
+ // 任务不存在时,根据配置不同,对任务执行操作
+ if (!task.isRunning()
+ && mod.equals(QueueMod.WAIT.getTag())
+ && task.getState() == IEntity.STATE_WAIT) {
+ mQueue.startTask(task);
+ }
+ }
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStopCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStopCmd.java
new file mode 100644
index 00000000..85c400bd
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStopCmd.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.arialyy.aria.core.command.group;
+
+import com.arialyy.aria.core.inf.AbsTaskEntity;
+
+/**
+ * Created by AriaL on 2017/6/29.
+ * 停止任务组的命令
+ */
+class GroupStopCmd extends AbsGroupCmd{
+ /**
+ * @param targetName 创建任务的对象名
+ */
+ GroupStopCmd(String targetName, T entity) {
+ super(targetName, entity);
+ }
+
+ @Override public void executeCmd() {
+
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/AbsNormalCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/AbsNormalCmd.java
new file mode 100644
index 00000000..675a918a
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/AbsNormalCmd.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.arialyy.aria.core.command.normal;
+
+import com.arialyy.aria.core.command.AbsCmd;
+import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
+import com.arialyy.aria.core.download.DownloadTaskEntity;
+import com.arialyy.aria.core.inf.AbsTaskEntity;
+import com.arialyy.aria.core.queue.DownloadGroupTaskQueue;
+import com.arialyy.aria.core.queue.DownloadTaskQueue;
+import com.arialyy.aria.core.queue.UploadTaskQueue;
+import com.arialyy.aria.core.upload.UploadTaskEntity;
+import com.arialyy.aria.util.CheckUtil;
+import com.arialyy.aria.util.CommonUtil;
+
+/**
+ * Created by lyy on 2016/8/22.
+ * 下载命令
+ */
+public abstract class AbsNormalCmd extends AbsCmd {
+
+ /**
+ * 能否执行命令
+ */
+ boolean canExeCmd = true;
+
+ /**
+ * @param targetName 产生任务的对象名
+ */
+ AbsNormalCmd(String targetName, T entity) {
+ //canExeCmd = CheckUtil.checkCmdEntity(entity,
+ // !(this instanceof CancelCmd) || !(this instanceof StopCmd));
+ mTargetName = targetName;
+ mTaskEntity = entity;
+ TAG = CommonUtil.getClassName(this);
+ if (entity instanceof DownloadTaskEntity) {
+ mQueue = DownloadTaskQueue.getInstance();
+ isDownloadCmd = true;
+ } else if (entity instanceof UploadTaskEntity) {
+ mQueue = UploadTaskQueue.getInstance();
+ isDownloadCmd = false;
+ } else if (entity instanceof DownloadGroupTaskEntity) {
+ mQueue = DownloadGroupTaskQueue.getInstance();
+ isDownloadCmd = true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/AddCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/AddCmd.java
similarity index 76%
rename from Aria/src/main/java/com/arialyy/aria/core/command/AddCmd.java
rename to Aria/src/main/java/com/arialyy/aria/core/command/normal/AddCmd.java
index fe6d481b..e848813b 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/AddCmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/AddCmd.java
@@ -14,18 +14,18 @@
* limitations under the License.
*/
-package com.arialyy.aria.core.command;
+package com.arialyy.aria.core.command.normal;
import android.util.Log;
+import com.arialyy.aria.core.inf.AbsTask;
import com.arialyy.aria.core.inf.IEntity;
-import com.arialyy.aria.core.inf.ITask;
import com.arialyy.aria.core.inf.AbsTaskEntity;
/**
* Created by lyy on 2016/8/22.
* 添加任务的命令
*/
-class AddCmd extends AbsCmd {
+class AddCmd extends AbsNormalCmd {
AddCmd(String targetName, T entity) {
super(targetName, entity);
@@ -33,10 +33,10 @@ class AddCmd extends AbsCmd {
@Override public void executeCmd() {
if (!canExeCmd) return;
- ITask task = mQueue.getTask(mEntity.getEntity());
+ AbsTask task = mQueue.getTask(mTaskEntity.getEntity());
if (task == null) {
- mEntity.getEntity().setState(IEntity.STATE_WAIT);
- mQueue.createTask(mTargetName, mEntity);
+ mTaskEntity.getEntity().setState(IEntity.STATE_WAIT);
+ mQueue.createTask(mTargetName, mTaskEntity);
} else {
Log.w(TAG, "添加命令执行失败,【该任务已经存在】");
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java
new file mode 100644
index 00000000..375b2ffd
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.arialyy.aria.core.command.normal;
+
+import com.arialyy.aria.core.download.DownloadGroupEntity;
+import com.arialyy.aria.core.download.DownloadTaskEntity;
+import com.arialyy.aria.core.inf.AbsTaskEntity;
+import com.arialyy.aria.core.upload.UploadTaskEntity;
+import com.arialyy.aria.orm.DbEntity;
+import com.arialyy.aria.util.CommonUtil;
+import java.util.List;
+
+/**
+ * Created by AriaL on 2017/6/27.
+ * 删除所有任务,并且删除所有回掉
+ */
+final class CancelAllCmd extends AbsNormalCmd {
+ /**
+ * @param targetName 产生任务的对象名
+ */
+ CancelAllCmd(String targetName, T entity) {
+ super(targetName, entity);
+ }
+
+ @Override public void executeCmd() {
+ mQueue.removeAllTask();
+ if (mTaskEntity instanceof DownloadTaskEntity) {
+ handleDownloadRemove();
+ } else {
+ handleUploadRemove();
+ }
+ }
+
+ /**
+ * 处理上传的删除
+ */
+ private void handleUploadRemove() {
+ List allEntity = DbEntity.findAllData(UploadTaskEntity.class);
+ for (UploadTaskEntity entity : allEntity) {
+ CommonUtil.delUploadTaskConfig(mTaskEntity.removeFile, entity);
+ }
+ }
+
+ /**
+ * 处理下载的删除
+ */
+ private void handleDownloadRemove() {
+ List allEntity = DbEntity.findAllData(DownloadTaskEntity.class);
+ for (DownloadTaskEntity entity : allEntity) {
+ CommonUtil.delDownloadTaskConfig(mTaskEntity.removeFile, entity);
+ }
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/CancelCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelCmd.java
similarity index 75%
rename from Aria/src/main/java/com/arialyy/aria/core/command/CancelCmd.java
rename to Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelCmd.java
index ad2aecd8..ff859066 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/CancelCmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelCmd.java
@@ -14,32 +14,33 @@
* limitations under the License.
*/
-package com.arialyy.aria.core.command;
+package com.arialyy.aria.core.command.normal;
import android.text.TextUtils;
-import com.arialyy.aria.core.inf.ITask;
+import com.arialyy.aria.core.inf.AbsNormalTask;
+import com.arialyy.aria.core.inf.AbsTask;
import com.arialyy.aria.core.inf.AbsTaskEntity;
/**
* Created by lyy on 2016/9/20.
* 取消命令
*/
-class CancelCmd extends AbsCmd {
+class CancelCmd extends AbsNormalCmd {
CancelCmd(String targetName, T entity) {
super(targetName, entity);
}
@Override public void executeCmd() {
if (!canExeCmd) return;
- ITask task = mQueue.getTask(mEntity.getEntity());
+ AbsTask task = mQueue.getTask(mTaskEntity.getEntity());
if (task == null) {
- task = mQueue.createTask(mTargetName, mEntity);
+ task = mQueue.createTask(mTargetName, mTaskEntity);
}
if (task != null) {
if (!TextUtils.isEmpty(mTargetName)) {
task.setTargetName(mTargetName);
}
- mQueue.cancelTask(task);
+ mQueue.removeTask(task);
}
}
}
\ No newline at end of file
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/HighestPriorityCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/HighestPriorityCmd.java
similarity index 78%
rename from Aria/src/main/java/com/arialyy/aria/core/command/HighestPriorityCmd.java
rename to Aria/src/main/java/com/arialyy/aria/core/command/normal/HighestPriorityCmd.java
index 74999611..e0efa2f7 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/HighestPriorityCmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/HighestPriorityCmd.java
@@ -13,11 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.arialyy.aria.core.command;
+package com.arialyy.aria.core.command.normal;
import android.text.TextUtils;
-import com.arialyy.aria.core.inf.ITask;
+import com.arialyy.aria.core.download.DownloadTask;
+import com.arialyy.aria.core.inf.AbsNormalTask;
import com.arialyy.aria.core.inf.AbsTaskEntity;
+import com.arialyy.aria.core.queue.DownloadTaskQueue;
/**
* Created by lyy on 2017/6/2.
@@ -28,8 +30,10 @@ import com.arialyy.aria.core.inf.AbsTaskEntity;
* 4、用户手动暂停或任务完成后,第二次重新执行该任务,该命令将失效
* 5、如果下载队列中已经满了,则会停止队尾的任务,当高优先级任务完成后,该队尾任务将自动执行
* 6、把任务设置为最高优先级任务后,将自动执行任务,不需要重新调用start()启动任务
+ *
+ * 目前只只支持单下载任务的最高优先级任务
*/
-final class HighestPriorityCmd extends AbsCmd {
+final class HighestPriorityCmd extends AbsNormalCmd {
/**
* @param targetName 产生任务的对象名
*/
@@ -39,15 +43,15 @@ final class HighestPriorityCmd extends AbsCmd {
@Override public void executeCmd() {
if (!canExeCmd) return;
- ITask task = mQueue.getTask(mEntity.getEntity());
+ DownloadTask task = (DownloadTask) mQueue.getTask(mTaskEntity.getEntity());
if (task == null) {
- task = mQueue.createTask(mTargetName, mEntity);
+ task = (DownloadTask) mQueue.createTask(mTargetName, mTaskEntity);
}
if (task != null) {
if (!TextUtils.isEmpty(mTargetName)) {
task.setTargetName(mTargetName);
}
- mQueue.setTaskHighestPriority(task);
+ ((DownloadTaskQueue) mQueue).setTaskHighestPriority(task);
}
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/CmdFactory.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/NormalCmdFactory.java
similarity index 80%
rename from Aria/src/main/java/com/arialyy/aria/core/command/CmdFactory.java
rename to Aria/src/main/java/com/arialyy/aria/core/command/normal/NormalCmdFactory.java
index ae725b51..85aa33fc 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/CmdFactory.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/NormalCmdFactory.java
@@ -14,16 +14,17 @@
* limitations under the License.
*/
-package com.arialyy.aria.core.command;
+package com.arialyy.aria.core.command.normal;
import com.arialyy.aria.core.AriaManager;
+import com.arialyy.aria.core.command.AbsCmdFactory;
import com.arialyy.aria.core.inf.AbsTaskEntity;
/**
* Created by Lyy on 2016/9/23.
* 命令工厂
*/
-public class CmdFactory {
+public class NormalCmdFactory extends AbsCmdFactory {
/**
* 创建任务
*/
@@ -56,17 +57,20 @@ public class CmdFactory {
* 恢复所有停止的任务
*/
public static final int TASK_RESUME_ALL = 0x130;
+ /**
+ * 删除所有任务,
+ */
+ public static final int TASK_CANCEL_ALL = 0x131;
+ private static volatile NormalCmdFactory INSTANCE = null;
- private static volatile CmdFactory INSTANCE = null;
-
- private CmdFactory() {
+ private NormalCmdFactory() {
}
- public static CmdFactory getInstance() {
+ public static NormalCmdFactory getInstance() {
if (INSTANCE == null) {
synchronized (AriaManager.LOCK) {
- INSTANCE = new CmdFactory();
+ INSTANCE = new NormalCmdFactory();
}
}
return INSTANCE;
@@ -78,7 +82,7 @@ public class CmdFactory {
* @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}
*/
- public AbsCmd createCmd(String target, T entity, int type) {
+ public AbsNormalCmd createCmd(String target, T entity, int type) {
switch (type) {
case TASK_CREATE:
return new AddCmd<>(target, entity);
@@ -95,6 +99,8 @@ public class CmdFactory {
return new StopAllCmd<>(target, entity);
case TASK_RESUME_ALL:
return new ResumeAllCmd<>(target, entity);
+ case TASK_CANCEL_ALL:
+ return new CancelAllCmd<>(target, entity);
default:
return null;
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/ResumeAllCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/ResumeAllCmd.java
similarity index 73%
rename from Aria/src/main/java/com/arialyy/aria/core/command/ResumeAllCmd.java
rename to Aria/src/main/java/com/arialyy/aria/core/command/normal/ResumeAllCmd.java
index c7110077..1233ebe1 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/ResumeAllCmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/ResumeAllCmd.java
@@ -1,11 +1,11 @@
-package com.arialyy.aria.core.command;
+package com.arialyy.aria.core.command.normal;
import android.util.Log;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
+import com.arialyy.aria.core.inf.AbsTask;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IEntity;
-import com.arialyy.aria.core.inf.ITask;
import com.arialyy.aria.orm.DbEntity;
import java.util.List;
@@ -15,7 +15,7 @@ import java.util.List;
* 1.如果执行队列没有满,则开始下载任务,直到执行队列满
* 2.如果队列执行队列已经满了,则将所有任务添加到等待队列中
*/
-final class ResumeAllCmd extends AbsCmd {
+final class ResumeAllCmd extends AbsNormalCmd {
/**
* @param targetName 产生任务的对象名
*/
@@ -27,9 +27,9 @@ final class ResumeAllCmd extends AbsCmd {
List allEntity =
DbEntity.findDatas(DownloadEntity.class, "state=?", IEntity.STATE_STOP + "");
for (DownloadEntity entity : allEntity) {
- int exeNum = mQueue.getExeTaskNum();
+ int exeNum = mQueue.getCurrentExePoolNum();
if (exeNum == 0 || exeNum < mQueue.getMaxTaskNum()) {
- ITask task = createTask(entity);
+ AbsTask task = createTask(entity);
mQueue.startTask(task);
} else {
entity.setState(IEntity.STATE_WAIT);
@@ -38,10 +38,11 @@ final class ResumeAllCmd extends AbsCmd {
}
}
- private ITask createTask(DownloadEntity entity) {
- ITask task = mQueue.getTask(entity);
+ private AbsTask createTask(DownloadEntity entity) {
+ AbsTask task = mQueue.getTask(entity);
if (task == null) {
- DownloadTaskEntity taskEntity = new DownloadTaskEntity(entity);
+ DownloadTaskEntity taskEntity = new DownloadTaskEntity();
+ taskEntity.entity = entity;
task = mQueue.createTask(mTargetName, taskEntity);
} else {
Log.w(TAG, "添加命令执行失败,【该任务已经存在】");
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/StartCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/StartCmd.java
new file mode 100644
index 00000000..7da4a5ca
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/StartCmd.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.arialyy.aria.core.command.normal;
+
+import android.text.TextUtils;
+import com.arialyy.aria.core.AriaManager;
+import com.arialyy.aria.core.QueueMod;
+import com.arialyy.aria.core.download.DownloadGroupTask;
+import com.arialyy.aria.core.download.DownloadTask;
+import com.arialyy.aria.core.inf.AbsTask;
+import com.arialyy.aria.core.inf.IEntity;
+import com.arialyy.aria.core.inf.AbsTaskEntity;
+import com.arialyy.aria.core.queue.DownloadGroupTaskQueue;
+import com.arialyy.aria.core.queue.DownloadTaskQueue;
+import com.arialyy.aria.core.scheduler.DQueueMapping;
+import com.arialyy.aria.orm.Primary;
+
+/**
+ * Created by lyy on 2016/8/22.
+ * 开始命令
+ * 队列模型{@link QueueMod#NOW}、{@link QueueMod#WAIT}
+ */
+class StartCmd extends AbsNormalCmd {
+
+ StartCmd(String targetName, T entity) {
+ super(targetName, entity);
+ }
+
+ @Override public void executeCmd() {
+ if (!canExeCmd) return;
+ String mod;
+ int maxTaskNum;
+ AriaManager manager = AriaManager.getInstance(AriaManager.APP);
+ if (isDownloadCmd) {
+ mod = manager.getDownloadConfig().getQueueMod();
+ maxTaskNum = manager.getDownloadConfig().getMaxTaskNum();
+ } else {
+ mod = manager.getUploadConfig().getQueueMod();
+ maxTaskNum = manager.getUploadConfig().getMaxTaskNum();
+ }
+
+ AbsTask task = mQueue.getTask(mTaskEntity.getEntity());
+ if (task == null) {
+ task = mQueue.createTask(mTargetName, mTaskEntity);
+ if (!TextUtils.isEmpty(mTargetName)) {
+ task.setTargetName(mTargetName);
+ }
+ // 任务不存在时,根据配置不同,对任务执行操作
+ if (mod.equals(QueueMod.NOW.getTag())) {
+ mQueue.startTask(task);
+ } else if (mod.equals(QueueMod.WAIT.getTag())) {
+ if (mQueue.getCurrentExePoolNum() < maxTaskNum
+ || task.getState() == IEntity.STATE_STOP
+ || task.getState() == IEntity.STATE_COMPLETE) {
+ mQueue.startTask(task);
+ }
+ }
+ } else {
+ // 任务不存在时,根据配置不同,对任务执行操作
+ if (!task.isRunning()) {
+ mQueue.startTask(task);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/StopAllCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/StopAllCmd.java
similarity index 75%
rename from Aria/src/main/java/com/arialyy/aria/core/command/StopAllCmd.java
rename to Aria/src/main/java/com/arialyy/aria/core/command/normal/StopAllCmd.java
index 2c16378e..431adfdd 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/StopAllCmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/StopAllCmd.java
@@ -1,4 +1,4 @@
-package com.arialyy.aria.core.command;
+package com.arialyy.aria.core.command.normal;
import com.arialyy.aria.core.inf.AbsTaskEntity;
@@ -6,7 +6,7 @@ import com.arialyy.aria.core.inf.AbsTaskEntity;
* Created by AriaL on 2017/6/13.
* 停止所有任务的命令,并清空所有等待队列
*/
-final class StopAllCmd extends AbsCmd {
+final class StopAllCmd extends AbsNormalCmd {
/**
* @param targetName 产生任务的对象名
*/
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/StopCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/StopCmd.java
similarity index 78%
rename from Aria/src/main/java/com/arialyy/aria/core/command/StopCmd.java
rename to Aria/src/main/java/com/arialyy/aria/core/command/normal/StopCmd.java
index 1e1fb295..9d0b0811 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/StopCmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/StopCmd.java
@@ -14,19 +14,19 @@
* limitations under the License.
*/
-package com.arialyy.aria.core.command;
+package com.arialyy.aria.core.command.normal;
import android.text.TextUtils;
import android.util.Log;
+import com.arialyy.aria.core.inf.AbsTask;
import com.arialyy.aria.core.inf.IEntity;
-import com.arialyy.aria.core.inf.ITask;
import com.arialyy.aria.core.inf.AbsTaskEntity;
/**
* Created by lyy on 2016/9/20.
* 停止命令
*/
-class StopCmd extends AbsCmd {
+class StopCmd extends AbsNormalCmd {
StopCmd(String targetName, T entity) {
super(targetName, entity);
@@ -34,10 +34,10 @@ class StopCmd extends AbsCmd {
@Override public void executeCmd() {
if (!canExeCmd) return;
- ITask task = mQueue.getTask(mEntity.getEntity());
+ AbsTask task = mQueue.getTask(mTaskEntity.getEntity());
if (task == null) {
- if (mEntity.getEntity().getState() == IEntity.STATE_RUNNING) {
- task = mQueue.createTask(mTargetName, mEntity);
+ if (mTaskEntity.getEntity().getState() == IEntity.STATE_RUNNING) {
+ task = mQueue.createTask(mTargetName, mTaskEntity);
mQueue.stopTask(task);
} else {
Log.w(TAG, "停止命令执行失败,【调度器中没有该任务】");
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DListener.java b/Aria/src/main/java/com/arialyy/aria/core/download/DListener.java
new file mode 100644
index 00000000..2d31b0d8
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DListener.java
@@ -0,0 +1,144 @@
+/*
+ * 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.download;
+
+import android.os.Handler;
+import com.arialyy.aria.core.AriaManager;
+import com.arialyy.aria.core.download.downloader.DownloadListener;
+import com.arialyy.aria.core.inf.AbsEntity;
+import com.arialyy.aria.core.inf.AbsTask;
+import com.arialyy.aria.core.inf.IEntity;
+import com.arialyy.aria.core.scheduler.ISchedulers;
+import com.arialyy.aria.util.CommonUtil;
+import java.lang.ref.WeakReference;
+
+/**
+ * 下载监听类
+ */
+class DListener>
+ extends DownloadListener {
+ private WeakReference outHandler;
+ private long lastLen = 0; //上一次发送长度
+ private boolean isFirst = true;
+ private ENTITY entity;
+ private TASK task;
+ private boolean isConvertSpeed = false;
+ boolean isWait = false;
+
+ DListener(TASK task, Handler outHandler) {
+ this.outHandler = new WeakReference<>(outHandler);
+ this.task = new WeakReference<>(task).get();
+ this.entity = this.task.getEntity();
+ final AriaManager manager = AriaManager.getInstance(AriaManager.APP);
+ isConvertSpeed = manager.getDownloadConfig().isConvertSpeed();
+ }
+
+ @Override public void onPre() {
+ saveData(IEntity.STATE_PRE, -1);
+ sendInState2Target(ISchedulers.PRE);
+ }
+
+ @Override public void onPostPre(long fileSize) {
+ entity.setFileSize(fileSize);
+ entity.setConvertFileSize(CommonUtil.formatFileSize(fileSize));
+ saveData(IEntity.STATE_POST_PRE, -1);
+ sendInState2Target(ISchedulers.POST_PRE);
+ }
+
+ @Override public void onStart(long startLocation) {
+ saveData(IEntity.STATE_RUNNING, startLocation);
+ sendInState2Target(ISchedulers.START);
+ }
+
+ @Override public void onResume(long resumeLocation) {
+ saveData(IEntity.STATE_RUNNING, resumeLocation);
+ sendInState2Target(ISchedulers.RESUME);
+ }
+
+ @Override public void onProgress(long currentLocation) {
+ entity.setCurrentProgress(currentLocation);
+ long speed = currentLocation - lastLen;
+ if (isFirst) {
+ speed = 0;
+ isFirst = false;
+ }
+ handleSpeed(speed);
+ sendInState2Target(ISchedulers.RUNNING);
+ lastLen = currentLocation;
+ }
+
+ @Override public void onStop(long stopLocation) {
+ saveData(isWait ? IEntity.STATE_WAIT : IEntity.STATE_STOP, stopLocation);
+ handleSpeed(0);
+ sendInState2Target(ISchedulers.STOP);
+ }
+
+ @Override public void onCancel() {
+ saveData(IEntity.STATE_CANCEL, -1);
+ handleSpeed(0);
+ sendInState2Target(ISchedulers.CANCEL);
+ }
+
+ @Override public void onComplete() {
+ saveData(IEntity.STATE_COMPLETE, entity.getFileSize());
+ handleSpeed(0);
+ sendInState2Target(ISchedulers.COMPLETE);
+ }
+
+ @Override public void onFail() {
+ entity.setFailNum(entity.getFailNum() + 1);
+ saveData(IEntity.STATE_FAIL, -1);
+ handleSpeed(0);
+ sendInState2Target(ISchedulers.FAIL);
+ }
+
+ private void handleSpeed(long speed) {
+ if (isConvertSpeed) {
+ entity.setConvertSpeed(CommonUtil.formatFileSize(speed) + "/s");
+ } else {
+ entity.setSpeed(speed);
+ }
+ }
+
+ /**
+ * 将任务状态发送给下载器
+ *
+ * @param state {@link ISchedulers#START}
+ */
+ private void sendInState2Target(int state) {
+ if (outHandler.get() != null) {
+ outHandler.get().obtainMessage(state, task).sendToTarget();
+ }
+ }
+
+ private void saveData(int state, long location) {
+ if (state == IEntity.STATE_CANCEL) {
+ entity.deleteData();
+ } else if (state == IEntity.STATE_COMPLETE) {
+ entity.setState(state);
+ entity.setComplete(true);
+ entity.setCompleteTime(System.currentTimeMillis());
+ entity.setCurrentProgress(entity.getFileSize());
+ entity.update();
+ } else {
+ entity.setState(state);
+ if (location != -1) {
+ entity.setCurrentProgress(location);
+ }
+ entity.update();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java
index 5c0e18bf..f710c50f 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java
@@ -18,25 +18,107 @@ package com.arialyy.aria.core.download;
import android.os.Parcel;
import android.os.Parcelable;
-import com.arialyy.aria.core.inf.AbsEntity;
-import com.arialyy.aria.orm.Ignore;
+import com.arialyy.aria.core.inf.AbsNormalEntity;
+import com.arialyy.aria.core.inf.AbsTaskEntity;
+import com.arialyy.aria.orm.Primary;
/**
* Created by lyy on 2015/12/25.
* 下载实体
- * !!! 注意:CREATOR要进行@Ignore注解
- * !!!并且需要Parcelable时需要手动填写rowID;
*/
-public class DownloadEntity extends AbsEntity implements Parcelable {
+public class DownloadEntity extends AbsNormalEntity implements Parcelable {
private String downloadUrl = ""; //下载路径
- private String downloadPath = ""; //保存路径
- private boolean isDownloadComplete = false; //是否下载完成
+ @Primary private String downloadPath = ""; //保存路径
private boolean isRedirect = false; //是否重定向
private String redirectUrl = ""; //重定向链接
+ /**
+ * 所属任务组
+ */
+ private String groupName = "";
+
+ /**
+ * 通过{@link AbsTaskEntity#md5Key}从服务器的返回信息中获取的文件md5信息,如果服务器没有返回,则不会设置该信息
+ * 如果你已经设置了该任务的MD5信息,Aria也不会从服务器返回的信息中获取该信息
+ */
+ private String md5Code = "";
+
+ /**
+ * 通过{@link AbsTaskEntity#dispositionKey}从服务器的返回信息中获取的文件描述信息
+ */
+ private String disposition = "";
+
+ /**
+ * 从disposition获取到的文件名,如果可以获取到,则会赋值到这个字段
+ */
+ private String serverFileName = "";
+
+ @Override public String getKey() {
+ return downloadUrl;
+ }
+
public DownloadEntity() {
}
+ @Override public String toString() {
+ return "DownloadEntity{"
+ + "downloadUrl='"
+ + downloadUrl
+ + '\''
+ + ", downloadPath='"
+ + downloadPath
+ + '\''
+ + ", isRedirect="
+ + isRedirect
+ + ", redirectUrl='"
+ + redirectUrl
+ + '\''
+ + ", groupName='"
+ + groupName
+ + '\''
+ + ", md5Code='"
+ + md5Code
+ + '\''
+ + ", disposition='"
+ + disposition
+ + '\''
+ + ", serverFileName='"
+ + serverFileName
+ + '\''
+ + '}';
+ }
+
+ public String getMd5Code() {
+ return md5Code;
+ }
+
+ public void setMd5Code(String md5Code) {
+ this.md5Code = md5Code;
+ }
+
+ public String getDisposition() {
+ return disposition;
+ }
+
+ public void setDisposition(String disposition) {
+ this.disposition = disposition;
+ }
+
+ public String getServerFileName() {
+ return serverFileName;
+ }
+
+ public void setServerFileName(String serverFileName) {
+ this.serverFileName = serverFileName;
+ }
+
+ public String getGroupName() {
+ return groupName;
+ }
+
+ public void setGroupName(String groupName) {
+ this.groupName = groupName;
+ }
public String getDownloadUrl() {
return downloadUrl;
@@ -56,14 +138,6 @@ public class DownloadEntity extends AbsEntity implements Parcelable {
return this;
}
- public boolean isDownloadComplete() {
- return isDownloadComplete;
- }
-
- public void setDownloadComplete(boolean downloadComplete) {
- isDownloadComplete = downloadComplete;
- }
-
@Override public DownloadEntity clone() throws CloneNotSupportedException {
return (DownloadEntity) super.clone();
}
@@ -92,21 +166,27 @@ public class DownloadEntity extends AbsEntity implements Parcelable {
super.writeToParcel(dest, flags);
dest.writeString(this.downloadUrl);
dest.writeString(this.downloadPath);
- dest.writeByte(this.isDownloadComplete ? (byte) 1 : (byte) 0);
dest.writeByte(this.isRedirect ? (byte) 1 : (byte) 0);
dest.writeString(this.redirectUrl);
+ dest.writeString(this.groupName);
+ dest.writeString(this.md5Code);
+ dest.writeString(this.disposition);
+ dest.writeString(this.serverFileName);
}
protected DownloadEntity(Parcel in) {
super(in);
this.downloadUrl = in.readString();
this.downloadPath = in.readString();
- this.isDownloadComplete = in.readByte() != 0;
this.isRedirect = in.readByte() != 0;
this.redirectUrl = in.readString();
+ this.groupName = in.readString();
+ this.md5Code = in.readString();
+ this.disposition = in.readString();
+ this.serverFileName = in.readString();
}
- @Ignore public static final Creator CREATOR = new Creator() {
+ public static final Creator CREATOR = new Creator() {
@Override public DownloadEntity createFromParcel(Parcel source) {
return new DownloadEntity(source);
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java
new file mode 100644
index 00000000..da96b5ff
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java
@@ -0,0 +1,102 @@
+/*
+ * 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.download;
+
+import android.os.Parcel;
+import com.arialyy.aria.core.inf.AbsGroupEntity;
+import com.arialyy.aria.orm.NormalList;
+import com.arialyy.aria.orm.OneToMany;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by AriaL on 2017/6/29.
+ * 下载任务组实体
+ */
+public class DownloadGroupEntity extends AbsGroupEntity {
+
+ @OneToMany(table = DownloadEntity.class, key = "groupName") private List subtask =
+ new ArrayList<>();
+
+ /**
+ * 子任务链接组
+ */
+ @NormalList(clazz = String.class) private List urls = new ArrayList<>();
+
+ /**
+ * 任务组下载文件的文件夹地址
+ *
+ * @see DownloadGroupTarget#setDownloadDirPath(String)
+ */
+ private String dirPath = "";
+
+ public List getSubTask() {
+ return subtask;
+ }
+
+ void setSubTasks(List subTasks) {
+ this.subtask = subTasks;
+ }
+
+ public String getDirPath() {
+ return dirPath;
+ }
+
+ public void setDirPath(String dirPath) {
+ this.dirPath = dirPath;
+ }
+
+ public List getUrls() {
+ return urls;
+ }
+
+ void setUrls(List urls) {
+ this.urls = urls;
+ }
+
+ void setGroupName(String key) {
+ this.groupName = key;
+ }
+
+ public DownloadGroupEntity() {
+ }
+
+ @Override public int describeContents() {
+ return 0;
+ }
+
+ @Override public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeTypedList(this.subtask);
+ dest.writeString(this.dirPath);
+ }
+
+ protected DownloadGroupEntity(Parcel in) {
+ super(in);
+ this.subtask = in.createTypedArrayList(DownloadEntity.CREATOR);
+ this.dirPath = in.readString();
+ }
+
+ public static final Creator CREATOR = new Creator() {
+ @Override public DownloadGroupEntity createFromParcel(Parcel source) {
+ return new DownloadGroupEntity(source);
+ }
+
+ @Override public DownloadGroupEntity[] newArray(int size) {
+ return new DownloadGroupEntity[size];
+ }
+ };
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java
new file mode 100644
index 00000000..e77e1c06
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java
@@ -0,0 +1,241 @@
+/*
+ * 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.download;
+
+import android.text.TextUtils;
+import com.arialyy.aria.core.inf.AbsGroupTarget;
+import com.arialyy.aria.orm.DbEntity;
+import com.arialyy.aria.orm.DbUtil;
+import com.arialyy.aria.util.CheckUtil;
+import com.arialyy.aria.util.CommonUtil;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by AriaL on 2017/6/29.
+ */
+public class DownloadGroupTarget
+ extends AbsGroupTarget {
+ private List mUrls = new ArrayList<>();
+ private final String TAG = "DownloadGroupTarget";
+ /**
+ * 子任务文件名
+ */
+ private List mSubTaskFileName = new ArrayList<>();
+ private String mGroupName;
+ /**
+ * 是否已经设置了文件路径
+ */
+ private boolean isSetDirPathed = false;
+
+ DownloadGroupTarget(DownloadGroupEntity groupEntity, String targetName) {
+ this.mTargetName = targetName;
+ if (groupEntity.getUrls() != null && !groupEntity.getUrls().isEmpty()) {
+ this.mUrls.addAll(groupEntity.getUrls());
+ }
+ init(groupEntity.getGroupName());
+ }
+
+ DownloadGroupTarget(List urls, String targetName) {
+ this.mTargetName = targetName;
+ this.mUrls = urls;
+ init(CommonUtil.getMd5Code(urls));
+ }
+
+ private void init(String key) {
+ mGroupName = key;
+ mTaskEntity = DbEntity.findFirst(DownloadGroupTaskEntity.class, "key=?", key);
+ if (mTaskEntity == null) {
+ mTaskEntity = new DownloadGroupTaskEntity();
+ mTaskEntity.key = key;
+ mTaskEntity.entity = getDownloadGroupEntity();
+ mTaskEntity.insert();
+ }
+ if (mTaskEntity.entity == null) {
+ mTaskEntity.entity = getDownloadGroupEntity();
+ }
+ mEntity = mTaskEntity.entity;
+ }
+
+ /**
+ * 查询任务组实体,如果数据库不存在该实体,则新创建一个新的任务组实体
+ */
+ private DownloadGroupEntity getDownloadGroupEntity() {
+ DownloadGroupEntity entity =
+ DbEntity.findFirst(DownloadGroupEntity.class, "groupName=?", mGroupName);
+ if (entity == null) {
+ entity = new DownloadGroupEntity();
+ entity.setGroupName(mGroupName);
+ entity.setUrls(mUrls);
+ entity.insert();
+ }
+ return entity;
+ }
+
+ /**
+ * 设置任务组别名
+ */
+ public DownloadGroupTarget setGroupAlias(String alias) {
+ if (TextUtils.isEmpty(alias)) return this;
+ mEntity.setAlias(alias);
+ mEntity.update();
+ return this;
+ }
+
+ /**
+ * 如果你是使用{@link DownloadReceiver#load(DownloadGroupEntity)}进行下载操作,那么你需要设置任务组的下载地址
+ */
+ public DownloadGroupTarget setGroupUrl(List urls) {
+ CheckUtil.checkDownloadUrls(urls);
+ mUrls.clear();
+ mUrls.addAll(urls);
+ mEntity.setGroupName(CommonUtil.getMd5Code(urls));
+ mEntity.update();
+ return this;
+ }
+
+ /**
+ * 设置任务组的文件夹路径,在Aria中,任务组的所有子任务都会下载到以任务组组名的文件夹中。
+ * 如:groupDirPath = "/mnt/sdcard/download/group_test"
+ *
+ * {@code
+ * + mnt
+ * + sdcard
+ * + download
+ * + group_test
+ * - task1.apk
+ * - task2.apk
+ * - task3.apk
+ * ....
+ *
+ * }
+ *
+ *
+ * @param groupDirPath 任务组保存文件夹路径
+ */
+ public DownloadGroupTarget setDownloadDirPath(String groupDirPath) {
+ if (TextUtils.isEmpty(groupDirPath)) {
+ throw new NullPointerException("任务组文件夹保存路径不能为null");
+ }
+
+ isSetDirPathed = true;
+ if (mEntity.getDirPath().equals(groupDirPath)) return this;
+
+ File file = new File(groupDirPath);
+ if (file.exists() && file.isFile()) {
+ throw new IllegalArgumentException("路径不能为文件");
+ }
+ if (!file.exists()) {
+ file.mkdirs();
+ }
+
+ mEntity.setDirPath(groupDirPath);
+ if (!TextUtils.isEmpty(mEntity.getDirPath())) {
+ reChangeDirPath(groupDirPath);
+ } else {
+ mEntity.setSubTasks(createSubTask());
+ }
+ mEntity.update();
+ return this;
+ }
+
+ /**
+ * 改变任务组文件夹路径,修改文件夹路径会将子任务所有路径更换
+ *
+ * @param newDirPath 新的文件夹路径
+ */
+ private void reChangeDirPath(String newDirPath) {
+ List subTask = mEntity.getSubTask();
+ if (subTask != null && !subTask.isEmpty()) {
+ for (DownloadEntity entity : subTask) {
+ String oldPath = entity.getDownloadPath();
+ String newPath = newDirPath + "/" + entity.getFileName();
+ File file = new File(oldPath);
+ file.renameTo(new File(newPath));
+ DbEntity.exeSql("UPDATE DownloadEntity SET downloadPath='"
+ + newPath
+ + "' WHERE downloadPath='"
+ + oldPath
+ + "'");
+ DbEntity.exeSql(
+ "UPDATE DownloadTaskEntity SET key='" + newPath + "' WHERE key='" + oldPath + "'");
+ }
+ } else {
+ mEntity.setSubTasks(createSubTask());
+ }
+ }
+
+ /**
+ * 设置子任务文件名,该方法必须在{@link #setDownloadDirPath(String)}之后调用,否则不生效
+ */
+ public DownloadGroupTarget setSubTaskFileName(List subTaskFileName) {
+ if (subTaskFileName == null || subTaskFileName.isEmpty()) return this;
+ mSubTaskFileName.addAll(subTaskFileName);
+ if (mUrls.size() != subTaskFileName.size()) {
+ throw new IllegalArgumentException("下载链接数必须要和保存路径的数量一致");
+ }
+ if (isSetDirPathed) {
+ List entities = mEntity.getSubTask();
+ int i = 0;
+ for (DownloadEntity entity : entities) {
+ String newName = mSubTaskFileName.get(i);
+ updateSubFileName(entity, newName);
+ i++;
+ }
+ }
+ return this;
+ }
+
+ /**
+ * 更新子任务文件名
+ */
+ private void updateSubFileName(DownloadEntity entity, String newName) {
+ if (!newName.equals(entity.getFileName())) {
+ String oldPath = mEntity.getDirPath() + "/" + entity.getFileName();
+ String newPath = mEntity.getDirPath() + "/" + newName;
+ File file = new File(oldPath);
+ if (file.exists()) {
+ file.renameTo(new File(newPath));
+ }
+ DbEntity.exeSql(
+ "UPDATE DownloadTaskEntity SET key='" + newPath + "' WHERE key='" + oldPath + "'");
+ entity.setDownloadPath(newPath);
+ entity.setFileName(newName);
+ entity.update();
+ }
+ }
+
+ /**
+ * 创建子任务
+ */
+ private List createSubTask() {
+ List list = new ArrayList<>();
+ for (int i = 0, len = mUrls.size(); i < len; i++) {
+ DownloadEntity entity = new DownloadEntity();
+ entity.setDownloadUrl(mUrls.get(i));
+ String fileName = mSubTaskFileName.isEmpty() ? createFileName(entity.getDownloadUrl())
+ : mSubTaskFileName.get(i);
+ entity.setDownloadPath(mEntity.getDirPath() + "/" + fileName);
+ entity.setGroupName(mGroupName);
+ entity.setGroupChild(true);
+ entity.setFileName(fileName);
+ entity.insert();
+ list.add(entity);
+ }
+ return list;
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java
new file mode 100644
index 00000000..1a375bba
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java
@@ -0,0 +1,98 @@
+/*
+ * 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.download;
+
+import android.os.Handler;
+import com.arialyy.aria.core.AriaManager;
+import com.arialyy.aria.core.download.downloader.DownloadGroupUtil;
+import com.arialyy.aria.core.download.downloader.IDownloadUtil;
+import com.arialyy.aria.core.inf.AbsGroupTask;
+import com.arialyy.aria.core.scheduler.ISchedulers;
+import com.arialyy.aria.util.CheckUtil;
+
+/**
+ * Created by AriaL on 2017/6/27.
+ * 任务组任务
+ */
+public class DownloadGroupTask extends AbsGroupTask {
+ private final String TAG = "DownloadGroupTask";
+ private DListener mListener;
+ private IDownloadUtil mUtil;
+
+ private DownloadGroupTask(DownloadGroupTaskEntity taskEntity, Handler outHandler) {
+ mTaskEntity = taskEntity;
+ mEntity = taskEntity.getEntity();
+ mOutHandler = outHandler;
+ mContext = AriaManager.APP;
+ mListener = new DListener<>(this, mOutHandler);
+ mUtil = new DownloadGroupUtil(mListener, mTaskEntity);
+ }
+
+ @Override public boolean isRunning() {
+ return mUtil.isDownloading();
+ }
+
+ @Override public void start() {
+ mUtil.startDownload();
+ }
+
+ @Override public void stop() {
+ if (!mUtil.isDownloading()) {
+ if (mOutHandler != null) {
+ mOutHandler.obtainMessage(ISchedulers.STOP, this).sendToTarget();
+ }
+ }
+ mUtil.stopDownload();
+ }
+
+ @Override public void cancel() {
+ if (!mUtil.isDownloading()) {
+ if (mOutHandler != null) {
+ mOutHandler.obtainMessage(ISchedulers.CANCEL, this).sendToTarget();
+ }
+ }
+ mUtil.cancelDownload();
+ }
+
+ public static class Builder {
+ DownloadGroupTaskEntity taskEntity;
+ Handler outHandler;
+ String targetName;
+
+ public Builder(String targetName, DownloadGroupTaskEntity taskEntity) {
+ CheckUtil.checkTaskEntity(taskEntity);
+ this.targetName = targetName;
+ this.taskEntity = taskEntity;
+ }
+
+ /**
+ * 设置自定义Handler处理下载状态时间
+ *
+ * @param schedulers {@link ISchedulers}
+ */
+ public DownloadGroupTask.Builder setOutHandler(ISchedulers schedulers) {
+ this.outHandler = new Handler(schedulers);
+ return this;
+ }
+
+ public DownloadGroupTask build() {
+ DownloadGroupTask task = new DownloadGroupTask(taskEntity, outHandler);
+ task.setTargetName(targetName);
+ taskEntity.save();
+ return task;
+ }
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTaskEntity.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTaskEntity.java
new file mode 100644
index 00000000..4987a1d0
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTaskEntity.java
@@ -0,0 +1,31 @@
+/*
+ * 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.download;
+
+import com.arialyy.aria.core.inf.AbsTaskEntity;
+import com.arialyy.aria.orm.OneToOne;
+
+/**
+ * Created by AriaL on 2017/7/1.
+ */
+public class DownloadGroupTaskEntity extends AbsTaskEntity {
+
+ @OneToOne(table = DownloadGroupEntity.class, key = "groupName") public DownloadGroupEntity entity;
+
+ @Override public DownloadGroupEntity getEntity() {
+ return entity;
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java
index 8f29f02f..ff289bd7 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java
@@ -17,12 +17,14 @@ package com.arialyy.aria.core.download;
import android.support.annotation.NonNull;
import com.arialyy.aria.core.AriaManager;
-import com.arialyy.aria.core.inf.ICmd;
+import com.arialyy.aria.core.inf.AbsEntity;
+import com.arialyy.aria.core.inf.AbsReceiver;
import com.arialyy.aria.core.inf.IReceiver;
-import com.arialyy.aria.core.command.CmdFactory;
-import com.arialyy.aria.core.command.AbsCmd;
+import com.arialyy.aria.core.command.normal.NormalCmdFactory;
+import com.arialyy.aria.core.scheduler.DownloadGroupSchedulers;
import com.arialyy.aria.core.scheduler.DownloadSchedulers;
import com.arialyy.aria.core.scheduler.ISchedulerListener;
+import com.arialyy.aria.core.upload.ProxyHelper;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.CheckUtil;
import com.arialyy.aria.util.CommonUtil;
@@ -34,10 +36,8 @@ import java.util.Set;
* Created by lyy on 2016/12/5.
* 下载功能接收器
*/
-public class DownloadReceiver implements IReceiver {
- private static final String TAG = "DownloadReceiver";
- public String targetName;
- public Object obj;
+public class DownloadReceiver extends AbsReceiver {
+ private final String TAG = "DownloadReceiver";
public ISchedulerListener listener;
/**
@@ -51,24 +51,67 @@ public class DownloadReceiver implements IReceiver {
}
/**
- * {@link #load(String)},请使用该方法
+ * 使用下载实体执行下载操作
*/
- @Deprecated public DownloadTarget load(DownloadEntity entity) {
+ public DownloadTarget load(DownloadEntity entity) {
return new DownloadTarget(entity, targetName);
}
/**
- * 读取下载链接
+ * 加载下载地址
*/
public DownloadTarget load(@NonNull String downloadUrl) {
CheckUtil.checkDownloadUrl(downloadUrl);
- DownloadEntity entity =
- DownloadEntity.findData(DownloadEntity.class, "downloadUrl=?", downloadUrl);
- if (entity == null) {
- entity = new DownloadEntity();
+ return new DownloadTarget(downloadUrl, targetName);
+ }
+
+ /**
+ * 加载下载地址,如果任务组的中的下载地址改变了,则任务从新的一个任务组
+ */
+ public DownloadGroupTarget load(List urls) {
+ CheckUtil.checkDownloadUrls(urls);
+ return new DownloadGroupTarget(urls, targetName);
+ }
+
+ /**
+ * 使用任务组实体执行任务组的实体执行任务组的下载操作
+ *
+ * @param groupEntity 如果加载的任务实体没有子项的下载地址,
+ * 那么你需要使用{@link DownloadGroupTarget#setGroupUrl(List)}设置子项的下载地址
+ */
+ public DownloadGroupTarget load(DownloadGroupEntity groupEntity) {
+ return new DownloadGroupTarget(groupEntity, targetName);
+ }
+
+ /**
+ * 将当前类注册到Aria
+ */
+ public DownloadReceiver register() {
+ String className = obj.getClass().getName();
+ Set dCounter = ProxyHelper.getInstance().downloadCounter;
+ Set dgCounter = ProxyHelper.getInstance().downloadGroupCounter;
+ if (dCounter != null && dCounter.contains(className)) {
+ DownloadSchedulers.getInstance().register(obj);
+ }
+ if (dgCounter != null && dgCounter.contains(className)) {
+ DownloadGroupSchedulers.getInstance().register(obj);
+ }
+ return this;
+ }
+
+ /**
+ * 取消注册
+ */
+ @Override public void unRegister() {
+ String className = obj.getClass().getName();
+ Set dCounter = ProxyHelper.getInstance().downloadCounter;
+ Set dgCounter = ProxyHelper.getInstance().downloadGroupCounter;
+ if (dCounter != null && dCounter.contains(className)) {
+ DownloadSchedulers.getInstance().unRegister(obj);
+ }
+ if (dgCounter != null && dgCounter.contains(className)) {
+ DownloadGroupSchedulers.getInstance().unRegister(obj);
}
- entity.setDownloadUrl(downloadUrl);
- return new DownloadTarget(entity, targetName);
}
/**
@@ -83,21 +126,6 @@ public class DownloadReceiver implements IReceiver {
return this;
}
- /**
- * 将当前类注册到Aria
- */
- public DownloadReceiver register() {
- DownloadSchedulers.getInstance().register(obj);
- return this;
- }
-
- /**
- * 取消注册
- */
- @Override public void unRegister() {
- DownloadSchedulers.getInstance().unRegister(obj);
- }
-
/**
* 移除回调
*
@@ -119,27 +147,74 @@ public class DownloadReceiver implements IReceiver {
*/
public DownloadEntity getDownloadEntity(String downloadUrl) {
CheckUtil.checkDownloadUrl(downloadUrl);
- return DownloadEntity.findData(DownloadEntity.class, "downloadUrl=?", downloadUrl);
+ return DbEntity.findFirst(DownloadEntity.class, "downloadUrl=? and isGroupChild='false'",
+ downloadUrl);
+ }
+
+ /**
+ * 通过下载链接获取保存在数据库的下载任务实体
+ */
+ public DownloadTaskEntity getDownloadTask(String downloadUrl) {
+ CheckUtil.checkDownloadUrl(downloadUrl);
+ return DbEntity.findFirst(DownloadTaskEntity.class, "groupName=? and isGroupTask='false'",
+ downloadUrl);
+ }
+
+ /**
+ * 通过下载链接获取保存在数据库的下载任务组实体
+ */
+ public DownloadGroupTaskEntity getDownloadGroupTask(List urls) {
+ CheckUtil.checkDownloadUrls(urls);
+ String hashCode = CommonUtil.getMd5Code(urls);
+ return DbEntity.findFirst(DownloadGroupTaskEntity.class, "key=?", hashCode);
}
/**
* 下载任务是否存在
*/
@Override public boolean taskExists(String downloadUrl) {
- return DownloadEntity.findData(DownloadEntity.class, "downloadUrl=?", downloadUrl) != null;
+ return DownloadEntity.findFirst(DownloadEntity.class, "downloadUrl=?", downloadUrl) != null;
}
- @Override public List getTaskList() {
- return DownloadEntity.findAllData(DownloadEntity.class);
+ /**
+ * 获取普通下载任务列表
+ */
+ @Override public List getSimpleTaskList() {
+ return DownloadEntity.findDatas(DownloadEntity.class, "isGroupChild=? and downloadPath!=''",
+ "false");
+ }
+
+ /**
+ * 获取任务组列表
+ */
+ public List getGroupTaskList() {
+ return DownloadEntity.findAllData(DownloadGroupEntity.class);
+ }
+
+ /**
+ * 获取普通任务和任务组的任务列表
+ */
+ public List getTotleTaskList() {
+ List list = new ArrayList<>();
+ List simpleTask = getSimpleTaskList();
+ List groupTask = getGroupTaskList();
+ if (simpleTask != null && !simpleTask.isEmpty()) {
+ list.addAll(simpleTask);
+ }
+ if (groupTask != null && !groupTask.isEmpty()) {
+ list.addAll(groupTask);
+ }
+ return list;
}
/**
* 停止所有正在下载的任务,并清空等待队列。
*/
@Override public void stopAllTask() {
- final AriaManager ariaManager = AriaManager.getInstance(AriaManager.APP);
- ariaManager.setCmd(CmdFactory.getInstance()
- .createCmd(targetName, new DownloadTaskEntity(), CmdFactory.TASK_STOP_ALL)).exe();
+ AriaManager.getInstance(AriaManager.APP)
+ .setCmd(NormalCmdFactory.getInstance()
+ .createCmd(targetName, new DownloadTaskEntity(), NormalCmdFactory.TASK_STOP_ALL))
+ .exe();
}
/**
@@ -148,23 +223,23 @@ public class DownloadReceiver implements IReceiver {
* 2.如果队列执行队列已经满了,则将所有任务添加到等待队列中
*/
public void resumeAllTask() {
- final AriaManager ariaManager = AriaManager.getInstance(AriaManager.APP);
- ariaManager.setCmd(CmdFactory.getInstance()
- .createCmd(targetName, new DownloadTaskEntity(), CmdFactory.TASK_RESUME_ALL)).exe();
+ AriaManager.getInstance(AriaManager.APP)
+ .setCmd(NormalCmdFactory.getInstance()
+ .createCmd(targetName, new DownloadTaskEntity(), NormalCmdFactory.TASK_RESUME_ALL))
+ .exe();
}
/**
* 删除所有任务
+ *
+ * @param removeFile {@code true} 删除已经下载完成的任务,不仅删除下载记录,还会删除已经下载完成的文件,{@code false}
+ * 如果文件已经下载完成,只删除下载记录
*/
- @Override public void removeAllTask() {
+ @Override public void removeAllTask(boolean removeFile) {
final AriaManager ariaManager = AriaManager.getInstance(AriaManager.APP);
- List allEntity = DbEntity.findAllData(DownloadEntity.class);
- List cancelCmds = new ArrayList<>();
- for (DownloadEntity entity : allEntity) {
- cancelCmds.add(
- CommonUtil.createCmd(targetName, new DownloadTaskEntity(entity), CmdFactory.TASK_CANCEL));
- }
- ariaManager.setCmds(cancelCmds).exe();
+ ariaManager.setCmd(CommonUtil.createCmd(targetName, new DownloadTaskEntity(),
+ NormalCmdFactory.TASK_CANCEL_ALL)).exe();
+
Set keys = ariaManager.getReceiver().keySet();
for (String key : keys) {
IReceiver receiver = ariaManager.getReceiver().get(key);
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java
index 05e6c2d9..c77e853c 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java
@@ -17,31 +17,60 @@ package com.arialyy.aria.core.download;
import android.support.annotation.NonNull;
import android.text.TextUtils;
-import android.util.Log;
-import com.arialyy.aria.core.RequestEnum;
-import com.arialyy.aria.core.inf.AbsTarget;
+import com.arialyy.aria.core.inf.AbsNormalTarget;
+import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.queue.DownloadTaskQueue;
+import com.arialyy.aria.orm.DbEntity;
import java.io.File;
-import java.util.Map;
/**
* Created by lyy on 2016/12/5.
* https://github.com/AriaLyy/Aria
*/
-public class DownloadTarget extends AbsTarget {
+public class DownloadTarget
+ extends AbsNormalTarget {
DownloadTarget(DownloadEntity entity, String targetName) {
- this.entity = entity;
- this.targetName = targetName;
- taskEntity = new DownloadTaskEntity(entity);
+ this(entity.getDownloadUrl(), targetName);
}
- @Override public void pause() {
- super.pause();
+ DownloadTarget(String url, String targetName) {
+ mTargetName = targetName;
+ DownloadEntity entity = getEntity(url);
+ mTaskEntity = DbEntity.findFirst(DownloadTaskEntity.class, "key=? and isGroupTask='false'",
+ entity.getDownloadPath());
+ if (mTaskEntity == null) {
+ mTaskEntity = new DownloadTaskEntity();
+ mTaskEntity.key = entity.getDownloadPath();
+ mTaskEntity.entity = entity;
+ mTaskEntity.save();
+ }
+ if (mTaskEntity.entity == null) {
+ mTaskEntity.entity = entity;
+ }
+ mEntity = entity;
}
- @Override public void resume() {
- super.resume();
+ /**
+ * 如果任务存在,但是下载实体不存在,则通过下载地址获取下载实体
+ *
+ * @param downloadUrl 下载地址
+ */
+ private DownloadEntity getEntity(String downloadUrl) {
+ DownloadEntity entity =
+ DownloadEntity.findFirst(DownloadEntity.class, "downloadUrl=? and isGroupChild='false'",
+ downloadUrl);
+ if (entity == null) {
+ entity = new DownloadEntity();
+ entity.setDownloadUrl(downloadUrl);
+ entity.setGroupChild(false);
+ entity.save();
+ }
+ File file = new File(entity.getDownloadPath());
+ if (!file.exists()) {
+ entity.setState(IEntity.STATE_WAIT);
+ }
+ return entity;
}
/**
@@ -65,53 +94,11 @@ public class DownloadTarget extends AbsTarget headers) {
- super._addHeaders(headers);
- return this;
- }
-
/**
* 下载任务是否存在
*/
@Override public boolean taskExists() {
- return DownloadTaskQueue.getInstance().getTask(entity.getDownloadUrl()) != null;
- }
-
- /**
- * 设置请求类型
- *
- * @param requestEnum {@link RequestEnum}
- */
- public DownloadTarget setRequestMode(RequestEnum requestEnum) {
- super._setRequestMode(requestEnum);
- return this;
+ return DownloadTaskQueue.getInstance().getTask(mEntity.getDownloadUrl()) != null;
}
/**
@@ -122,8 +109,11 @@ public class DownloadTarget extends AbsTarget {
+public class DownloadTask extends AbsNormalTask {
public static final String TAG = "DownloadTask";
- private IDownloadListener mListener;
- private Handler mOutHandler;
- private IDownloadUtil mUtil;
- private boolean isWait = false;
+ private DListener mListener;
+ private SimpleDownloadUtil mUtil;
private DownloadTask(DownloadTaskEntity taskEntity, Handler outHandler) {
- mEntity = taskEntity.downloadEntity;
+ mEntity = taskEntity.getEntity();
mOutHandler = outHandler;
mContext = AriaManager.APP;
- mListener = new DListener(mContext, this, mOutHandler);
- mUtil = new DownloadUtil(mContext, taskEntity, mListener);
+ mListener = new DListener<>(this, mOutHandler);
+ mUtil = new SimpleDownloadUtil(taskEntity, mListener);
}
/**
@@ -98,7 +90,6 @@ public class DownloadTask extends AbsTask {
* 暂停任务,并让任务处于等待状态
*/
@Override public void stopAndWait() {
- super.stopAndWait();
stop(true);
}
@@ -115,13 +106,10 @@ public class DownloadTask extends AbsTask {
* 开始下载
*/
@Override public void start() {
- isWait = false;
+ mListener.isWait = false;
if (mUtil.isDownloading()) {
Log.d(TAG, "任务正在下载");
} else {
- if (mListener == null || isWait) {
- mListener = new DListener(mContext, this, mOutHandler);
- }
mUtil.startDownload();
}
}
@@ -134,20 +122,15 @@ public class DownloadTask extends AbsTask {
}
private void stop(boolean isWait) {
- this.isWait = isWait;
+ mListener.isWait = isWait;
if (mUtil.isDownloading()) {
mUtil.stopDownload();
} else {
mEntity.setState(isWait ? IEntity.STATE_WAIT : IEntity.STATE_STOP);
- mEntity.save();
+ mEntity.update();
if (mOutHandler != null) {
- mOutHandler.obtainMessage(DownloadSchedulers.STOP, this).sendToTarget();
+ mOutHandler.obtainMessage(ISchedulers.STOP, this).sendToTarget();
}
- // 发送停止下载的广播
- Intent intent = CommonUtil.createIntent(mContext.getPackageName(), Aria.ACTION_STOP);
- intent.putExtra(Aria.CURRENT_LOCATION, mEntity.getCurrentProgress());
- intent.putExtra(Aria.DOWNLOAD_ENTITY, mEntity);
- mContext.sendBroadcast(intent);
}
}
@@ -155,20 +138,13 @@ public class DownloadTask extends AbsTask {
* 取消下载
*/
@Override public void cancel() {
- if (!mEntity.isDownloadComplete()) {
+ if (!mEntity.isComplete()) {
if (!mUtil.isDownloading()) {
if (mOutHandler != null) {
- mOutHandler.obtainMessage(DownloadSchedulers.CANCEL, this).sendToTarget();
+ mOutHandler.obtainMessage(ISchedulers.CANCEL, this).sendToTarget();
}
- //发送取消下载的广播
- Intent intent = CommonUtil.createIntent(mContext.getPackageName(), Aria.ACTION_CANCEL);
- intent.putExtra(Aria.DOWNLOAD_ENTITY, mEntity);
- mContext.sendBroadcast(intent);
}
mUtil.cancelDownload();
- mUtil.delConfigFile();
- mUtil.delTempFile();
- mEntity.deleteData();
}
}
@@ -178,7 +154,6 @@ public class DownloadTask extends AbsTask {
String targetName;
public Builder(String targetName, DownloadTaskEntity taskEntity) {
- CheckUtil.checkTaskEntity(taskEntity);
this.targetName = targetName;
this.taskEntity = taskEntity;
}
@@ -196,162 +171,9 @@ public class DownloadTask extends AbsTask {
public DownloadTask build() {
DownloadTask task = new DownloadTask(taskEntity, outHandler);
task.setTargetName(targetName);
- taskEntity.downloadEntity.save();
+ taskEntity.getEntity().save();
+ taskEntity.save();
return task;
}
}
-
- /**
- * 下载监听类
- */
- private static class DListener extends DownloadListener {
- WeakReference outHandler;
- WeakReference wTask;
- Context context;
- Intent sendIntent;
- long lastLen = 0; //上一次发送长度
- long lastTime = 0;
- long INTERVAL_TIME = 1000; //1m更新周期
- boolean isFirst = true;
- DownloadEntity downloadEntity;
- DownloadTask task;
- boolean isOpenBroadCast = false;
- boolean isConvertSpeed = false;
-
- DListener(Context context, DownloadTask task, Handler outHandler) {
- this.context = context;
- this.outHandler = new WeakReference<>(outHandler);
- this.wTask = new WeakReference<>(task);
- this.task = wTask.get();
- this.downloadEntity = this.task.getDownloadEntity();
- sendIntent = CommonUtil.createIntent(context.getPackageName(), Aria.ACTION_RUNNING);
- sendIntent.putExtra(Aria.DOWNLOAD_ENTITY, downloadEntity);
- final AriaManager manager = AriaManager.getInstance(context);
- isOpenBroadCast = manager.getDownloadConfig().isOpenBreadCast();
- isConvertSpeed = manager.getDownloadConfig().isConvertSpeed();
- }
-
- @Override public void supportBreakpoint(boolean support) {
- super.supportBreakpoint(support);
- if (!support) {
- sendInState2Target(ISchedulers.SUPPORT_BREAK_POINT);
- sendIntent(Aria.ACTION_SUPPORT_BREAK_POINT, -1);
- }
- }
-
- @Override public void onPre() {
- super.onPre();
- downloadEntity.setState(IEntity.STATE_PRE);
- sendInState2Target(ISchedulers.PRE);
- sendIntent(Aria.ACTION_PRE, -1);
- }
-
- @Override public void onPostPre(long fileSize) {
- super.onPostPre(fileSize);
- downloadEntity.setFileSize(fileSize);
- downloadEntity.setState(IEntity.STATE_POST_PRE);
- sendInState2Target(ISchedulers.POST_PRE);
- sendIntent(Aria.ACTION_POST_PRE, -1);
- }
-
- @Override public void onResume(long resumeLocation) {
- super.onResume(resumeLocation);
- downloadEntity.setState(IEntity.STATE_RUNNING);
- sendInState2Target(ISchedulers.RESUME);
- sendIntent(Aria.ACTION_RESUME, resumeLocation);
- }
-
- @Override public void onStart(long startLocation) {
- super.onStart(startLocation);
- downloadEntity.setState(IEntity.STATE_RUNNING);
- sendInState2Target(ISchedulers.START);
- sendIntent(Aria.ACTION_START, startLocation);
- }
-
- @Override public void onProgress(long currentLocation) {
- super.onProgress(currentLocation);
- if (System.currentTimeMillis() - lastTime > INTERVAL_TIME) {
- long speed = currentLocation - lastLen;
- sendIntent.putExtra(Aria.CURRENT_LOCATION, currentLocation);
- sendIntent.putExtra(Aria.CURRENT_SPEED, speed);
- lastTime = System.currentTimeMillis();
- if (isFirst) {
- speed = 0;
- isFirst = false;
- }
- handleSpeed(speed);
- downloadEntity.setCurrentProgress(currentLocation);
- lastLen = currentLocation;
- sendInState2Target(ISchedulers.RUNNING);
- context.sendBroadcast(sendIntent);
- }
- }
-
- @Override public void onStop(long stopLocation) {
- super.onStop(stopLocation);
- downloadEntity.setState(task.isWait ? IEntity.STATE_WAIT : IEntity.STATE_STOP);
- handleSpeed(0);
- sendInState2Target(ISchedulers.STOP);
- sendIntent(Aria.ACTION_STOP, stopLocation);
- }
-
- @Override public void onCancel() {
- super.onCancel();
- downloadEntity.setState(IEntity.STATE_CANCEL);
- handleSpeed(0);
- sendInState2Target(ISchedulers.CANCEL);
- sendIntent(Aria.ACTION_CANCEL, -1);
- downloadEntity.deleteData();
- }
-
- @Override public void onComplete() {
- super.onComplete();
- downloadEntity.setState(IEntity.STATE_COMPLETE);
- downloadEntity.setDownloadComplete(true);
- handleSpeed(0);
- sendInState2Target(ISchedulers.COMPLETE);
- sendIntent(Aria.ACTION_COMPLETE, downloadEntity.getFileSize());
- }
-
- @Override public void onFail() {
- super.onFail();
- downloadEntity.setFailNum(downloadEntity.getFailNum() + 1);
- downloadEntity.setState(IEntity.STATE_FAIL);
- handleSpeed(0);
- sendInState2Target(ISchedulers.FAIL);
- sendIntent(Aria.ACTION_FAIL, -1);
- }
-
- private void handleSpeed(long speed) {
- if (isConvertSpeed) {
- downloadEntity.setConvertSpeed(CommonUtil.formatFileSize(speed) + "/s");
- } else {
- downloadEntity.setSpeed(speed);
- }
- }
-
- /**
- * 将任务状态发送给下载器
- *
- * @param state {@link DownloadSchedulers#START}
- */
- private void sendInState2Target(int state) {
- if (outHandler.get() != null) {
- outHandler.get().obtainMessage(state, task).sendToTarget();
- }
- }
-
- private void sendIntent(String action, long location) {
- downloadEntity.setDownloadComplete(action.equals(Aria.ACTION_COMPLETE));
- downloadEntity.setCurrentProgress(location);
- downloadEntity.update();
- if (!isOpenBroadCast) return;
- Intent intent = CommonUtil.createIntent(context.getPackageName(), action);
- intent.putExtra(Aria.DOWNLOAD_ENTITY, downloadEntity);
- if (location != -1) {
- intent.putExtra(Aria.CURRENT_LOCATION, location);
- }
- context.sendBroadcast(intent);
- }
- }
}
\ No newline at end of file
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java
index 75f6a17b..f5b9dbc0 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java
@@ -16,22 +16,30 @@
package com.arialyy.aria.core.download;
import com.arialyy.aria.core.inf.AbsTaskEntity;
+import com.arialyy.aria.orm.OneToOne;
/**
* Created by lyy on 2017/1/23.
* 下载任务实体
*/
-public class DownloadTaskEntity extends AbsTaskEntity {
+public class DownloadTaskEntity extends AbsTaskEntity {
- public DownloadEntity downloadEntity;
+ @OneToOne(table = DownloadEntity.class, key = "downloadPath") public DownloadEntity entity;
- public DownloadTaskEntity(){}
+ /**
+ * 所属的任务组组名,如果不属于任务组,则为null
+ */
+ public String groupName = "";
- public DownloadTaskEntity(DownloadEntity downloadEntity) {
- this.downloadEntity = downloadEntity;
+ /**
+ * 该任务是否属于任务组
+ */
+ public boolean isGroupTask = false;
+
+ public DownloadTaskEntity() {
}
@Override public DownloadEntity getEntity() {
- return downloadEntity;
+ return entity;
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadUtil.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadUtil.java
deleted file mode 100644
index 2f08ba86..00000000
--- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadUtil.java
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * 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.download;
-
-import android.content.Context;
-import android.util.Log;
-import android.util.SparseArray;
-import com.arialyy.aria.core.AriaManager;
-import com.arialyy.aria.util.BufferedRandomAccessFile;
-import com.arialyy.aria.util.CheckUtil;
-import com.arialyy.aria.util.CommonUtil;
-import java.io.File;
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Properties;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-/**
- * Created by lyy on 2015/8/25.
- * 下载工具类
- */
-class DownloadUtil implements IDownloadUtil, Runnable {
- private static final String TAG = "DownloadUtil";
- /**
- * 线程数
- */
- private int THREAD_NUM;
- /**
- * 小于1m的文件不启用多线程
- */
- private static final long SUB_LEN = 1024 * 1024;
- //下载监听
- private IDownloadListener mListener;
- private int mConnectTimeOut = 0; //连接超时时间
- private boolean isNewTask = true;
- private boolean isSupportBreakpoint = true;
- private Context mContext;
- private DownloadEntity mDownloadEntity;
- private DownloadTaskEntity mDownloadTaskEntity;
- private ExecutorService mFixedThreadPool;
- private File mDownloadFile; //下载的文件
- private File mConfigFile;//下载信息配置文件
- private SparseArray mTask = new SparseArray<>();
- private DownloadStateConstance CONSTANCE;
-
- DownloadUtil(Context context, DownloadTaskEntity entity, IDownloadListener downloadListener) {
- mDownloadEntity = entity.downloadEntity;
- mContext = context.getApplicationContext();
- mDownloadTaskEntity = entity;
- mListener = downloadListener;
- // 线程下载数改变后,新的下载才会生效
- //mFixedThreadPool = Executors.newFixedThreadPool(Integer.MAX_VALUE);
- CONSTANCE = new DownloadStateConstance();
- init();
- }
-
- private void init() {
- mConnectTimeOut = AriaManager.getInstance(mContext).getDownloadConfig().getConnectTimeOut();
- mDownloadFile = new File(mDownloadTaskEntity.downloadEntity.getDownloadPath());
- //读取已完成的线程数
- mConfigFile = new File(mContext.getFilesDir().getPath()
- + AriaManager.DOWNLOAD_TEMP_DIR
- + mDownloadFile.getName()
- + ".properties");
- try {
- if (!mConfigFile.exists()) { //记录文件被删除,则重新下载
- isNewTask = true;
- CommonUtil.createFile(mConfigFile.getPath());
- } else {
- isNewTask = !mDownloadFile.exists();
- }
- } catch (Exception e) {
- e.printStackTrace();
- failDownload("下载失败,记录文件被删除");
- }
- }
-
- public IDownloadListener getListener() {
- return mListener;
- }
-
- /**
- * 获取当前下载位置
- */
- @Override public long getCurrentLocation() {
- return CONSTANCE.CURRENT_LOCATION;
- }
-
- @Override public boolean isDownloading() {
- return CONSTANCE.isDownloading;
- }
-
- public void setMaxSpeed(double maxSpeed) {
- for (int i = 0; i < THREAD_NUM; i++) {
- SingleThreadTask task = (SingleThreadTask) mTask.get(i);
- if (task != null) {
- task.setMaxSpeed(maxSpeed);
- }
- }
- }
-
- /**
- * 取消下载
- */
- @Override public void cancelDownload() {
- CONSTANCE.isCancel = true;
- CONSTANCE.isDownloading = false;
- if (mFixedThreadPool != null) {
- mFixedThreadPool.shutdown();
- }
- for (int i = 0; i < THREAD_NUM; i++) {
- SingleThreadTask task = (SingleThreadTask) mTask.get(i);
- if (task != null) {
- task.cancel();
- }
- }
- }
-
- /**
- * 停止下载
- */
- @Override public void stopDownload() {
- CONSTANCE.isStop = true;
- CONSTANCE.isDownloading = false;
- if (mFixedThreadPool != null) {
- mFixedThreadPool.shutdown();
- }
- for (int i = 0; i < THREAD_NUM; i++) {
- SingleThreadTask task = (SingleThreadTask) mTask.get(i);
- if (task != null) {
- task.stop();
- }
- }
- }
-
- /**
- * 删除下载记录文件
- */
- @Override public void delConfigFile() {
- if (mContext != null && mDownloadEntity != null) {
- File dFile = new File(mDownloadEntity.getDownloadPath());
- File config =
- new File(mContext.getFilesDir().getPath() + "/temp/" + dFile.getName() + ".properties");
- if (config.exists()) {
- config.delete();
- }
- }
- }
-
- /**
- * 删除temp文件
- */
- @Override public void delTempFile() {
- if (mContext != null && mDownloadEntity != null) {
- File dFile = new File(mDownloadEntity.getDownloadPath());
- if (dFile.exists()) {
- dFile.delete();
- }
- }
- }
-
- /**
- * 多线程断点续传下载文件,开始下载
- */
- @Override public void startDownload() {
- CONSTANCE.cleanState();
- mListener.onPre();
- new Thread(this).start();
- }
-
- @Override public void resumeDownload() {
- startDownload();
- }
-
- private void failDownload(String msg) {
- Log.e(TAG, msg);
- CONSTANCE.isDownloading = false;
- stopDownload();
- mListener.onFail();
- }
-
- @Override public void run() {
- try {
- URL url = new URL(mDownloadEntity.getDownloadUrl());
- HttpURLConnection conn = ConnectionHelp.handleConnection(url);
- conn = ConnectionHelp.setConnectParam(mDownloadTaskEntity, conn);
- conn.setRequestProperty("Range", "bytes=" + 0 + "-");
- conn.setConnectTimeout(mConnectTimeOut);
- conn.connect();
- handleConnect(conn);
- } catch (IOException e) {
- failDownload("下载失败【downloadUrl:"
- + mDownloadEntity.getDownloadUrl()
- + "】\n【filePath:"
- + mDownloadFile.getPath()
- + "】"
- + CommonUtil.getPrintException(e));
- }
- }
-
- /**
- * 处理状态吗
- */
- private void handleConnect(HttpURLConnection conn) throws IOException {
- int len = conn.getContentLength();
- //if (len < 0) { //网络被劫持时会出现这个问题
- // failDownload("下载失败,网络被劫持");
- // return;
- //}
- int code = conn.getResponseCode();
- //https://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81
- //206支持断点
- if (code == HttpURLConnection.HTTP_PARTIAL) {
- if (!checkLen(len)) return;
- isSupportBreakpoint = true;
- mListener.supportBreakpoint(true);
- handleBreakpoint(conn);
- } else if (code == HttpURLConnection.HTTP_OK) {
- //在conn.setRequestProperty("Range", "bytes=" + 0 + "-");下,200为不支持断点状态
- if (!checkLen(len)) return;
- isSupportBreakpoint = false;
- mListener.supportBreakpoint(false);
- Log.w(TAG, "该下载链接不支持断点下载");
- handleBreakpoint(conn);
- } else if (code == HttpURLConnection.HTTP_NOT_FOUND) {
- Log.w(TAG, "任务【" + mDownloadEntity.getDownloadUrl() + "】下载失败,错误码:404");
- mListener.onCancel();
- } else if (code == HttpURLConnection.HTTP_MOVED_TEMP
- || code == HttpURLConnection.HTTP_MOVED_PERM
- || code == HttpURLConnection.HTTP_SEE_OTHER) {
- handle302Turn(conn);
- } else {
- failDownload("任务【" + mDownloadEntity.getDownloadUrl() + "】下载失败,错误码:" + code);
- }
- }
-
- /**
- * 检查长度是否合法
- *
- * @param len 从服务器获取的文件长度
- * @return true, 合法
- */
- private boolean checkLen(long len) {
- if (len < 0) {
- failDownload("任务【" + mDownloadEntity.getDownloadUrl() + "】下载失败,文件长度小于0");
- return false;
- }
- return true;
- }
-
- /**
- * 处理30x跳转
- */
- private void handle302Turn(HttpURLConnection conn) throws IOException {
- String newUrl = conn.getHeaderField(mDownloadTaskEntity.redirectUrlKey);
- Log.d(TAG, "30x跳转,新url为【" + newUrl + "】");
- mDownloadEntity.setRedirect(true);
- mDownloadEntity.setRedirectUrl(newUrl);
- mDownloadEntity.update();
- String cookies = conn.getHeaderField("Set-Cookie");
- conn = (HttpURLConnection) new URL(newUrl).openConnection();
- conn = ConnectionHelp.setConnectParam(mDownloadTaskEntity, conn);
- conn.setRequestProperty("Cookie", cookies);
- conn.setRequestProperty("Range", "bytes=" + 0 + "-");
- conn.setConnectTimeout(mConnectTimeOut);
- conn.connect();
-
- handleConnect(conn);
- }
-
- /**
- * 处理断点
- */
- private void handleBreakpoint(HttpURLConnection conn) throws IOException {
- //不支持断点只能单线程下载
- if (!isSupportBreakpoint) {
- handleNoSupportBreakpointDownload(conn);
- return;
- }
- int fileLength = conn.getContentLength();
- Properties pro = createConfigFile(fileLength);
- int blockSize = fileLength / THREAD_NUM;
- int[] recordL = new int[THREAD_NUM];
- int rl = 0;
- for (int i = 0; i < THREAD_NUM; i++) {
- recordL[i] = -1;
- }
- for (int i = 0; i < THREAD_NUM; i++) {
- long startL = i * blockSize, endL = (i + 1) * blockSize;
- Object state = pro.getProperty(mDownloadFile.getName() + "_state_" + i);
- if (state != null && Integer.parseInt(state + "") == 1) { //该线程已经完成
- if (resumeRecordLocation(i, startL, endL)) return;
- continue;
- }
- //分配下载位置
- Object record = pro.getProperty(mDownloadFile.getName() + "_record_" + i);
- //如果有记录,则恢复下载
- if (!isNewTask && record != null && Long.parseLong(record + "") > 0) {
- Long r = Long.parseLong(record + "");
- CONSTANCE.CURRENT_LOCATION += r - startL;
- Log.d(TAG, "任务【" + mDownloadEntity.getFileName() + "】线程__" + i + "__恢复下载");
- mListener.onChildResume(r);
- startL = r;
- recordL[rl] = i;
- rl++;
- } else {
- handleNewTask(fileLength);
- }
- if (isNewTask) {
- recordL[rl] = i;
- rl++;
- }
- if (i == (THREAD_NUM - 1)) {
- //最后一个线程的结束位置即为文件的总长度
- endL = fileLength;
- }
- addSingleTask(i, startL, endL, fileLength);
- }
- startSingleTask(recordL);
- }
-
- /**
- * 处理不支持断点的下载
- */
- private void handleNoSupportBreakpointDownload(HttpURLConnection conn) {
- ConfigEntity entity = new ConfigEntity();
- long len = conn.getContentLength();
- entity.FILE_SIZE = len;
- entity.DOWNLOAD_URL = mDownloadEntity.isRedirect() ? mDownloadEntity.getRedirectUrl()
- : mDownloadEntity.getDownloadUrl();
- entity.TEMP_FILE = mDownloadFile;
- entity.THREAD_ID = 0;
- entity.START_LOCATION = 0;
- entity.END_LOCATION = entity.FILE_SIZE;
- entity.CONFIG_FILE_PATH = mConfigFile.getPath();
- entity.isSupportBreakpoint = isSupportBreakpoint;
- entity.DOWNLOAD_TASK_ENTITY = mDownloadTaskEntity;
- THREAD_NUM = 1;
- CONSTANCE.THREAD_NUM = THREAD_NUM;
- SingleThreadTask task = new SingleThreadTask(CONSTANCE, mListener, entity);
- mTask.put(0, task);
- mFixedThreadPool.execute(task);
- mListener.onPostPre(len);
- mListener.onStart(0);
- }
-
- /**
- * 创建配置文件
- */
- private Properties createConfigFile(long fileLength) throws IOException {
- Properties pro = null;
- //必须建一个文件
- CommonUtil.createFile(mDownloadFile.getPath());
- BufferedRandomAccessFile file =
- new BufferedRandomAccessFile(new File(mDownloadFile.getPath()), "rwd", 8192);
- //设置文件长度
- file.setLength(fileLength);
- mListener.onPostPre(fileLength);
- //分配每条线程的下载区间
- pro = CommonUtil.loadConfig(mConfigFile);
- if (pro.isEmpty()) {
- handleNewTask(fileLength);
- } else {
- Set