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 79%
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,43 +51,51 @@ 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();
- }
- entity.setDownloadUrl(downloadUrl);
- return new DownloadTarget(entity, targetName);
+ return new DownloadTarget(downloadUrl, targetName);
}
/**
- * 添加调度器回调
+ * 加载下载地址,如果任务组的中的下载地址改变了,则任务从新的一个任务组
+ */
+ public DownloadGroupTarget load(List urls) {
+ CheckUtil.checkDownloadUrls(urls);
+ return new DownloadGroupTarget(urls, targetName);
+ }
+
+ /**
+ * 使用任务组实体执行任务组的实体执行任务组的下载操作
*
- * @see #register()
+ * @param groupEntity 如果加载的任务实体没有子项的下载地址,
+ * 那么你需要使用{@link DownloadGroupTarget#setGroupUrl(List)}设置子项的下载地址
*/
- @Deprecated public DownloadReceiver addSchedulerListener(
- ISchedulerListener listener) {
- this.listener = listener;
- DownloadSchedulers.getInstance().addSchedulerListener(targetName, listener);
- return this;
+ public DownloadGroupTarget load(DownloadGroupEntity groupEntity) {
+ return new DownloadGroupTarget(groupEntity, targetName);
}
/**
* 将当前类注册到Aria
*/
public DownloadReceiver register() {
- DownloadSchedulers.getInstance().register(obj);
+ 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;
}
@@ -95,7 +103,27 @@ public class DownloadReceiver implements IReceiver {
* 取消注册
*/
@Override public void unRegister() {
- DownloadSchedulers.getInstance().unRegister(obj);
+ 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);
+ }
+ }
+
+ /**
+ * 添加调度器回调
+ *
+ * @see #register()
+ */
+ @Deprecated public DownloadReceiver addSchedulerListener(
+ ISchedulerListener listener) {
+ this.listener = listener;
+ DownloadSchedulers.getInstance().addSchedulerListener(targetName, listener);
+ return this;
}
/**
@@ -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
+ * 才能生效
*/
- @Override public long getCurrentProgress() {
- return mEntity.getCurrentProgress();
+ @Override public long getSpeed() {
+ return mEntity.getSpeed();
}
/**
- * 获取单位转换后的进度
+ * @return 返回转换单位后的速度,需要你在配置文件中配置,转换完成后为:1b/s、1kb/s、1mb/s、1gb/s、1tb/s
+ *
+ * {@code
+ *
+ *
+ * ...
+ *
+ *
*
- * @return 如:已经下载3mb的大小,则返回{@code 3mb}
+ * 或在代码中设置
+ * Aria.get(this).getDownloadConfig().setConvertSpeed(true);
+ *
+ * }
+ *
+ * 才能生效
*/
- @Override public String getConvertCurrentProgress() {
- if (mEntity.getCurrentProgress() == 0) {
- return "0b";
- }
- return CommonUtil.formatFileSize(mEntity.getCurrentProgress());
+ @Override public String getConvertSpeed() {
+ return mEntity.getConvertSpeed();
}
@Override public ENTITY getEntity() {
return mEntity;
}
- /**
- * 删除任务记录,删除后,再次启动该任务的下载时,将重新下载
- */
- @Override public void removeRecord() {
- mEntity.deleteData();
- }
-
public String getTargetName() {
return mTargetName;
}
@@ -164,4 +165,8 @@ public abstract class AbsTask extends DbEntity {
+
+ /**
+ * Task实体对应的key
+ */
+ @Primary public String key = "";
-public abstract class AbsTaskEntity {
/**
* http 请求头
*/
@@ -35,9 +43,45 @@ public abstract class AbsTaskEntity {
public RequestEnum requestEnum = RequestEnum.GET;
/**
- * 重定向后,新url的key
+ * 从链接中含有的文件md5码信息所需要的key
+ */
+ public String md5Key = "Content-MD5";
+
+ /**
+ * 从链接中获取文件描述信息所需要的key
+ */
+ public String dispositionKey = "Content-Disposition";
+
+ /**
+ * 重定向后,从链接中获取新url所需要的key
*/
public String redirectUrlKey = "location";
- public abstract AbsEntity getEntity();
+ /**
+ * 从Disposition获取的文件名说需要的key
+ */
+ public String dispositionFileKey = "attachment;filename";
+
+ /**
+ * 重定向链接
+ */
+ public String redirectUrl = "";
+
+ /**
+ * {@code true} 删除任务数据库记录,并且删除已经下载完成的文件
+ * {@code false} 如果任务已经完成,只删除任务数据库记录
+ */
+ @Ignore public boolean removeFile = false;
+
+ /**
+ * 是否支持断点, {@code true} 为支持断点
+ */
+ public boolean isSupportBP = true;
+
+ /**
+ * 状态码
+ */
+ public int code;
+
+ public abstract ENTITY getEntity();
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/IEntity.java b/Aria/src/main/java/com/arialyy/aria/core/inf/IEntity.java
index 6b60f1bb..156a01ce 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/inf/IEntity.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/inf/IEntity.java
@@ -20,42 +20,41 @@ import com.arialyy.aria.orm.Ignore;
/**
* Created by lyy on 2017/2/23.
*/
-
public interface IEntity {
/**
* 其它状态
*/
- @Ignore public static final int STATE_OTHER = -1;
+ @Ignore int STATE_OTHER = -1;
/**
* 失败状态
*/
- @Ignore public static final int STATE_FAIL = 0;
+ @Ignore int STATE_FAIL = 0;
/**
* 完成状态
*/
- @Ignore public static final int STATE_COMPLETE = 1;
+ @Ignore int STATE_COMPLETE = 1;
/**
* 停止状态
*/
- @Ignore public static final int STATE_STOP = 2;
+ @Ignore int STATE_STOP = 2;
/**
- * 未开始状态
+ * 等待状态
*/
- @Ignore public static final int STATE_WAIT = 3;
+ @Ignore int STATE_WAIT = 3;
/**
* 下载中
*/
- @Ignore public static final int STATE_RUNNING = 4;
+ @Ignore int STATE_RUNNING = 4;
/**
* 预处理
*/
- @Ignore public static final int STATE_PRE = 5;
+ @Ignore int STATE_PRE = 5;
/**
* 预处理完成
*/
- @Ignore public static final int STATE_POST_PRE = 6;
+ @Ignore int STATE_POST_PRE = 6;
/**
* 取消下载
*/
- @Ignore public static final int STATE_CANCEL = 7;
+ @Ignore int STATE_CANCEL = 7;
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/IDownloadListener.java b/Aria/src/main/java/com/arialyy/aria/core/inf/IEventListener.java
similarity index 58%
rename from Aria/src/main/java/com/arialyy/aria/core/download/IDownloadListener.java
rename to Aria/src/main/java/com/arialyy/aria/core/inf/IEventListener.java
index 0e805e35..c9842fac 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/IDownloadListener.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/inf/IEventListener.java
@@ -13,73 +13,56 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package com.arialyy.aria.core.download;
+package com.arialyy.aria.core.inf;
/**
- * 下载监听
+ * Created by Aria.Lao on 2017/7/18.
+ * 基础事件
*/
-interface IDownloadListener {
-
- /**
- * 支持断点回调
- *
- * @param support true,支持;false 不支持
- */
- public void supportBreakpoint(boolean support);
-
- /**
- * 取消下载
- */
- public void onCancel();
-
- /**
- * 下载失败
- */
- public void onFail();
+public interface IEventListener {
/**
* 预处理,有时有些地址链接比较慢,这时可以先在这个地方出来一些界面上的UI,如按钮的状态
*/
- public void onPre();
+ void onPre();
/**
* 预处理完成,准备下载---开始下载之间
*/
- public void onPostPre(long fileSize);
+ void onPostPre(long fileSize);
/**
- * 下载监听
+ * 开始
*/
- public void onProgress(long currentLocation);
+ void onStart(long startLocation);
/**
- * 单一线程的结束位置
+ * 恢复位置
*/
- public void onChildComplete(long finishLocation);
+ void onResume(long resumeLocation);
/**
- * 开始
+ * 下载监听
*/
- public void onStart(long startLocation);
+ void onProgress(long currentLocation);
/**
- * 子程恢复下载的位置
+ * 停止
*/
- public void onChildResume(long resumeLocation);
+ void onStop(long stopLocation);
/**
- * 恢复位置
+ * 下载完成
*/
- public void onResume(long resumeLocation);
+ void onComplete();
/**
- * 停止
+ * 取消下载
*/
- public void onStop(long stopLocation);
+ void onCancel();
/**
- * 下载完成
+ * 下载失败
*/
- public void onComplete();
-}
\ No newline at end of file
+ void onFail();
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/IReceiver.java b/Aria/src/main/java/com/arialyy/aria/core/inf/IReceiver.java
index 0c8d701c..dc347eee 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/inf/IReceiver.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/inf/IReceiver.java
@@ -44,7 +44,7 @@ public interface IReceiver {
/**
* 删除所有任务
*/
- public void removeAllTask();
+ public void removeAllTask(boolean removeFile);
/**
* 任务是否存在
@@ -56,5 +56,5 @@ public interface IReceiver {
/**
* 获取任务列表
*/
- public List getTaskList();
+ public List getSimpleTaskList();
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/ITarget.java b/Aria/src/main/java/com/arialyy/aria/core/inf/ITarget.java
new file mode 100644
index 00000000..6a12071b
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/inf/ITarget.java
@@ -0,0 +1,86 @@
+/*
+ * 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.inf;
+
+import android.support.annotation.NonNull;
+import com.arialyy.aria.core.RequestEnum;
+import java.util.Map;
+
+/**
+ * Created by AriaL on 2017/6/29.
+ */
+public interface ITarget {
+ /**
+ * 任务文件大小
+ */
+ long getSize();
+
+ /**
+ * 转换后的大小
+ */
+ String getConvertSize();
+
+ /**
+ * 获取任务进度百分比
+ */
+ int getPercent();
+
+ /**
+ * 获取任务进度,如果任务存在,则返回当前进度
+ */
+ long getCurrentProgress();
+
+ /**
+ * 给url请求添加头部
+ *
+ * @param key 头部key
+ * @param header 头部value
+ */
+ TARGET addHeader(@NonNull String key, @NonNull String header) ;
+
+ /**
+ * 给url请求添加头部
+ */
+ TARGET addHeaders(Map headers);
+
+ /**
+ * 设置请求类型
+ *
+ * @param requestEnum {@link RequestEnum}
+ */
+ TARGET setRequestMode(RequestEnum requestEnum);
+
+ /**
+ * 开始下载
+ */
+ void start();
+
+ /**
+ * 停止下载
+ */
+ void stop();
+
+ /**
+ * 恢复下载
+ */
+ void resume();
+
+ /**
+ * 取消下载
+ */
+ void cancel();
+
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/ITask.java b/Aria/src/main/java/com/arialyy/aria/core/inf/ITask.java
index c8b4efa2..70bee951 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/inf/ITask.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/inf/ITask.java
@@ -18,25 +18,17 @@ package com.arialyy.aria.core.inf;
/**
* Created by lyy on 2017/2/13.
*/
-
public interface ITask {
/**
- * 暂停任务,并让任务处于等待状态
+ * 获取下载状态
*/
- public void stopAndWait();
+ int getState();
/**
- * 设置任务为最高优先级任务,在下载队列中,有且只有一个最高优先级任务
- */
- public void setHighestPriority(boolean isHighestPriority);
-
- /**
- * 该任务是否是最高优先级任务
- *
- * @return {@code true} 任务为最高优先级任务
+ * 获取扩展字段
*/
- public boolean isHighestPriorityTask();
+ String getExtendField();
/**
* 唯一标识符,DownloadTask 为下载地址,UploadTask 为文件路径
@@ -44,14 +36,14 @@ public interface ITask {
public String getKey();
/**
- * 是否真正执行
+ * 任务是否正在执行
*
* @return true,正在执行;
*/
public boolean isRunning();
/**
- * 获取工具实体
+ * 获取信息实体
*/
public ENTITY getEntity();
@@ -100,5 +92,4 @@ public interface ITask {
public void setTargetName(String targetName);
- public void removeRecord();
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java
index 625d28dd..8dab1afb 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java
@@ -17,24 +17,51 @@
package com.arialyy.aria.core.queue;
import android.util.Log;
-import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.AriaManager;
+import com.arialyy.aria.core.download.DownloadEntity;
+import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.inf.AbsEntity;
-import com.arialyy.aria.core.inf.ITask;
+import com.arialyy.aria.core.inf.AbsTask;
import com.arialyy.aria.core.inf.AbsTaskEntity;
-import com.arialyy.aria.core.queue.pool.CachePool;
-import com.arialyy.aria.core.queue.pool.ExecutePool;
+import com.arialyy.aria.core.inf.IEntity;
+import com.arialyy.aria.core.queue.pool.BaseCachePool;
+import com.arialyy.aria.core.queue.pool.BaseExecutePool;
import java.util.Set;
/**
* Created by lyy on 2017/2/23.
* 任务队列
*/
-abstract class AbsTaskQueue
+abstract class AbsTaskQueue
implements ITaskQueue {
private final String TAG = "AbsTaskQueue";
- CachePool mCachePool = new CachePool<>();
- ExecutePool mExecutePool;
+ BaseCachePool mCachePool;
+ BaseExecutePool mExecutePool;
+
+ AbsTaskQueue() {
+ mCachePool = setCachePool();
+ mExecutePool = setExecutePool();
+ }
+
+ abstract BaseCachePool setCachePool();
+
+ abstract BaseExecutePool setExecutePool();
+
+ @Override public boolean taskIsRunning(String key) {
+ return mExecutePool.getTask(key) != null;
+ }
+
+ @Override public void removeAllTask() {
+ Set exeKeys = mExecutePool.getAllTask().keySet();
+ for (String key : exeKeys) {
+ TASK task = mExecutePool.getAllTask().get(key);
+ if (task != null) task.cancel();
+ }
+ Set cacheKeys = mCachePool.getAllTask().keySet();
+ for (String key : cacheKeys) {
+ mExecutePool.removeTask(key);
+ }
+ }
/**
* 停止所有任务
@@ -55,17 +82,27 @@ abstract class AbsTaskQueue= oldMaxSize) {
+ for (int i = 0, len = Math.abs(diff); i < len; i++) {
+ TASK eTask = mExecutePool.pollTask();
+ if (eTask != null) {
+ stopTask(eTask);
+ }
+ }
+ }
+ mExecutePool.setMaxNum(downloadNum);
+ if (diff >= 1) {
+ for (int i = 0; i < diff; i++) {
+ TASK nextTask = getNextTask();
+ if (nextTask != null && nextTask.getState() == IEntity.STATE_WAIT) {
+ startTask(nextTask);
+ }
+ }
+ }
}
@Override public TASK getTask(String url) {
@@ -109,12 +169,22 @@ abstract class AbsTaskQueue {
+ private static volatile DownloadGroupTaskQueue INSTANCE = null;
+
+ private final String TAG = "DownloadGroupTaskQueue";
+
+ public static DownloadGroupTaskQueue getInstance() {
+ if (INSTANCE == null) {
+ synchronized (AriaManager.LOCK) {
+ INSTANCE = new DownloadGroupTaskQueue();
+ }
+ }
+ return INSTANCE;
+ }
+
+ private DownloadGroupTaskQueue() {
+ }
+
+ @Override BaseCachePool setCachePool() {
+ return DownloadSharePool.getInstance().cachePool;
+ }
+
+ @Override BaseExecutePool setExecutePool() {
+ return DownloadSharePool.getInstance().executePool;
+ }
+
+ @Override public DownloadGroupTask createTask(String targetName, DownloadGroupTaskEntity entity) {
+ DownloadGroupTask task = null;
+ if (!TextUtils.isEmpty(targetName)) {
+ task = (DownloadGroupTask) TaskFactory.getInstance()
+ .createTask(targetName, entity, DownloadGroupSchedulers.getInstance());
+ entity.key = entity.getEntity().getGroupName();
+ mCachePool.putTask(task);
+
+ DQueueMapping.getInstance().addType(task.getKey(), DQueueMapping.QUEUE_TYPE_DOWNLOAD_GROUP);
+ } else {
+ Log.e(TAG, "target name 为 null!!");
+ }
+ return task;
+ }
+
+ @Override public String getKey(DownloadGroupEntity entity) {
+ return entity.getGroupName();
+ }
+
+ @Override public int getConfigMaxNum() {
+ return AriaManager.getInstance(AriaManager.APP).getDownloadConfig().oldMaxTaskNum;
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java
index 4140433a..24d4344c 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java
@@ -22,8 +22,10 @@ import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.download.DownloadTaskEntity;
-import com.arialyy.aria.core.inf.IEntity;
-import com.arialyy.aria.core.queue.pool.ExecutePool;
+import com.arialyy.aria.core.queue.pool.BaseCachePool;
+import com.arialyy.aria.core.queue.pool.BaseExecutePool;
+import com.arialyy.aria.core.queue.pool.DownloadSharePool;
+import com.arialyy.aria.core.scheduler.DQueueMapping;
import com.arialyy.aria.core.scheduler.DownloadSchedulers;
import java.util.LinkedHashSet;
import java.util.Map;
@@ -48,10 +50,28 @@ public class DownloadTaskQueue
}
private DownloadTaskQueue() {
- mExecutePool = new ExecutePool<>(true);
}
- @Override public void setTaskHighestPriority(DownloadTask task) {
+ @Override BaseCachePool setCachePool() {
+ return DownloadSharePool.getInstance().cachePool;
+ }
+
+ @Override BaseExecutePool setExecutePool() {
+ return DownloadSharePool.getInstance().executePool;
+ }
+
+ @Override public String getKey(DownloadEntity entity) {
+ return entity.getDownloadUrl();
+ }
+
+ @Override public int getConfigMaxNum() {
+ return AriaManager.getInstance(AriaManager.APP).getDownloadConfig().oldMaxTaskNum;
+ }
+
+ /**
+ * 设置任务为最高优先级任务
+ */
+ public void setTaskHighestPriority(DownloadTask task) {
task.setHighestPriority(true);
Map exeTasks = mExecutePool.getAllTask();
if (exeTasks != null && !exeTasks.isEmpty()) {
@@ -91,66 +111,36 @@ public class DownloadTaskQueue
}
}
- public void setMaxSpeed(double maxSpeed){
+ /**
+ * 最大下载速度
+ */
+ public void setMaxSpeed(double maxSpeed) {
Map tasks = mExecutePool.getAllTask();
Set keys = tasks.keySet();
- for (String key : keys){
+ for (String key : keys) {
DownloadTask task = tasks.get(key);
task.setMaxSpeed(maxSpeed);
}
}
- @Override public void setMaxTaskNum(int downloadNum) {
- int oldMaxSize = AriaManager.getInstance(AriaManager.APP).getDownloadConfig().oldMaxTaskNum;
- int diff = downloadNum - oldMaxSize;
- if (oldMaxSize == downloadNum) {
- Log.d(TAG, "设置的下载任务数和配置文件的下载任务数一直,跳过");
- return;
- }
- //设置的任务数小于配置任务数
- if (diff <= -1 && mExecutePool.size() >= oldMaxSize) {
- for (int i = 0, len = Math.abs(diff); i < len; i++) {
- DownloadTask eTask = mExecutePool.pollTask();
- if (eTask != null) {
- stopTask(eTask);
- }
- }
- }
- mExecutePool.setDownloadNum(downloadNum);
- if (diff >= 1) {
- for (int i = 0; i < diff; i++) {
- DownloadTask nextTask = getNextTask();
- if (nextTask != null && nextTask.getDownloadEntity().getState() == IEntity.STATE_WAIT) {
- startTask(nextTask);
- }
- }
- }
- }
-
@Override public DownloadTask createTask(String target, DownloadTaskEntity entity) {
DownloadTask task = null;
if (!TextUtils.isEmpty(target)) {
task = (DownloadTask) TaskFactory.getInstance()
.createTask(target, entity, DownloadSchedulers.getInstance());
+ entity.key = entity.getEntity().getDownloadPath();
mCachePool.putTask(task);
+
+ DQueueMapping.getInstance().addType(task.getKey(), DQueueMapping.QUEUE_TYPE_DOWNLOAD);
} else {
- Log.e(TAG, "target name 为 null是!!");
+ Log.e(TAG, "target name 为 null!!");
}
- return task;
- }
- @Override public DownloadTask getTask(DownloadEntity entity) {
- return getTask(entity.getDownloadUrl());
+ return task;
}
- @Override public void removeTask(DownloadEntity entity) {
- DownloadTask task = mExecutePool.getTask(entity.getDownloadUrl());
- if (task != null) {
- Log.d(TAG, "从执行池删除任务,删除" + (mExecutePool.removeTask(task) ? "成功" : "失败"));
- }
- task = mCachePool.getTask(entity.getDownloadUrl());
- if (task != null) {
- Log.d(TAG, "从缓存池删除任务,删除" + (mCachePool.removeTask(task) ? "成功" : "失败"));
- }
+ @Override public void stopTask(DownloadTask task) {
+ task.setHighestPriority(false);
+ super.stopTask(task);
}
}
\ No newline at end of file
diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/ITaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/ITaskQueue.java
index 9c9bd7c0..76594a81 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/queue/ITaskQueue.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/queue/ITaskQueue.java
@@ -19,8 +19,10 @@ package com.arialyy.aria.core.queue;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.download.DownloadTask;
+import com.arialyy.aria.core.inf.AbsEntity;
+import com.arialyy.aria.core.inf.AbsNormalTask;
+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;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTask;
@@ -30,7 +32,15 @@ import com.arialyy.aria.core.upload.UploadTaskEntity;
* Created by lyy on 2016/8/16.
* 任务功能接口
*/
-public interface ITaskQueue {
+public interface ITaskQueue {
+
+ /**
+ * 通过key判断任务是否正在执行
+ *
+ * @param key 下载链接,或上传文件的路径
+ * @return {@code true} 任务正在运行
+ */
+ boolean taskIsRunning(String key);
/**
* 停止所有任务
@@ -38,11 +48,9 @@ public interface ITaskQueue {@link DownloadTaskEntity}、{@link UploadTaskEntity}
- * @param {@link DownloadSchedulers}
- * @return {@link DownloadTask}、{@link UploadTask}
+ * @param {@link DownloadTaskEntity}、{@link UploadTaskEntity}、{@link
+ * DownloadGroupTaskEntity}
+ * @param {@link DownloadSchedulers}、{@link UploadSchedulers}
+ * @return {@link DownloadTask}、{@link UploadTask}、{@link DownloadGroupTask}
*/
- ITask createTask(String targetName,
- ENTITY entity, SCHEDULER schedulers) {
+ ITask createTask(
+ String targetName, TASK_ENTITY entity, SCHEDULER schedulers) {
if (entity instanceof DownloadTaskEntity) {
return createDownloadTask(targetName, (DownloadTaskEntity) entity, schedulers);
} else if (entity instanceof UploadTaskEntity) {
return createUploadTask(targetName, (UploadTaskEntity) entity, schedulers);
+ } else if (entity instanceof DownloadGroupTaskEntity) {
+ return createDownloadGroupTask(targetName, (DownloadGroupTaskEntity) entity, schedulers);
}
return null;
}
+ /**
+ * 创建下载任务主任务
+ *
+ * @param entity 下载任务实体{@link DownloadGroupTask}
+ * @param schedulers {@link ISchedulers}
+ */
+ private DownloadGroupTask createDownloadGroupTask(String targetName,
+ DownloadGroupTaskEntity entity, ISchedulers schedulers) {
+ DownloadGroupTask.Builder builder = new DownloadGroupTask.Builder(targetName, entity);
+ builder.setOutHandler(schedulers);
+ return builder.build();
+ }
+
/**
* @param entity 上传任务实体{@link UploadTaskEntity}
* @param schedulers {@link ISchedulers}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java
index 2b56ac84..46e3f9b4 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java
@@ -19,7 +19,9 @@ package com.arialyy.aria.core.queue;
import android.text.TextUtils;
import android.util.Log;
import com.arialyy.aria.core.AriaManager;
-import com.arialyy.aria.core.queue.pool.ExecutePool;
+import com.arialyy.aria.core.queue.pool.BaseCachePool;
+import com.arialyy.aria.core.queue.pool.BaseExecutePool;
+import com.arialyy.aria.core.queue.pool.UploadSharePool;
import com.arialyy.aria.core.scheduler.UploadSchedulers;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTask;
@@ -43,11 +45,22 @@ public class UploadTaskQueue extends AbsTaskQueue(false);
}
- @Override public void setMaxTaskNum(int newMaxNum) {
+ @Override BaseCachePool setCachePool() {
+ return UploadSharePool.getInstance().cachePool;
+ }
+
+ @Override BaseExecutePool setExecutePool() {
+ return UploadSharePool.getInstance().executePool;
+ }
+ @Override public String getKey(UploadEntity entity) {
+ return entity.getFilePath();
+ }
+
+ @Override public int getConfigMaxNum() {
+ return AriaManager.getInstance(AriaManager.APP).getUploadConfig().oldMaxTaskNum;
}
@Override public UploadTask createTask(String targetName, UploadTaskEntity entity) {
@@ -55,25 +68,11 @@ public class UploadTaskQueue extends AbsTaskQueue implements IPool {
- private static final String TAG = "CachePool";
+public class BaseCachePool implements IPool {
+ private static final String TAG = "BaseCachePool";
private static final int MAX_NUM = Integer.MAX_VALUE; //最大下载任务数
private static final long TIME_OUT = 1000;
private Map mCacheMap;
private LinkedBlockingQueue mCacheQueue;
- public CachePool() {
+ public BaseCachePool() {
mCacheQueue = new LinkedBlockingQueue<>(MAX_NUM);
mCacheMap = new HashMap<>();
}
/**
- * 获取所有正在执行的任务
+ * 获取被缓存的任务
*/
public Map getAllTask() {
return mCacheMap;
@@ -95,7 +96,7 @@ public class CachePool implements IPool {
@Override public TASK pollTask() {
synchronized (AriaManager.LOCK) {
try {
- TASK task = null;
+ TASK task;
task = mCacheQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
if (task != null) {
String url = task.getKey();
diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/ExecutePool.java b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/BaseExecutePool.java
similarity index 73%
rename from Aria/src/main/java/com/arialyy/aria/core/queue/pool/ExecutePool.java
rename to Aria/src/main/java/com/arialyy/aria/core/queue/pool/BaseExecutePool.java
index 4f9691af..fda42905 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/ExecutePool.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/BaseExecutePool.java
@@ -19,11 +19,12 @@ package com.arialyy.aria.core.queue.pool;
import android.text.TextUtils;
import android.util.Log;
import com.arialyy.aria.core.AriaManager;
+import com.arialyy.aria.core.inf.AbsTask;
import com.arialyy.aria.core.inf.ITask;
+import com.arialyy.aria.core.scheduler.DQueueMapping;
import com.arialyy.aria.util.CommonUtil;
import java.util.HashMap;
import java.util.Map;
-import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
@@ -31,23 +32,28 @@ import java.util.concurrent.TimeUnit;
* Created by lyy on 2016/8/15.
* 任务执行池,所有当前下载任务都该任务池中,默认下载大小为2
*/
-public class ExecutePool implements IPool {
- private static final String TAG = "ExecutePool";
- private static final long TIME_OUT = 1000;
- private ArrayBlockingQueue mExecuteQueue;
- private Map mExecuteMap;
- private int mSize;
-
- public ExecutePool(boolean isDownload) {
- if (isDownload) {
- mSize = AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getMaxTaskNum();
- } else {
- mSize = AriaManager.getInstance(AriaManager.APP).getUploadConfig().getMaxTaskNum();
- }
+public class BaseExecutePool implements IPool {
+ private final String TAG = "BaseExecutePool";
+ final long TIME_OUT = 1000;
+ ArrayBlockingQueue mExecuteQueue;
+ Map mExecuteMap;
+ int mSize;
+
+ BaseExecutePool() {
+ mSize = getMaxSize();
mExecuteQueue = new ArrayBlockingQueue<>(mSize);
mExecuteMap = new HashMap<>();
}
+ /**
+ * 获取最大任务数配置
+ *
+ * @return {@link AriaManager#getDownloadConfig()} {@link AriaManager#getUploadConfig()},如果不设置,默认返回2
+ */
+ protected int getMaxSize() {
+ return 2;
+ }
+
/**
* 获取所有正在执行的任务
*/
@@ -67,10 +73,6 @@ public class ExecutePool implements IPool {
return false;
} else {
if (mExecuteQueue.size() >= mSize) {
- Set keys = mExecuteMap.keySet();
- for (String key : keys) {
- if (mExecuteMap.get(key).isHighestPriorityTask()) return false;
- }
if (pollFirstTask()) {
return putNewTask(task);
}
@@ -83,19 +85,19 @@ public class ExecutePool implements IPool {
}
/**
- * 设置执行任务数
+ * 设置执行队列最大任务数
*
- * @param downloadNum 下载数
+ * @param maxNum 下载数
*/
- public void setDownloadNum(int downloadNum) {
+ public void setMaxNum(int maxNum) {
try {
- ArrayBlockingQueue temp = new ArrayBlockingQueue<>(downloadNum);
+ ArrayBlockingQueue temp = new ArrayBlockingQueue<>(maxNum);
TASK task;
while ((task = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS)) != null) {
temp.offer(task);
}
mExecuteQueue = temp;
- mSize = downloadNum;
+ mSize = maxNum;
} catch (InterruptedException e) {
e.printStackTrace();
}
@@ -104,9 +106,9 @@ public class ExecutePool implements IPool {
/**
* 添加新任务
*
- * @param newTask 新下载任务
+ * @param newTask 新任务
*/
- private boolean putNewTask(TASK newTask) {
+ boolean putNewTask(TASK newTask) {
String url = newTask.getKey();
boolean s = mExecuteQueue.offer(newTask);
Log.w(TAG, "任务添加" + (s ? "成功" : "失败,【" + url + "】"));
@@ -119,16 +121,13 @@ public class ExecutePool implements IPool {
/**
* 队列满时,将移除下载队列中的第一个任务
*/
- private boolean pollFirstTask() {
+ boolean pollFirstTask() {
try {
TASK oldTask = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
if (oldTask == null) {
Log.e(TAG, "移除任务失败");
return false;
}
- if (oldTask.isHighestPriorityTask()) {
- return false;
- }
oldTask.stop();
String key = CommonUtil.keyToHashKey(oldTask.getKey());
mExecuteMap.remove(key);
@@ -142,7 +141,7 @@ public class ExecutePool implements IPool {
@Override public TASK pollTask() {
synchronized (AriaManager.LOCK) {
try {
- TASK task = null;
+ TASK task;
task = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
if (task != null) {
String url = task.getKey();
@@ -173,22 +172,22 @@ public class ExecutePool implements IPool {
Log.e(TAG, "任务不能为空");
return false;
} else {
- String key = CommonUtil.keyToHashKey(task.getKey());
- mExecuteMap.remove(key);
- return mExecuteQueue.remove(task);
+ return removeTask(task.getKey());
}
}
}
- @Override public boolean removeTask(String downloadUrl) {
+ @Override public boolean removeTask(String key) {
synchronized (AriaManager.LOCK) {
- if (TextUtils.isEmpty(downloadUrl)) {
+ if (TextUtils.isEmpty(key)) {
Log.e(TAG, "请传入有效的任务key");
return false;
}
- String key = CommonUtil.keyToHashKey(downloadUrl);
- TASK task = mExecuteMap.get(key);
- mExecuteMap.remove(key);
+ String convertKey = CommonUtil.keyToHashKey(key);
+ TASK task = mExecuteMap.get(convertKey);
+ mExecuteMap.remove(convertKey);
+
+ DQueueMapping.getInstance().removeType(key);
return mExecuteQueue.remove(task);
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/DownloadExecutePool.java b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/DownloadExecutePool.java
new file mode 100644
index 00000000..6123a62b
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/DownloadExecutePool.java
@@ -0,0 +1,82 @@
+/*
+ * 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.queue.pool;
+
+import android.util.Log;
+import com.arialyy.aria.core.AriaManager;
+import com.arialyy.aria.core.inf.AbsTask;
+import com.arialyy.aria.util.CommonUtil;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by AriaL on 2017/6/29.
+ * 单个下载任务的执行池
+ */
+public class DownloadExecutePool extends BaseExecutePool {
+ private final String TAG = "DownloadExecutePool";
+
+ @Override protected int getMaxSize() {
+ return AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getMaxTaskNum();
+ }
+
+ @Override public boolean putTask(TASK task) {
+ synchronized (AriaManager.LOCK) {
+ if (task == null) {
+ Log.e(TAG, "任务不能为空!!");
+ return false;
+ }
+ String url = task.getKey();
+ if (mExecuteQueue.contains(task)) {
+ Log.e(TAG, "队列中已经包含了该任务,任务key【" + url + "】");
+ return false;
+ } else {
+ if (mExecuteQueue.size() >= mSize) {
+ Set keys = mExecuteMap.keySet();
+ for (String key : keys) {
+ if (mExecuteMap.get(key).isHighestPriorityTask()) return false;
+ }
+ if (pollFirstTask()) {
+ return putNewTask(task);
+ }
+ } else {
+ return putNewTask(task);
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override boolean pollFirstTask() {
+ try {
+ TASK oldTask = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
+ if (oldTask == null) {
+ Log.e(TAG, "移除任务失败");
+ return false;
+ }
+ if (oldTask.isHighestPriorityTask()) {
+ return false;
+ }
+ oldTask.stop();
+ String key = CommonUtil.keyToHashKey(oldTask.getKey());
+ mExecuteMap.remove(key);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/DownloadSharePool.java b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/DownloadSharePool.java
new file mode 100644
index 00000000..cd7625bd
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/DownloadSharePool.java
@@ -0,0 +1,43 @@
+/*
+ * 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.queue.pool;
+
+import com.arialyy.aria.core.AriaManager;
+
+/**
+ * Created by Aria.Lao on 2017/7/17.
+ * 下载任务池,该池子为简单任务和任务组共用
+ */
+public class DownloadSharePool {
+ private static volatile DownloadSharePool INSTANCE;
+
+ public DownloadExecutePool executePool;
+ public BaseCachePool cachePool;
+
+ private DownloadSharePool() {
+ executePool = new DownloadExecutePool<>();
+ cachePool = new BaseCachePool<>();
+ }
+
+ public static DownloadSharePool getInstance() {
+ if (INSTANCE == null) {
+ synchronized (AriaManager.LOCK) {
+ INSTANCE = new DownloadSharePool();
+ }
+ }
+ return INSTANCE;
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/IPool.java b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/IPool.java
index 53378e9c..ae6ab6c7 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/IPool.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/IPool.java
@@ -16,24 +16,24 @@
package com.arialyy.aria.core.queue.pool;
-import com.arialyy.aria.core.inf.ITask;
+import com.arialyy.aria.core.inf.AbsTask;
/**
* Created by lyy on 2016/8/14.
* 任务池
*/
-public interface IPool {
+interface IPool {
/**
* 将下载任务添加到任务池中
*/
- public boolean putTask(T task);
+ boolean putTask(T task);
/**
* 按照队列原则取出下载任务
*
* @return 返回null或者下载任务
*/
- public T pollTask();
+ T pollTask();
/**
* 通过下载链接获取下载任务,当任务不为空时,队列将删除该下载任务
@@ -41,7 +41,7 @@ public interface IPool {
* @param downloadUrl 下载链接
* @return 返回null或者下载任务
*/
- public T getTask(String downloadUrl);
+ T getTask(String downloadUrl);
/**
* 删除任务池中的下载任务
@@ -49,20 +49,20 @@ public interface IPool {
* @param task 下载任务
* @return true:移除成功
*/
- public boolean removeTask(T task);
+ boolean removeTask(T task);
/**
- * 通过下载链接移除下载任务
+ * 通过key除下载任务
*
- * @param downloadUrl 下载链接
+ * @param key 下载链接
* @return true:移除成功
*/
- public boolean removeTask(String downloadUrl);
+ boolean removeTask(String key);
/**
* 池子大小
*
- * @return 返回缓存池或者当前任务池大小
+ * @return 返回缓存池或者执行池大小
*/
- public int size();
+ int size();
}
\ No newline at end of file
diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/UploadExecutePool.java b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/UploadExecutePool.java
new file mode 100644
index 00000000..b5437f2c
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/UploadExecutePool.java
@@ -0,0 +1,28 @@
+/*
+ * 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.queue.pool;
+
+import com.arialyy.aria.core.AriaManager;
+import com.arialyy.aria.core.inf.AbsTask;
+
+/**
+ * Created by Aria.Lao on 2017/7/17.
+ */
+public class UploadExecutePool extends BaseExecutePool {
+ @Override protected int getMaxSize() {
+ return AriaManager.getInstance(AriaManager.APP).getUploadConfig().getMaxTaskNum();
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/UploadSharePool.java b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/UploadSharePool.java
new file mode 100644
index 00000000..f75af152
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/UploadSharePool.java
@@ -0,0 +1,43 @@
+/*
+ * 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.queue.pool;
+
+import com.arialyy.aria.core.AriaManager;
+
+/**
+ * Created by Aria.Lao on 2017/7/17.
+ * 下载任务池,该池子为简单任务和任务组共用
+ */
+public class UploadSharePool {
+ private static volatile UploadSharePool INSTANCE;
+
+ public UploadExecutePool executePool;
+ public BaseCachePool cachePool;
+
+ private UploadSharePool() {
+ executePool = new UploadExecutePool();
+ cachePool = new BaseCachePool<>();
+ }
+
+ public static UploadSharePool getInstance() {
+ if (INSTANCE == null) {
+ synchronized (AriaManager.LOCK) {
+ INSTANCE = new UploadSharePool();
+ }
+ }
+ return INSTANCE;
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java
index f53bf4e7..8e40eacb 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java
@@ -21,9 +21,9 @@ import android.util.Log;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.inf.AbsEntity;
+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.core.queue.ITaskQueue;
import com.arialyy.aria.core.upload.UploadTask;
import java.util.Iterator;
@@ -33,28 +33,32 @@ import java.util.concurrent.ConcurrentHashMap;
/**
* Created by lyy on 2017/6/4.
+ * 事件调度器,用于处理任务状态的调度
*/
-public abstract class AbsSchedulers, QUEUE extends ITaskQueue>
+abstract class AbsSchedulers, QUEUE extends ITaskQueue>
implements ISchedulers {
- private static final String TAG = "AbsSchedulers";
+ private final String TAG = "AbsSchedulers";
- /**
- * 下载的动态生成的代理类后缀
- */
- String DOWNLOAD_PROXY_CLASS_SUFFIX = "$$DownloadListenerProxy";
-
- /**
- * 上传的动态生成的代理类后缀
- */
- String UPLOAD_PROXY_CLASS_SUFFIX = "$$UploadListenerProxy";
+ static final int DOWNLOAD = 0xa1;
+ static final int UPLOAD = 0xa2;
+ static final int DOWNLOAD_GROUP = 0xa3;
protected QUEUE mQueue;
- protected boolean isDownload = true;
private Map> mSchedulerListeners = new ConcurrentHashMap<>();
private Map> mObservers = new ConcurrentHashMap<>();
+ /**
+ * 设置调度器类型
+ */
+ abstract int getSchedulerType();
+
+ /**
+ * 设置代理类后缀名
+ */
+ abstract String getProxySuffix();
+
/**
* @param targetName 观察者,创建该监听器的对象类名
* @param schedulerListener {@link ISchedulerListener}
@@ -109,18 +113,14 @@ public abstract class AbsSchedulers createListener(String targetName) {
AbsSchedulerListener listener = null;
try {
- Class clazz = Class.forName(
- targetName + (isDownload ? DOWNLOAD_PROXY_CLASS_SUFFIX : UPLOAD_PROXY_CLASS_SUFFIX));
+ Class clazz = Class.forName(targetName + getProxySuffix());
listener = (AbsSchedulerListener) clazz.newInstance();
} catch (ClassNotFoundException e) {
Log.e(TAG, targetName + ",没有Aria的Download或Upload注解方法");
- //e.printStackTrace();
} catch (InstantiationException e) {
Log.e(TAG, e.getMessage());
- //e.printStackTrace();
} catch (IllegalAccessException e) {
Log.e(TAG, e.getMessage());
- //e.printStackTrace();
}
return listener;
}
@@ -131,7 +131,6 @@ public abstract class AbsSchedulers 0;
+ }
+
+ /**
+ * 获取正在执行的队列数
+ */
+ int getExeTaskNum() {
+ return mQueue.getCurrentExePoolNum();
+ }
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/DQueueMapping.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/DQueueMapping.java
new file mode 100644
index 00000000..623a4a0e
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/DQueueMapping.java
@@ -0,0 +1,89 @@
+/*
+ * 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.scheduler;
+
+import com.arialyy.aria.core.AriaManager;
+import com.arialyy.aria.core.queue.DownloadGroupTaskQueue;
+import com.arialyy.aria.core.queue.DownloadTaskQueue;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Created by Aria.Lao on 2017/7/13.
+ * 下载任务和队列的映射表
+ */
+public class DQueueMapping {
+
+ public static final int QUEUE_TYPE_DOWNLOAD = 0xa1;
+ public static final int QUEUE_TYPE_DOWNLOAD_GROUP = 0xa2;
+ public static final int QUEUE_NONE = 0xab2;
+ private LinkedHashMap types = new LinkedHashMap<>();
+
+ private static volatile DQueueMapping instance = null;
+
+ private DQueueMapping() {
+
+ }
+
+ public static DQueueMapping getInstance() {
+ if (instance == null) {
+ synchronized (AriaManager.LOCK) {
+ instance = new DQueueMapping();
+ }
+ }
+ return instance;
+ }
+
+ /**
+ * map中增加类型
+ *
+ * @param key 任务的key
+ * @param type {@link #QUEUE_TYPE_DOWNLOAD}、{@link #QUEUE_TYPE_DOWNLOAD}
+ */
+ public void addType(String key, int type) {
+ types.put(key, type);
+ }
+
+ /**
+ * @param key 任务的key
+ */
+ public void removeType(String key) {
+ types.remove(key);
+ }
+
+ /**
+ * 获取下一个任务类型
+ *
+ * @return {@link #QUEUE_TYPE_DOWNLOAD}、{@link #QUEUE_TYPE_DOWNLOAD}
+ */
+ public int nextType() {
+ Iterator> iter = types.entrySet().iterator();
+ if (iter.hasNext()) {
+ Map.Entry next = iter.next();
+ int type = next.getValue();
+ iter.remove();
+ return type;
+ }
+ return QUEUE_NONE;
+ }
+
+ public boolean canStart() {
+ return DownloadTaskQueue.getInstance().getCurrentExePoolNum()
+ + DownloadGroupTaskQueue.getInstance().getCurrentExePoolNum() >= AriaManager.getInstance(
+ AriaManager.APP).getDownloadConfig().getMaxTaskNum();
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadGroupSchedulers.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadGroupSchedulers.java
new file mode 100644
index 00000000..dd4dde4a
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadGroupSchedulers.java
@@ -0,0 +1,74 @@
+/*
+ * 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.scheduler;
+
+import com.arialyy.aria.core.AriaManager;
+import com.arialyy.aria.core.download.DownloadGroupEntity;
+import com.arialyy.aria.core.download.DownloadGroupTask;
+import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
+import com.arialyy.aria.core.queue.DownloadGroupTaskQueue;
+
+/**
+ * Created by AriaL on 2017/7/2.
+ * 任务组调度器
+ */
+public class DownloadGroupSchedulers extends
+ AbsSchedulers {
+ private final String TAG = "DownloadGroupSchedulers";
+ private static volatile DownloadGroupSchedulers INSTANCE = null;
+
+ private DownloadGroupSchedulers() {
+ mQueue = DownloadGroupTaskQueue.getInstance();
+ }
+
+ public static DownloadGroupSchedulers getInstance() {
+ if (INSTANCE == null) {
+ synchronized (AriaManager.LOCK) {
+ INSTANCE = new DownloadGroupSchedulers();
+ }
+ }
+ return INSTANCE;
+ }
+
+ @Override int getSchedulerType() {
+ return DOWNLOAD_GROUP;
+ }
+
+ @Override String getProxySuffix() {
+ return "$$DownloadGroupListenerProxy";
+ }
+
+ @Override protected void startNextTask() {
+ if (getExeTaskNum() + DownloadSchedulers.getInstance().getExeTaskNum()
+ >= AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getMaxTaskNum()) {
+ return;
+ }
+ if (!DownloadSchedulers.getInstance().hasNextTask()) {
+ nextSelf();
+ } else {
+ Integer nextType = DQueueMapping.getInstance().nextType();
+ if (nextType == DQueueMapping.QUEUE_TYPE_DOWNLOAD) {
+ DownloadSchedulers.getInstance().nextSelf();
+ } else {
+ nextSelf();
+ }
+ }
+ }
+
+ void nextSelf() {
+ super.startNextTask();
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadSchedulers.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadSchedulers.java
index f6137abf..5226c13b 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadSchedulers.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadSchedulers.java
@@ -16,11 +16,13 @@
package com.arialyy.aria.core.scheduler;
+import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.queue.DownloadTaskQueue;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTask;
+import java.nio.MappedByteBuffer;
/**
* Created by lyy on 2016/8/16.
@@ -29,12 +31,11 @@ import com.arialyy.aria.core.download.DownloadTask;
public class DownloadSchedulers
extends AbsSchedulers {
- private static final String TAG = "DownloadSchedulers";
+ private final String TAG = "DownloadSchedulers";
private static volatile DownloadSchedulers INSTANCE = null;
private DownloadSchedulers() {
mQueue = DownloadTaskQueue.getInstance();
- isDownload = true;
}
public static DownloadSchedulers getInstance() {
@@ -45,4 +46,33 @@ public class DownloadSchedulers
}
return INSTANCE;
}
+
+ @Override int getSchedulerType() {
+ return DOWNLOAD;
+ }
+
+ @Override String getProxySuffix() {
+ return "$$DownloadListenerProxy";
+ }
+
+ @Override protected void startNextTask() {
+ if (getExeTaskNum() + DownloadGroupSchedulers.getInstance().getExeTaskNum()
+ >= AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getMaxTaskNum()) {
+ return;
+ }
+ if (!DownloadGroupSchedulers.getInstance().hasNextTask()) {
+ nextSelf();
+ } else {
+ Integer nextType = DQueueMapping.getInstance().nextType();
+ if (nextType == DQueueMapping.QUEUE_TYPE_DOWNLOAD_GROUP) {
+ DownloadGroupSchedulers.getInstance().nextSelf();
+ } else {
+ nextSelf();
+ }
+ }
+ }
+
+ void nextSelf() {
+ super.startNextTask();
+ }
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/ISchedulers.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/ISchedulers.java
index 7549b55a..a88e1f29 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/scheduler/ISchedulers.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/ISchedulers.java
@@ -17,54 +17,54 @@
package com.arialyy.aria.core.scheduler;
import android.os.Handler;
-import com.arialyy.aria.core.inf.ITask;
+import com.arialyy.aria.core.inf.AbsTask;
/**
* Created by lyy on 2016/11/2.
* 调度器功能接口
*/
-public interface ISchedulers extends Handler.Callback {
+public interface ISchedulers extends Handler.Callback {
/**
* 断点支持
*/
- public static final int SUPPORT_BREAK_POINT = 9;
+ int SUPPORT_BREAK_POINT = 9;
/**
* 任务预加载
*/
- public static final int PRE = 0;
+ int PRE = 0;
/**
* 任务预加载完成
*/
- public static final int POST_PRE = 1;
+ int POST_PRE = 1;
/**
* 任务开始
*/
- public static final int START = 2;
+ int START = 2;
/**
* 任务停止
*/
- public static final int STOP = 3;
+ int STOP = 3;
/**
* 任务失败
*/
- public static final int FAIL = 4;
+ int FAIL = 4;
/**
* 任务取消
*/
- public static final int CANCEL = 5;
+ int CANCEL = 5;
/**
* 任务完成
*/
- public static final int COMPLETE = 6;
+ int COMPLETE = 6;
/**
* 任务处理中
*/
- public static final int RUNNING = 7;
+ int RUNNING = 7;
/**
* 恢复任务
*/
- public static final int RESUME = 8;
+ int RESUME = 8;
/**
* 注册下载器监听,一个观察者只能注册一次监听
@@ -72,26 +72,25 @@ public interface ISchedulers extends Handler.Callback {
* @param targetName 观察者,创建该监听器的对象类名
* @param schedulerListener {@link ISchedulerListener}
*/
- public void addSchedulerListener(String targetName, ISchedulerListener schedulerListener);
+ void addSchedulerListener(String targetName, ISchedulerListener schedulerListener);
/**
* @param targetName 观察者,创建该监听器的对象类名
* 取消注册监听器
*/
- public void removeSchedulerListener(String targetName,
- ISchedulerListener schedulerListener);
+ void removeSchedulerListener(String targetName, ISchedulerListener schedulerListener);
/**
* 将当前类注册到Aria
*
* @param obj 观察者类
*/
- public void register(Object obj);
+ void register(Object obj);
/**
* 移除注册
*
* @param obj 观察者类
*/
- public void unRegister(Object obj);
+ void unRegister(Object obj);
}
\ No newline at end of file
diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/UploadSchedulers.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/UploadSchedulers.java
index c3dfd361..be260d57 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/scheduler/UploadSchedulers.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/UploadSchedulers.java
@@ -32,7 +32,6 @@ public class UploadSchedulers
private UploadSchedulers() {
mQueue = UploadTaskQueue.getInstance();
- isDownload = false;
}
public static UploadSchedulers getInstance() {
@@ -44,4 +43,12 @@ public class UploadSchedulers
return INSTANCE;
}
+
+ @Override int getSchedulerType() {
+ return UPLOAD;
+ }
+
+ @Override String getProxySuffix() {
+ return "$$UploadListenerProxy";
+ }
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/IUploadListener.java b/Aria/src/main/java/com/arialyy/aria/core/upload/IUploadListener.java
index 02a9e28c..2a8cab14 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/upload/IUploadListener.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/upload/IUploadListener.java
@@ -15,60 +15,12 @@
*/
package com.arialyy.aria.core.upload;
+import com.arialyy.aria.core.inf.IEventListener;
+
/**
* Created by lyy on 2017/2/9.
* 上传监听
*/
-public interface IUploadListener {
-
- /**
- * 预处理
- */
- public void onPre();
-
- /**
- * 预处理完成
- */
- public void onPostPre(long fileSize);
-
- /**
- * 开始上传
- */
- public void onStart();
-
- /**
- * 恢复上传
- *
- * @param resumeLocation 上次上传停止位置
- */
- public void onResume(long resumeLocation);
-
- /**
- * 停止上传
- *
- * @param stopLocation 上传停止位置
- */
- public void onStop(long stopLocation);
-
- /**
- * 上传进度
- *
- * @param currentLocation 当前进度
- */
- public void onProgress(long currentLocation);
-
- /**
- * 取消上传
- */
- public void onCancel();
-
- /**
- * 上传成功
- */
- public void onComplete();
+interface IUploadListener extends IEventListener {
- /**
- * 上传失败
- */
- public void onFail();
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/ProxyHelper.java b/Aria/src/main/java/com/arialyy/aria/core/upload/ProxyHelper.java
new file mode 100644
index 00000000..7162301a
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/upload/ProxyHelper.java
@@ -0,0 +1,78 @@
+/*
+ * 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.upload;
+
+import com.arialyy.aria.core.AriaManager;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Set;
+
+import static java.util.Collections.unmodifiableSet;
+
+/**
+ * Created by Aria.Lao on 2017/7/10.
+ * 代理参数获取
+ */
+public class ProxyHelper {
+ public Set downloadCounter, uploadCounter, downloadGroupCounter;
+
+ public static volatile ProxyHelper INSTANCE = null;
+
+ private ProxyHelper() {
+ init();
+ }
+
+ public static ProxyHelper getInstance() {
+ if (INSTANCE == null) {
+ synchronized (AriaManager.LOCK) {
+ INSTANCE = new ProxyHelper();
+ }
+ }
+ return INSTANCE;
+ }
+
+ private void init() {
+ try {
+ Class clazz = Class.forName("com.arialyy.aria.ProxyClassCounter");
+ Method download = clazz.getMethod("getDownloadCounter");
+ Method downloadGroup = clazz.getMethod("getDownloadGroupCounter");
+ Method upload = clazz.getMethod("getUploadCounter");
+ Object object = clazz.newInstance();
+ Object dc = download.invoke(object);
+ if (dc != null) {
+ downloadCounter = unmodifiableSet((Set) dc);
+ }
+ Object dgc = downloadGroup.invoke(object);
+ if (dgc != null) {
+ downloadGroupCounter = unmodifiableSet((Set) dgc);
+ }
+ Object uc = upload.invoke(object);
+ if (uc != null) {
+ uploadCounter = unmodifiableSet((Set) uc);
+ }
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ } catch (InstantiationException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java
index dafc69d9..05bfc5cf 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java
@@ -17,25 +17,18 @@ package com.arialyy.aria.core.upload;
import android.os.Parcel;
import android.os.Parcelable;
-import com.arialyy.aria.core.inf.AbsEntity;
+import com.arialyy.aria.core.inf.AbsNormalEntity;
import com.arialyy.aria.orm.Ignore;
+import com.arialyy.aria.orm.Primary;
/**
* Created by lyy on 2017/2/9.
* 上传文件实体
*/
-public class UploadEntity extends AbsEntity implements Parcelable {
-
+public class UploadEntity extends AbsNormalEntity implements Parcelable {
+ @Primary
private String filePath; //文件路径
- private boolean isComplete = false;
-
- public boolean isComplete() {
- return isComplete;
- }
- public void setComplete(boolean complete) {
- isComplete = complete;
- }
public String getFilePath() {
return filePath;
@@ -45,6 +38,10 @@ public class UploadEntity extends AbsEntity implements Parcelable {
this.filePath = filePath;
}
+ @Override public String getKey() {
+ return filePath;
+ }
+
public UploadEntity() {
}
@@ -55,13 +52,11 @@ public class UploadEntity extends AbsEntity implements Parcelable {
@Override public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(this.filePath);
- dest.writeByte(this.isComplete ? (byte) 1 : (byte) 0);
}
protected UploadEntity(Parcel in) {
super(in);
this.filePath = in.readString();
- this.isComplete = in.readByte() != 0;
}
@Ignore public static final Creator CREATOR = new Creator() {
diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadListener.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadListener.java
index b8cfcb6a..a4c432ae 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadListener.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadListener.java
@@ -18,8 +18,7 @@ package com.arialyy.aria.core.upload;
/**
* Created by lyy on 2017/2/23.
*/
-
-public class UploadListener implements IUploadListener {
+class UploadListener implements IUploadListener {
@Override public void onPre() {
}
@@ -28,7 +27,7 @@ public class UploadListener implements IUploadListener {
}
- @Override public void onStart() {
+ @Override public void onStart(long startLocation) {
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java
index 38e71953..eab63b7c 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java
@@ -17,30 +17,24 @@ package com.arialyy.aria.core.upload;
import android.support.annotation.NonNull;
import com.arialyy.aria.core.AriaManager;
-import com.arialyy.aria.core.command.AbsCmd;
-import com.arialyy.aria.core.command.CmdFactory;
-import com.arialyy.aria.core.download.DownloadReceiver;
-import com.arialyy.aria.core.inf.IEntity;
+import com.arialyy.aria.core.command.normal.NormalCmdFactory;
+import com.arialyy.aria.core.download.DownloadTaskEntity;
+import com.arialyy.aria.core.inf.AbsReceiver;
import com.arialyy.aria.core.inf.IReceiver;
-import com.arialyy.aria.core.scheduler.DownloadSchedulers;
import com.arialyy.aria.core.scheduler.ISchedulerListener;
import com.arialyy.aria.core.scheduler.UploadSchedulers;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.CheckUtil;
import com.arialyy.aria.util.CommonUtil;
-import java.util.ArrayList;
import java.util.List;
import java.util.Set;
-import java.util.regex.Pattern;
/**
* Created by lyy on 2017/2/6.
* 上传功能接收器
*/
-public class UploadReceiver implements IReceiver {
+public class UploadReceiver extends AbsReceiver {
private static final String TAG = "DownloadReceiver";
- public String targetName;
- public Object obj;
public ISchedulerListener listener;
/**
@@ -50,17 +44,7 @@ public class UploadReceiver implements IReceiver {
*/
public UploadTarget load(@NonNull String filePath) {
CheckUtil.checkUploadPath(filePath);
- UploadEntity entity = UploadEntity.findData(UploadEntity.class, "filePath=?", filePath);
- if (entity == null) {
- entity = new UploadEntity();
- }
- String regex = "[/|\\\\|//]";
- Pattern p = Pattern.compile(regex);
- String[] strs = p.split(filePath);
- String fileName = strs[strs.length - 1];
- entity.setFileName(fileName);
- entity.setFilePath(filePath);
- return new UploadTarget(entity, targetName);
+ return new UploadTarget(filePath, targetName);
}
/**
@@ -68,41 +52,39 @@ public class UploadReceiver implements IReceiver {
*/
public UploadEntity getUploadEntity(String filePath) {
CheckUtil.checkUploadPath(filePath);
- return DbEntity.findData(UploadEntity.class, "filePath=?", filePath);
+ return DbEntity.findFirst(UploadEntity.class, "filePath=?", filePath);
}
/**
* 下载任务是否存在
*/
@Override public boolean taskExists(String filePath) {
- return DbEntity.findData(UploadEntity.class, "filePath=?", filePath) != null;
+ return DbEntity.findFirst(UploadEntity.class, "filePath=?", filePath) != null;
}
- @Override public List getTaskList() {
+ @Override public List getSimpleTaskList() {
return DbEntity.findAllData(UploadEntity.class);
}
@Override public void stopAllTask() {
- List allEntity = DbEntity.findAllData(UploadEntity.class);
- List stopCmds = new ArrayList<>();
- for (UploadEntity entity : allEntity) {
- if (entity.getState() == IEntity.STATE_RUNNING) {
- stopCmds.add(
- CommonUtil.createCmd(targetName, new UploadTaskEntity(entity), CmdFactory.TASK_STOP));
- }
- }
- AriaManager.getInstance(AriaManager.APP).setCmds(stopCmds).exe();
+ AriaManager.getInstance(AriaManager.APP)
+ .setCmd(NormalCmdFactory.getInstance()
+ .createCmd(targetName, new UploadTaskEntity(), NormalCmdFactory.TASK_STOP_ALL))
+ .exe();
}
- @Override public void removeAllTask() {
+ /**
+ * 删除所有任务
+ *
+ * @param removeFile {@code true} 删除已经上传完成的任务,不仅删除上传记录,还会删除已经上传完成的文件,{@code false}
+ * 如果文件已经上传完成,只删除上传记录
+ */
+ @Override public void removeAllTask(boolean removeFile) {
final AriaManager am = AriaManager.getInstance(AriaManager.APP);
- List allEntity = DbEntity.findAllData(UploadEntity.class);
- List cancelCmds = new ArrayList<>();
- for (UploadEntity entity : allEntity) {
- cancelCmds.add(
- CommonUtil.createCmd(targetName, new UploadTaskEntity(entity), CmdFactory.TASK_CANCEL));
- }
- am.setCmds(cancelCmds).exe();
+
+ am.setCmd(CommonUtil.createCmd(targetName, new DownloadTaskEntity(),
+ NormalCmdFactory.TASK_CANCEL_ALL)).exe();
+
Set keys = am.getReceiver().keySet();
for (String key : keys) {
IReceiver receiver = am.getReceiver().get(key);
@@ -118,14 +100,19 @@ public class UploadReceiver implements IReceiver {
/**
* 添加调度器回调
+ *
+ * @see #register()
*/
- public UploadReceiver addSchedulerListener(ISchedulerListener listener) {
+ @Deprecated public UploadReceiver addSchedulerListener(ISchedulerListener listener) {
this.listener = listener;
UploadSchedulers.getInstance().addSchedulerListener(targetName, listener);
return this;
}
- @Override public void removeSchedulerListener() {
+ /**
+ * @see #unRegister()
+ */
+ @Deprecated @Override public void removeSchedulerListener() {
if (listener != null) {
UploadSchedulers.getInstance().removeSchedulerListener(targetName, listener);
}
@@ -135,11 +122,19 @@ public class UploadReceiver implements IReceiver {
* 将当前类注册到Aria
*/
public UploadReceiver register() {
- UploadSchedulers.getInstance().register(obj);
+ String className = obj.getClass().getName();
+ Set cCounter = ProxyHelper.getInstance().uploadCounter;
+ if (cCounter != null && cCounter.contains(className)) {
+ UploadSchedulers.getInstance().register(obj);
+ }
return this;
}
@Override public void unRegister() {
- UploadSchedulers.getInstance().unRegister(obj);
+ String className = obj.getClass().getName();
+ Set dCounter = ProxyHelper.getInstance().uploadCounter;
+ if (dCounter != null && dCounter.contains(className)) {
+ UploadSchedulers.getInstance().unRegister(obj);
+ }
}
}
\ No newline at end of file
diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java
index 1868d51c..dd372289 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java
@@ -16,28 +16,49 @@
package com.arialyy.aria.core.upload;
import android.support.annotation.NonNull;
-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.queue.UploadTaskQueue;
import com.arialyy.aria.orm.DbEntity;
-import java.util.Map;
+import java.util.regex.Pattern;
/**
* Created by lyy on 2017/2/28.
*/
-public class UploadTarget extends AbsTarget {
+public class UploadTarget extends AbsNormalTarget {
- UploadTarget(UploadEntity entity, String targetName) {
- this.entity = entity;
- this.targetName = targetName;
- taskEntity = new UploadTaskEntity(entity);
+ UploadTarget(String filePath, String targetName) {
+ this.mTargetName = targetName;
+ mTaskEntity = DbEntity.findFirst(UploadTaskEntity.class, "key=?", filePath);
+ if (mTaskEntity == null) {
+ mTaskEntity = new UploadTaskEntity();
+ mTaskEntity.entity = getUploadEntity(filePath);
+ }
+ if (mTaskEntity.entity == null) {
+ mTaskEntity.entity = getUploadEntity(filePath);
+ }
+ mEntity = mTaskEntity.entity;
+ }
+
+ private UploadEntity getUploadEntity(String filePath) {
+ UploadEntity entity = UploadEntity.findFirst(UploadEntity.class, "filePath=?", filePath);
+ if (entity == null) {
+ entity = new UploadEntity();
+ String regex = "[/|\\\\|//]";
+ Pattern p = Pattern.compile(regex);
+ String[] strs = p.split(filePath);
+ String fileName = strs[strs.length - 1];
+ entity.setFileName(fileName);
+ entity.setFilePath(filePath);
+ entity.insert();
+ }
+ return entity;
}
/**
* 设置userAgent
*/
public UploadTarget setUserAngent(@NonNull String userAgent) {
- taskEntity.userAgent = userAgent;
+ mTaskEntity.userAgent = userAgent;
return this;
}
@@ -47,7 +68,7 @@ public class UploadTarget extends AbsTarget {
* @param uploadUrl 上传路径
*/
public UploadTarget setUploadUrl(@NonNull String uploadUrl) {
- taskEntity.uploadUrl = uploadUrl;
+ mTaskEntity.uploadUrl = uploadUrl;
return this;
}
@@ -57,7 +78,7 @@ public class UploadTarget extends AbsTarget {
* @param attachment 附件key
*/
public UploadTarget setAttachment(@NonNull String attachment) {
- taskEntity.attachment = attachment;
+ mTaskEntity.attachment = attachment;
return this;
}
@@ -65,7 +86,7 @@ public class UploadTarget extends AbsTarget {
* 设置文件名
*/
public UploadTarget setFileName(String fileName) {
- entity.setFileName(fileName);
+ mEntity.setFileName(fileName);
return this;
}
@@ -75,28 +96,7 @@ public class UploadTarget extends AbsTarget {
* @param contentType tip:multipart/form-data
*/
public UploadTarget setContentType(String contentType) {
- taskEntity.contentType = contentType;
- return this;
- }
-
- /**
- * 给url请求添加头部
- *
- * @param key 头部key
- * @param header 头部value
- */
- public UploadTarget addHeader(@NonNull String key, @NonNull String header) {
- super._addHeader(key, header);
- return this;
- }
-
- /**
- * 给url请求添加头部
- *
- * @param headers key为http头部的key,Value为http头对应的配置
- */
- public UploadTarget addHeaders(Map headers) {
- super._addHeaders(headers);
+ mTaskEntity.contentType = contentType;
return this;
}
@@ -104,28 +104,14 @@ public class UploadTarget extends AbsTarget {
* 下载任务是否存在
*/
@Override public boolean taskExists() {
- return UploadTaskQueue.getInstance().getTask(entity.getFilePath()) != null;
- }
-
- /**
- * 设置请求类型
- *
- * @param requestEnum {@link RequestEnum}
- */
- public UploadTarget setRequestMode(RequestEnum requestEnum) {
- super._setRequestMode(requestEnum);
- return this;
- }
-
- private UploadEntity getDownloadEntity() {
- return entity;
+ return UploadTaskQueue.getInstance().getTask(mEntity.getFilePath()) != null;
}
/**
* 是否在下载
*/
public boolean isUploading() {
- UploadTask task = UploadTaskQueue.getInstance().getTask(entity);
+ UploadTask task = UploadTaskQueue.getInstance().getTask(mEntity);
return task != null && task.isRunning();
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadUtil.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadUtil.java
index 88a87caa..c0ee07d7 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadUtil.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadUtil.java
@@ -51,7 +51,7 @@ final class UploadUtil implements Runnable {
UploadUtil(UploadTaskEntity taskEntity, IUploadListener listener) {
mTaskEntity = taskEntity;
CheckUtil.checkTaskEntity(taskEntity);
- mUploadEntity = taskEntity.uploadEntity;
+ mUploadEntity = taskEntity.getEntity();
if (listener == null) {
throw new IllegalArgumentException("上传监听不能为空");
}
@@ -109,7 +109,7 @@ final class UploadUtil implements Runnable {
for (String key : keys) {
addFormField(writer, key, mTaskEntity.formFields.get(key));
}
- mListener.onStart();
+ mListener.onStart(0);
uploadFile(writer, mTaskEntity.attachment, uploadFile);
Log.d(TAG, finish(writer) + "");
} catch (IOException e) {
@@ -162,11 +162,11 @@ final class UploadUtil implements Runnable {
writer.append("Content-Disposition: form-data; name=\"")
.append(attachment)
.append("\"; filename=\"")
- .append(mTaskEntity.uploadEntity.getFileName())
+ .append(mTaskEntity.getEntity().getFileName())
.append("\"")
.append(LINE_END);
writer.append("Content-Type: ")
- .append(URLConnection.guessContentTypeFromName(mTaskEntity.uploadEntity.getFileName()))
+ .append(URLConnection.guessContentTypeFromName(mTaskEntity.getEntity().getFileName()))
.append(LINE_END);
writer.append("Content-Transfer-Encoding: binary").append(LINE_END);
writer.append(LINE_END);
diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java b/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java
index faf40925..b8178ba5 100644
--- a/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java
+++ b/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java
@@ -17,7 +17,11 @@ package com.arialyy.aria.orm;
import android.text.TextUtils;
import com.arialyy.aria.core.download.DownloadEntity;
+import com.arialyy.aria.core.download.DownloadGroupEntity;
+import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
+import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.upload.UploadEntity;
+import com.arialyy.aria.core.upload.UploadTaskEntity;
import java.util.HashMap;
import java.util.Map;
@@ -28,7 +32,7 @@ import java.util.Map;
public class DBConfig {
static Map mapping = new HashMap<>();
static String DB_NAME;
- static int VERSION = 3;
+ static int VERSION = 10;
static {
if (TextUtils.isEmpty(DB_NAME)) {
@@ -41,6 +45,10 @@ public class DBConfig {
static {
mapping.put("DownloadEntity", DownloadEntity.class);
+ mapping.put("DownloadGroupEntity", DownloadGroupEntity.class);
+ mapping.put("DownloadTaskEntity", DownloadTaskEntity.class);
+ mapping.put("DownloadGroupTaskEntity", DownloadGroupTaskEntity.class);
mapping.put("UploadEntity", UploadEntity.class);
+ mapping.put("UploadTaskEntity", UploadTaskEntity.class);
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java b/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java
index fc42e75c..f872e5d2 100644
--- a/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java
+++ b/Aria/src/main/java/com/arialyy/aria/orm/DbEntity.java
@@ -19,8 +19,10 @@ package com.arialyy.aria.orm;
import android.support.annotation.NonNull;
import com.arialyy.aria.util.CommonUtil;
import java.lang.reflect.Field;
+import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
/**
* Created by lyy on 2015/11/2.
@@ -34,6 +36,13 @@ public class DbEntity {
}
+ /**
+ * 直接执行sql语句
+ */
+ public static void exeSql(String sql) {
+ DbUtil.getInstance().exeSql(sql);
+ }
+
/**
* 查询所有数据
*
@@ -55,7 +64,7 @@ public class DbEntity {
/**
* 查询一组数据
*
- * DownloadEntity.findData(DownloadEntity.class, "downloadUrl=?", downloadUrl);
+ * DownloadEntity.findFirst(DownloadEntity.class, "downloadUrl=?", downloadUrl);
*
*
* @return 没有数据返回null
@@ -68,12 +77,12 @@ public class DbEntity {
/**
* 查询一行数据
*
- * DownloadEntity.findData(DownloadEntity.class, "downloadUrl=?", downloadUrl);
+ * DownloadEntity.findFirst(DownloadEntity.class, "downloadUrl=?", downloadUrl);
*
*
* @return 没有数据返回null
*/
- public static T findData(Class clazz, String... expression) {
+ public static T findFirst(Class clazz, String... expression) {
DbUtil util = DbUtil.getInstance();
List datas = util.findData(clazz, expression);
return datas == null ? null : datas.size() > 0 ? datas.get(0) : null;
@@ -97,7 +106,6 @@ public class DbEntity {
* 删除当前数据
*/
public void deleteData() {
- //mUtil.delData(getClass(), new Object[] { "rowid" }, new Object[] { rowID });
deleteData(getClass(), "rowid=?", rowID + "");
}
@@ -124,7 +132,7 @@ public class DbEntity {
*/
public void save() {
synchronized (LOCK) {
- if (DbUtil.getInstance().tableExists(getClass()) && thisIsExist()) {
+ if (thisIsExist()) {
update();
} else {
insert();
@@ -136,7 +144,8 @@ public class DbEntity {
* 查找数据在表中是否存在
*/
private boolean thisIsExist() {
- return findData(getClass(), "rowid=?", rowID + "") != null;
+ DbUtil util = DbUtil.getInstance();
+ return util.isExist(getClass(), rowID);
}
/**
@@ -147,7 +156,7 @@ public class DbEntity {
updateRowID();
}
- private T findData(Class clazz, @NonNull String[] wheres,
+ private T findFirst(Class clazz, @NonNull String[] wheres,
@NonNull String[] values) {
DbUtil util = DbUtil.getInstance();
List list = util.findData(clazz, wheres, values);
@@ -156,7 +165,7 @@ public class DbEntity {
private void updateRowID() {
try {
- Field[] fields = CommonUtil.getFields(getClass());
+ List fields = CommonUtil.getAllFields(getClass());
List where = new ArrayList<>();
List values = new ArrayList<>();
for (Field field : fields) {
@@ -165,9 +174,22 @@ public class DbEntity {
continue;
}
where.add(field.getName());
- values.add(field.get(this) + "");
+ Type type = field.getType();
+ if (SqlHelper.isOneToOne(field)) {
+ values.add(SqlHelper.getOneToOneParams(field));
+ } else if (type == List.class) {
+ if (SqlHelper.isOneToMany(field)) {
+ values.add(SqlHelper.getOneToManyElementParams(field));
+ } else {
+ values.add(SqlHelper.list2Str(this, field));
+ }
+ } else if (type == Map.class) {
+ values.add(SqlHelper.map2Str((Map) field.get(this)));
+ } else {
+ values.add(field.get(this) + "");
+ }
}
- DbEntity entity = findData(getClass(), where.toArray(new String[where.size()]),
+ DbEntity entity = findFirst(getClass(), where.toArray(new String[where.size()]),
values.toArray(new String[values.size()]));
if (entity != null) {
rowID = entity.rowID;
diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DbUtil.java b/Aria/src/main/java/com/arialyy/aria/orm/DbUtil.java
index e02fd7d4..32cf7b03 100644
--- a/Aria/src/main/java/com/arialyy/aria/orm/DbUtil.java
+++ b/Aria/src/main/java/com/arialyy/aria/orm/DbUtil.java
@@ -64,6 +64,13 @@ public class DbUtil {
return INSTANCE;
}
+ /**
+ * 执行sql语句
+ */
+ void exeSql(String sql) {
+ mDb.execSQL(sql);
+ }
+
/**
* 删除某条数据
*/
@@ -97,6 +104,18 @@ public class DbUtil {
return SqlHelper.findData(mDb, clazz, expression);
}
+ /**
+ * 通过rowId判断数据是否存在
+ */
+ synchronized boolean isExist(Class clazz, int rowId) {
+ checkDb();
+ String sql = "SELECT rowid FROM " + CommonUtil.getClassName(clazz) + " WHERE rowid=" + rowId;
+ Cursor cursor = mDb.rawQuery(sql, null);
+ boolean isExist = cursor.getCount() > 0;
+ cursor.close();
+ return isExist;
+ }
+
/**
* 条件查寻数据
*/
@@ -127,7 +146,7 @@ public class DbUtil {
SqlHelper.createTable(mDb, clazz, tableName);
}
- private void checkDb(){
+ private void checkDb() {
if (mDb == null || !mDb.isOpen()) {
mDb = mHelper.getReadableDatabase();
}
@@ -175,7 +194,7 @@ public class DbUtil {
Log.e(TAG, "请输入删除条件");
return -1;
} else if (wheres.length != values.length) {
- Log.e(TAG, "key 和 vaule 长度不相等");
+ Log.e(TAG, "groupName 和 vaule 长度不相等");
return -1;
}
StringBuilder sb = new StringBuilder();
diff --git a/Aria/src/main/java/com/arialyy/aria/orm/NormalList.java b/Aria/src/main/java/com/arialyy/aria/orm/NormalList.java
new file mode 100644
index 00000000..2d2ba512
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/orm/NormalList.java
@@ -0,0 +1,32 @@
+/*
+ * 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.orm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by AriaL on 2017/7/4.
+ * 基本类型的List,只能用于常见的数据类型,如果是一对多的复杂数据结构,需要使用{@link OneToMany}
+ */
+@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface NormalList {
+ /**
+ * 数据类型
+ */
+ Class clazz();
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/orm/OneToMany.java b/Aria/src/main/java/com/arialyy/aria/orm/OneToMany.java
new file mode 100644
index 00000000..8f529e1b
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/orm/OneToMany.java
@@ -0,0 +1,36 @@
+/*
+ * 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.orm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by AriaL on 2017/7/4.
+ * 一对多
+ */
+@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface OneToMany {
+ /**
+ * 关联的表
+ */
+ Class extends DbEntity> table();
+ /**
+ * 关联的主键
+ */
+ String key();
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/orm/OneToOne.java b/Aria/src/main/java/com/arialyy/aria/orm/OneToOne.java
new file mode 100644
index 00000000..7641fd55
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/orm/OneToOne.java
@@ -0,0 +1,38 @@
+/*
+ * 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.orm;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by AriaL on 2017/7/4.
+ * 一对一
+ */
+@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface OneToOne {
+
+ /**
+ * 关联的表
+ */
+ Class extends DbEntity> table();
+
+ /**
+ * 关联的主键
+ */
+ String key();
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/orm/Id.java b/Aria/src/main/java/com/arialyy/aria/orm/Primary.java
similarity index 97%
rename from Aria/src/main/java/com/arialyy/aria/orm/Id.java
rename to Aria/src/main/java/com/arialyy/aria/orm/Primary.java
index a59b85d9..365f1713 100644
--- a/Aria/src/main/java/com/arialyy/aria/orm/Id.java
+++ b/Aria/src/main/java/com/arialyy/aria/orm/Primary.java
@@ -25,6 +25,6 @@ import java.lang.annotation.Target;
* Created by lyy on 2015/11/2.
* 表ID字段指定
*/
-@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Id {
+@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Primary {
int value() default -1;
}
\ No newline at end of file
diff --git a/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java b/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java
index 784900b1..2cdc017d 100644
--- a/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java
+++ b/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java
@@ -28,9 +28,13 @@ import com.arialyy.aria.util.CheckUtil;
import com.arialyy.aria.util.CommonUtil;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
/**
@@ -186,11 +190,26 @@ final class SqlHelper extends SQLiteOpenHelper {
sql = String.format(sql, params);
print(FIND_DATA, sql);
Cursor cursor = db.rawQuery(sql, null);
- List data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null;
+ List data = cursor.getCount() > 0 ? newInstanceEntity(db, clazz, cursor) : null;
+ cursor.close();
close(db);
return data;
}
+ /**
+ * 条件查寻数据
+ */
+ static synchronized List findData(SQLiteDatabase db, String tableName,
+ String... expression) {
+ Class clazz = null;
+ try {
+ clazz = (Class) Class.forName(tableName);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ return findData(db, clazz, expression);
+ }
+
/**
* 条件查寻数据
*/
@@ -201,7 +220,7 @@ final class SqlHelper extends SQLiteOpenHelper {
Log.e(TAG, "请输入查询条件");
return null;
} else if (wheres.length != values.length) {
- Log.e(TAG, "key 和 vaule 长度不相等");
+ Log.e(TAG, "groupName 和 vaule 长度不相等");
return null;
}
StringBuilder sb = new StringBuilder();
@@ -214,7 +233,8 @@ final class SqlHelper extends SQLiteOpenHelper {
}
print(FIND_DATA, sb.toString());
Cursor cursor = db.rawQuery(sb.toString(), null);
- List data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null;
+ List data = cursor.getCount() > 0 ? newInstanceEntity(db, clazz, cursor) : null;
+ cursor.close();
close(db);
return data;
}
@@ -228,7 +248,8 @@ final class SqlHelper extends SQLiteOpenHelper {
sb.append("SELECT rowid, * FROM ").append(CommonUtil.getClassName(clazz));
print(FIND_ALL_DATA, sb.toString());
Cursor cursor = db.rawQuery(sb.toString(), null);
- List data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null;
+ List data = cursor.getCount() > 0 ? newInstanceEntity(db, clazz, cursor) : null;
+ cursor.close();
close(db);
return data;
}
@@ -270,11 +291,26 @@ final class SqlHelper extends SQLiteOpenHelper {
}
sb.append(i > 0 ? ", " : "");
try {
- Object value = field.get(dbEntity);
- sb.append(field.getName())
- .append("='")
- .append(value == null ? "" : value.toString())
- .append("'");
+ String value;
+ sb.append(field.getName()).append("='");
+ Type type = field.getType();
+ if (type == Map.class) {
+ value = map2Str((Map) field.get(dbEntity));
+ } else if (type == List.class) {
+ if (isOneToMany(field)) {
+ value = getOneToManyElementParams(field);
+ } else {
+ value = list2Str(dbEntity, field);
+ }
+ } else if (isOneToOne(field)) {
+ value = getOneToOneParams(field);
+ } else {
+ Object obj = field.get(dbEntity);
+ value = obj == null ? "" : obj.toString();
+ }
+
+ sb.append(value == null ? "" : value);
+ sb.append("'");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
@@ -304,24 +340,39 @@ final class SqlHelper extends SQLiteOpenHelper {
continue;
}
sb.append(i > 0 ? ", " : "");
+ //sb.append(getFieldName(field.getType(), field));
sb.append(field.getName());
i++;
}
sb.append(") VALUES (");
i = 0;
- for (Field field : fields) {
- field.setAccessible(true);
- if (ignoreField(field)) {
- continue;
- }
- sb.append(i > 0 ? ", " : "");
- sb.append("'");
- try {
- sb.append(field.get(dbEntity)).append("'");
- } catch (IllegalAccessException e) {
- e.printStackTrace();
+ try {
+ for (Field field : fields) {
+ field.setAccessible(true);
+ if (ignoreField(field)) {
+ continue;
+ }
+ sb.append(i > 0 ? ", " : "");
+ sb.append("'");
+ Type type = field.getType();
+ if (type == Map.class) {
+ sb.append(map2Str((Map) field.get(dbEntity)));
+ } else if (type == List.class) {
+ if (isOneToMany(field)) {
+ sb.append(getOneToManyElementParams(field));
+ } else {
+ sb.append(list2Str(dbEntity, field));
+ }
+ } else if (isOneToOne(field)) {
+ sb.append(getOneToOneParams(field));
+ } else {
+ sb.append(field.get(dbEntity));
+ }
+ sb.append("'");
+ i++;
}
- i++;
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
}
sb.append(")");
print(INSERT_DATA, sb.toString());
@@ -330,6 +381,104 @@ final class SqlHelper extends SQLiteOpenHelper {
close(db);
}
+ /**
+ * 获取一对一参数
+ */
+ static String getOneToOneParams(Field field) {
+ OneToOne oneToOne = field.getAnnotation(OneToOne.class);
+ if (oneToOne == null) {
+ throw new IllegalArgumentException("@OneToOne注解的对象必须要有@Primary注解的字段");
+ }
+ return oneToOne.table().getName() + "$$" + oneToOne.key();
+ }
+
+ /**
+ * 获取List一对多参数
+ *
+ * @param field list反射字段
+ */
+ static String getOneToManyElementParams(Field field) {
+ OneToMany oneToMany = field.getAnnotation(OneToMany.class);
+ if (oneToMany == null) {
+ throw new IllegalArgumentException("一对多元素必须被@OneToMany注解");
+ }
+ //关联的表名
+ String tableName = oneToMany.table().getName();
+ //关联的字段
+ String key = oneToMany.key();
+ return tableName + "$$" + key;
+ }
+
+ /**
+ * 列表数据转字符串
+ *
+ * @param field list反射字段
+ */
+ static String list2Str(DbEntity dbEntity, Field field) throws IllegalAccessException {
+ NormalList normalList = field.getAnnotation(NormalList.class);
+ if (normalList == null) {
+ throw new IllegalArgumentException("List中元素必须被@NormalList注解");
+ }
+ List list = (List) field.get(dbEntity);
+ if (list == null || list.isEmpty()) return "";
+ StringBuilder sb = new StringBuilder();
+ for (Object aList : list) {
+ sb.append(aList).append("$$");
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 字符串转列表
+ *
+ * @param str 数据库中的字段
+ * @return 如果str为null,则返回null
+ */
+ private static List str2List(String str, Field field) {
+ NormalList normalList = field.getAnnotation(NormalList.class);
+ if (normalList == null) {
+ throw new IllegalArgumentException("List中元素必须被@NormalList注解");
+ }
+ if (TextUtils.isEmpty(str)) return null;
+ String[] datas = str.split("$$");
+ List list = new ArrayList();
+ String type = normalList.clazz().getName();
+ for (String data : datas) {
+ list.add(checkData(data, type));
+ }
+ return list;
+ }
+
+ private static Object checkData(String type, String data) {
+ switch (type) {
+ case "String":
+ return data;
+ case "int":
+ case "Integer":
+ return Integer.parseInt(data);
+ case "double":
+ case "Double":
+ return Double.parseDouble(data);
+ case "float":
+ case "Float":
+ return Float.parseFloat(data);
+ }
+ return null;
+ }
+
+ /**
+ * 查找class的主键字段
+ *
+ * @return 返回主键字段名
+ */
+ private static String getPrimaryName(Class extends DbEntity> clazz) {
+ List fields = CommonUtil.getAllFields(clazz);
+ for (Field field : fields) {
+ if (isPrimary(field)) return field.getName();
+ }
+ return null;
+ }
+
/**
* 查找表是否存在
*
@@ -380,9 +529,13 @@ final class SqlHelper extends SQLiteOpenHelper {
if (ignoreField(field)) {
continue;
}
- sb.append(field.getName());
Class> type = field.getType();
- if (type == String.class) {
+ sb.append(field.getName());
+ if (type == String.class
+ || type == Map.class
+ || type == List.class
+ || isOneToOne(field)
+ || type.isEnum()) {
sb.append(" varchar");
} else if (type == int.class || type == Integer.class) {
sb.append(" interger");
@@ -401,6 +554,10 @@ final class SqlHelper extends SQLiteOpenHelper {
} else {
continue;
}
+ if (isPrimary(field)) {
+ //sb.append(" PRIMARY KEY");
+ sb.append(" NOT NULL");
+ }
sb.append(",");
}
String str = sb.toString();
@@ -447,8 +604,8 @@ final class SqlHelper extends SQLiteOpenHelper {
/**
* 根据数据游标创建一个具体的对象
*/
- static synchronized List newInstanceEntity(Class clazz,
- Cursor cursor) {
+ private static synchronized List newInstanceEntity(SQLiteDatabase db,
+ Class clazz, Cursor cursor) {
List fields = CommonUtil.getAllFields(clazz);
List entitys = new ArrayList<>();
if (fields != null && fields.size() > 0) {
@@ -479,8 +636,39 @@ final class SqlHelper extends SQLiteOpenHelper {
field.set(entity, new Date(cursor.getString(column)));
} else if (type == byte[].class) {
field.set(entity, cursor.getBlob(column));
- } else {
- continue;
+ } else if (type == Map.class) {
+ field.set(entity, str2Map(cursor.getString(column)));
+ } else if (type == List.class) {
+ String value = cursor.getString(column);
+ if (isOneToMany(field)) {
+ //主键字段
+ String primaryKey = getPrimaryName(clazz);
+ if (TextUtils.isEmpty(primaryKey)) {
+ throw new IllegalArgumentException("List中的元素对象必须需要@Primary注解的字段");
+ }
+ //list字段保存的数据
+ int kc = cursor.getColumnIndex(primaryKey);
+ String primaryData = cursor.getString(kc);
+ if (TextUtils.isEmpty(primaryData)) continue;
+ List list = findForeignData(db, primaryData, value);
+ if (list == null) continue;
+ field.set(entity, findForeignData(db, primaryData, value));
+ } else {
+ field.set(entity, str2List(value, field));
+ }
+ } else if (isOneToOne(field)) {
+ String primaryKey = getPrimaryName(clazz);
+ if (TextUtils.isEmpty(primaryKey)) {
+ throw new IllegalArgumentException("@OneToOne的注解对象必须需要@Primary注解的字段");
+ }
+ int kc = cursor.getColumnIndex(primaryKey);
+ String params = cursor.getString(column);
+ String primaryData = cursor.getString(kc);
+ if (TextUtils.isEmpty(primaryData) || primaryData.equalsIgnoreCase("null")) continue;
+ List list = findForeignData(db, primaryData, params);
+ if (list != null && list.size() > 0) {
+ field.set(entity, list.get(0));
+ }
}
}
entity.rowID = cursor.getInt(cursor.getColumnIndex("rowid"));
@@ -496,6 +684,53 @@ final class SqlHelper extends SQLiteOpenHelper {
return entitys;
}
+ /**
+ * 查找一对多、一对一的关联数据
+ *
+ * @param primary 当前表的主键
+ * @param childParams 当前表关联数据的类名 $$ 主键名
+ */
+ private static List findForeignData(SQLiteDatabase db, String primary,
+ String childParams) {
+ String[] params = childParams.split("\\$\\$");
+ return findData(db, params[0], params[1] + "=?", primary);
+ }
+
+ /**
+ * 字符串转Map,只支持
+ *
+ * {@code Map}
+ *
+ */
+ private static Map str2Map(String str) {
+ Map map = new HashMap<>();
+ if (TextUtils.isEmpty(str)) {
+ return map;
+ }
+ String[] element = str.split(",");
+ for (String data : element) {
+ String[] s = data.split("\\$");
+ map.put(s[0], s[1]);
+ }
+ return map;
+ }
+
+ /**
+ * Map转字符串,只支持
+ *
+ * {@code Map}
+ *
+ */
+ static String map2Str(Map map) {
+ StringBuilder sb = new StringBuilder();
+ Set keys = map.keySet();
+ for (String key : keys) {
+ sb.append(key).append("$").append(map.get(key)).append(",");
+ }
+ String str = sb.toString();
+ return TextUtils.isEmpty(str) ? str : str.substring(0, str.length() - 1);
+ }
+
private static void close(SQLiteDatabase db) {
//if (db != null && db.isOpen()) db.close();
}
@@ -511,7 +746,7 @@ final class SqlHelper extends SQLiteOpenHelper {
* @return true 忽略该字段
*/
static boolean ignoreField(Field field) {
- // field.isSynthetic(), 使用as热启动App时,AS会自动给你的clss添加change字段
+ // field.isSynthetic(), 使用as热启动App时,AS会自动给你的class添加change字段
Ignore ignore = field.getAnnotation(Ignore.class);
int modifiers = field.getModifiers();
return (ignore != null && ignore.value())
@@ -520,4 +755,28 @@ final class SqlHelper extends SQLiteOpenHelper {
|| Modifier.isStatic(modifiers)
|| Modifier.isFinal(modifiers);
}
+
+ /**
+ * 判断是否一对多注解
+ */
+ static boolean isOneToMany(Field field) {
+ OneToMany oneToMany = field.getAnnotation(OneToMany.class);
+ return oneToMany != null;
+ }
+
+ /**
+ * 判断是否是一对一注解
+ */
+ static boolean isOneToOne(Field field) {
+ OneToOne oneToOne = field.getAnnotation(OneToOne.class);
+ return oneToOne != null;
+ }
+
+ /**
+ * 判断是否是主键
+ */
+ static boolean isPrimary(Field field) {
+ Primary pk = field.getAnnotation(Primary.class);
+ return pk != null;
+ }
}
\ No newline at end of file
diff --git a/Aria/src/main/java/com/arialyy/aria/util/CheckUtil.java b/Aria/src/main/java/com/arialyy/aria/util/CheckUtil.java
index c083c46e..34c54227 100644
--- a/Aria/src/main/java/com/arialyy/aria/util/CheckUtil.java
+++ b/Aria/src/main/java/com/arialyy/aria/util/CheckUtil.java
@@ -24,6 +24,7 @@ import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTaskEntity;
import com.arialyy.aria.exception.FileException;
+import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -76,6 +77,24 @@ public class CheckUtil {
if (TextUtils.isEmpty(downloadUrl)) throw new IllegalArgumentException("下载链接不能为null");
}
+ /**
+ * 检测下载链接组是否为null
+ */
+ public static void checkDownloadUrls(List urls) {
+ if (urls == null || urls.isEmpty()) {
+ throw new IllegalArgumentException("链接组不能为null");
+ }
+ }
+
+ /**
+ * 检查下载任务组保存路径
+ */
+ public static void checkDownloadPaths(List paths) {
+ if (paths == null || paths.isEmpty()) {
+ throw new IllegalArgumentException("链接保存路径不能为null");
+ }
+ }
+
/**
* 检测上传地址是否为null
*/
@@ -88,9 +107,9 @@ public class CheckUtil {
*/
public static void checkTaskEntity(AbsTaskEntity entity) {
if (entity instanceof DownloadTaskEntity) {
- checkDownloadTaskEntity(((DownloadTaskEntity) entity).downloadEntity);
+ checkDownloadTaskEntity(((DownloadTaskEntity) entity).getEntity());
} else if (entity instanceof UploadTaskEntity) {
- checkUploadTaskEntity(((UploadTaskEntity) entity).uploadEntity);
+ checkUploadTaskEntity(((UploadTaskEntity) entity).getEntity());
}
}
@@ -103,7 +122,7 @@ public class CheckUtil {
public static boolean checkCmdEntity(AbsTaskEntity entity, boolean checkType) {
boolean b = false;
if (entity instanceof DownloadTaskEntity) {
- DownloadEntity entity1 = ((DownloadTaskEntity) entity).downloadEntity;
+ DownloadEntity entity1 = ((DownloadTaskEntity) entity).getEntity();
if (entity1 == null) {
Log.e(TAG, "下载实体不能为空");
} else if (checkType && TextUtils.isEmpty(entity1.getDownloadUrl())) {
@@ -114,7 +133,7 @@ public class CheckUtil {
b = true;
}
} else if (entity instanceof UploadTaskEntity) {
- UploadEntity entity1 = ((UploadTaskEntity) entity).uploadEntity;
+ UploadEntity entity1 = ((UploadTaskEntity) entity).getEntity();
if (entity1 == null) {
Log.e(TAG, "上传实体不能为空");
} else if (TextUtils.isEmpty(entity1.getFilePath())) {
diff --git a/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java b/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java
index 28d447ad..b4d6db90 100644
--- a/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java
+++ b/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java
@@ -22,9 +22,14 @@ import android.content.SharedPreferences;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
-import com.arialyy.aria.core.command.CmdFactory;
-import com.arialyy.aria.core.command.AbsCmd;
+import com.arialyy.aria.core.AriaManager;
+import com.arialyy.aria.core.command.normal.NormalCmdFactory;
+import com.arialyy.aria.core.command.normal.AbsNormalCmd;
+import com.arialyy.aria.core.download.DownloadEntity;
+import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
+import com.arialyy.aria.core.upload.UploadEntity;
+import com.arialyy.aria.core.upload.UploadTaskEntity;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
@@ -42,6 +47,11 @@ import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.regex.Pattern;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
/**
* Created by lyy on 2016/1/22.
@@ -49,10 +59,140 @@ import java.util.regex.Pattern;
public class CommonUtil {
private static final String TAG = "CommonUtil";
+ /**
+ * 实例化泛型的实际类型参数
+ *
+ * @throws Exception
+ */
+ public static void typeCheck(Type type) throws Exception {
+ System.out.println("该类型是" + type);
+ // 参数化类型
+ if (type instanceof ParameterizedType) {
+ Type[] typeArguments = ((ParameterizedType) type).getActualTypeArguments();
+ for (int i = 0; i < typeArguments.length; i++) {
+ // 类型变量
+ if (typeArguments[i] instanceof TypeVariable) {
+ System.out.println("第" + (i + 1) + "个泛型参数类型是类型变量" + typeArguments[i] + ",无法实例化。");
+ }
+ // 通配符表达式
+ else if (typeArguments[i] instanceof WildcardType) {
+ System.out.println("第" + (i + 1) + "个泛型参数类型是通配符表达式" + typeArguments[i] + ",无法实例化。");
+ }
+ // 泛型的实际类型,即实际存在的类型
+ else if (typeArguments[i] instanceof Class) {
+ System.out.println("第" + (i + 1) + "个泛型参数类型是:" + typeArguments[i] + ",可以直接实例化对象");
+ }
+ }
+ // 参数化类型数组或类型变量数组
+ } else if (type instanceof GenericArrayType) {
+ System.out.println("该泛型类型是参数化类型数组或类型变量数组,可以获取其原始类型。");
+ Type componentType = ((GenericArrayType) type).getGenericComponentType();
+ // 类型变量
+ if (componentType instanceof TypeVariable) {
+ System.out.println("该类型变量数组的原始类型是类型变量" + componentType + ",无法实例化。");
+ }
+ // 参数化类型,参数化类型数组或类型变量数组
+ // 参数化类型数组或类型变量数组也可以是多维的数组,getGenericComponentType()方法仅仅是去掉最右边的[]
+ else {
+ // 递归调用方法自身
+ typeCheck(componentType);
+ }
+ } else if (type instanceof TypeVariable) {
+ System.out.println("该类型是类型变量");
+ } else if (type instanceof WildcardType) {
+ System.out.println("该类型是通配符表达式");
+ } else if (type instanceof Class) {
+ System.out.println("该类型不是泛型类型");
+ } else {
+ throw new Exception();
+ }
+ }
+
+ /**
+ * 根据下载任务组的url创建key
+ *
+ * @return urls 为 null 或者 size为0,返回""
+ */
+ public static String getMd5Code(List urls) {
+ if (urls == null || urls.size() < 1) return "";
+ String md5 = "";
+ StringBuilder sb = new StringBuilder();
+ for (String url : urls) {
+ sb.append(url);
+ }
+ try {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ md.update(sb.toString().getBytes());
+ md5 = new BigInteger(1, md.digest()).toString(16);
+ } catch (NoSuchAlgorithmException e) {
+ Log.e(TAG, e.getMessage());
+ }
+ return md5;
+ }
+
+ /**
+ * 删除上传任务的配置,包括
+ *
+ * @param removeFile {@code true} 不仅删除任务数据库记录,还会删除已经下载完成的文件
+ * {@code false}如果任务已经完成,只删除任务数据库记录
+ */
+ public static void delUploadTaskConfig(boolean removeFile, UploadTaskEntity tEntity) {
+ UploadEntity uEntity = tEntity.getEntity();
+ File file = new File(uEntity.getFilePath());
+ if (removeFile) {
+ if (file.exists()) {
+ file.delete();
+ }
+ } else {
+ if (!uEntity.isComplete()) {
+ if (file.exists()) {
+ file.delete();
+ }
+ }
+ }
+ File config = new File(
+ AriaManager.APP.getFilesDir().getPath() + "/temp/" + uEntity.getFileName() + ".properties");
+ if (config.exists()) {
+ config.delete();
+ }
+ uEntity.deleteData();
+ tEntity.deleteData();
+ }
+
+ /**
+ * 删除下载任务的配置,包括
+ *
+ * @param removeFile {@code true} 不仅删除任务数据库记录,还会删除已经下载完成的文件
+ * {@code false}如果任务已经完成,只删除任务数据库记录
+ */
+ public static void delDownloadTaskConfig(boolean removeFile, DownloadTaskEntity tEntity) {
+ DownloadEntity dEntity = tEntity.getEntity();
+ File file = new File(dEntity.getDownloadPath());
+ if (removeFile) {
+ if (file.exists()) {
+ file.delete();
+ }
+ } else {
+ if (!dEntity.isComplete()) {
+ if (file.exists()) {
+ file.delete();
+ }
+ }
+ }
+
+ File config = new File(
+ AriaManager.APP.getFilesDir().getPath() + "/temp/" + dEntity.getFileName() + ".properties");
+ if (config.exists()) {
+ config.delete();
+ }
+ dEntity.deleteData();
+ tEntity.deleteData();
+ }
+
/**
* 获取CPU核心数
*/
- public static int getNumCores() {
+ public static int getCoresNum() {
//Private Class to display only CPU devices in the directory listing
class CpuFilter implements FileFilter {
@Override public boolean accept(File pathname) {
@@ -180,8 +320,8 @@ public class CommonUtil {
}
}
- public static AbsCmd createCmd(String target, T entity, int cmd) {
- return CmdFactory.getInstance().createCmd(target, entity, cmd);
+ public static AbsNormalCmd createCmd(String target, T entity, int cmd) {
+ return NormalCmdFactory.getInstance().createCmd(target, entity, cmd);
}
/**
@@ -230,6 +370,10 @@ public class CommonUtil {
List fields = new ArrayList<>();
Class personClazz = clazz.getSuperclass();
if (personClazz != null) {
+ Class rootClazz = personClazz.getSuperclass();
+ if (rootClazz != null) {
+ Collections.addAll(fields, rootClazz.getDeclaredFields());
+ }
Collections.addAll(fields, personClazz.getDeclaredFields());
}
Collections.addAll(fields, clazz.getDeclaredFields());
@@ -397,9 +541,11 @@ public class CommonUtil {
}
/**
- * 创建文件 当文件不存在的时候就创建一个文件,否则直接返回文件
+ * 创建文件
+ * 当文件不存在的时候就创建一个文件。
+ * 如果文件存在,先删除原文件,然后重新创建一个新文件
*/
- public static File createFile(String path) {
+ public static void createFile(String path) {
File file = new File(path);
if (!file.getParentFile().exists()) {
Log.d(TAG, "目标文件所在路径不存在,准备创建……");
@@ -408,19 +554,18 @@ public class CommonUtil {
}
}
// 创建目标文件
+ if (file.exists()) {
+ final File to = new File(file.getAbsolutePath() + System.currentTimeMillis());
+ file.renameTo(to);
+ to.delete();
+ }
try {
- if (!file.exists()) {
- if (file.createNewFile()) {
- Log.d(TAG, "创建文件成功:" + file.getAbsolutePath());
- }
- return file;
- } else {
- return file;
+ if (file.createNewFile()) {
+ Log.d(TAG, "创建文件成功:" + file.getAbsolutePath());
}
} catch (IOException e) {
e.printStackTrace();
}
- return null;
}
/**
diff --git a/Aria/src/main/res/layout/activity_aria_file_shange.xml b/Aria/src/main/res/layout/activity_aria_file_shange.xml
deleted file mode 100644
index fd652062..00000000
--- a/Aria/src/main/res/layout/activity_aria_file_shange.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Aria/src/main/res/layout/item_file.xml b/Aria/src/main/res/layout/item_file.xml
deleted file mode 100644
index 7f4c8044..00000000
--- a/Aria/src/main/res/layout/item_file.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Aria/src/main/res/values/strings.xml b/Aria/src/main/res/values/strings.xml
deleted file mode 100644
index 010e9981..00000000
--- a/Aria/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
- Aria
-
- 下载实体不能为空
- 下载链接不能为空
- 存储地址不能为空
- 文件名不能为空
-
diff --git a/AriaAnnotations/build.gradle b/AriaAnnotations/build.gradle
index 0b581ad5..a9f2139b 100644
--- a/AriaAnnotations/build.gradle
+++ b/AriaAnnotations/build.gradle
@@ -11,4 +11,4 @@ dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
-//apply from: 'bintray-release.gradle'
\ No newline at end of file
+apply from: 'bintray-release.gradle'
\ No newline at end of file
diff --git a/AriaAnnotations/src/main/java/com/arialyy/annotations/AriaConstance.java b/AriaAnnotations/src/main/java/com/arialyy/annotations/AriaConstance.java
index 3fd7e89a..0481539a 100644
--- a/AriaAnnotations/src/main/java/com/arialyy/annotations/AriaConstance.java
+++ b/AriaAnnotations/src/main/java/com/arialyy/annotations/AriaConstance.java
@@ -21,5 +21,25 @@ package com.arialyy.annotations;
public interface AriaConstance {
String NO_URL = "";
+
+ /**
+ * 注解方法为普通任务下载
+ */
+ int DOWNLOAD = 0xa1;
+
+ /**
+ * 注解方法为任务组下载
+ */
+ int DOWNLOAD_GROUP = 0xa2;
+
+ /**
+ * 注解方法为普通任务上传
+ */
+ int UPLOAD = 0xb1;
+
+ /**
+ * 注解方法为任务组上传
+ */
+ int UPLOAD_GROUP = 0xb2;
}
diff --git a/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java b/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java
index 86df2895..41110643 100644
--- a/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java
+++ b/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java
@@ -38,63 +38,63 @@ import java.lang.annotation.Target;
/**
* 如果你在方法中添加{@code @Download.onPre}注解,在预处理完成时,Aria会调用该方法
*/
- @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onPre {
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onPre {
String[] value() default { AriaConstance.NO_URL };
}
/**
* 如果你在方法中添加{@code @Download.onTaskPre}注解,在任务预处理完成时,Aria会调用该方法
*/
- @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskPre {
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskPre {
String[] value() default { AriaConstance.NO_URL };
}
/**
* 如果你在方法中添加{@code @Download.onTaskResume}注解,在任务恢复下载时,Aria会调用该方法
*/
- @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskResume {
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskResume {
String[] value() default { AriaConstance.NO_URL };
}
/**
* 如果你在方法中添加{@code @Download.onTaskStart}注解,在任务开始下载时,Aria会调用该方法
*/
- @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskStart {
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskStart {
String[] value() default { AriaConstance.NO_URL };
}
/**
* 如果你在方法中添加{@code @Download.onTaskStop}注解,在任务停止时,Aria会调用该方法
*/
- @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskStop {
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskStop {
String[] value() default { AriaConstance.NO_URL };
}
/**
* 如果你在方法中添加{@code @Download.onTaskCancel}l注解,在任务取消时,Aria会调用该方法
*/
- @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskCancel {
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskCancel {
String[] value() default { AriaConstance.NO_URL };
}
/**
* 如果你在方法中添加{@code @Download.onTaskFail)注解,在任务预失败时,Aria会调用该方法
*/
- @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskFail {
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskFail {
String[] value() default { AriaConstance.NO_URL };
}
/**
* 如果你在方法中添加{@code @Download.onTaskComplete}注解,在任务完成时,Aria会调用该方法
*/
- @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskComplete {
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskComplete {
String[] value() default { AriaConstance.NO_URL };
}
/**
* 如果你在方法中添加{@code @Download.onTaskRunning}注解,在任务正在下载,Aria会调用该方法
*/
- @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskRunning {
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskRunning {
String[] value() default { AriaConstance.NO_URL };
}
@@ -102,7 +102,7 @@ import java.lang.annotation.Target;
* 如果你在方法中添加{@code @Download.onNoSupportBreakPoint}注解,如果该任务不支持断点,Aria会调用该方法
*/
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD)
- public @interface onNoSupportBreakPoint {
+ @interface onNoSupportBreakPoint {
String[] value() default { AriaConstance.NO_URL };
}
}
diff --git a/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java b/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java
new file mode 100644
index 00000000..c0777d82
--- /dev/null
+++ b/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java
@@ -0,0 +1,99 @@
+/*
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Created by Aria.Lao on 2017/6/6.
+ * Aria下载事件被注解的方法中,参数仅能有一个,参数类型为{@link com.arialyy.aria.core.download.DownloadGroupTask}
+ *
+ *
+ * {@literal @}Download.onPre(groupName)
+ * protected void onPre(DownloadGroupTask task) {
+ * }
+ *
+ *
+ * {@literal @}Download.onPre("myGroupName"),如果你的注解中增加了url描述,
+ * 则表示,所有下载任务中,只有下载地址为"myGroupName"的任务才能回调该注解的方法。
+ */
+@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface DownloadGroup {
+ /**
+ * 如果你在方法中添加{@code @Download.onPre}注解,在预处理完成时,Aria会调用该方法
+ */
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onPre {
+ String[] value() default { AriaConstance.NO_URL };
+ }
+
+ /**
+ * 如果你在方法中添加{@code @Download.onTaskPre}注解,在任务预处理完成时,Aria会调用该方法
+ */
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskPre {
+ String[] value() default { AriaConstance.NO_URL };
+ }
+
+ /**
+ * 如果你在方法中添加{@code @Download.onTaskResume}注解,在任务恢复下载时,Aria会调用该方法
+ */
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskResume {
+ String[] value() default { AriaConstance.NO_URL };
+ }
+
+ /**
+ * 如果你在方法中添加{@code @Download.onTaskStart}注解,在任务开始下载时,Aria会调用该方法
+ */
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskStart {
+ String[] value() default { AriaConstance.NO_URL };
+ }
+
+ /**
+ * 如果你在方法中添加{@code @Download.onTaskStop}注解,在任务停止时,Aria会调用该方法
+ */
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskStop {
+ String[] value() default { AriaConstance.NO_URL };
+ }
+
+ /**
+ * 如果你在方法中添加{@code @Download.onTaskCancel}l注解,在任务取消时,Aria会调用该方法
+ */
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskCancel {
+ String[] value() default { AriaConstance.NO_URL };
+ }
+
+ /**
+ * 如果你在方法中添加{@code @Download.onTaskFail)注解,在任务预失败时,Aria会调用该方法
+ */
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskFail {
+ String[] value() default { AriaConstance.NO_URL };
+ }
+
+ /**
+ * 如果你在方法中添加{@code @Download.onTaskComplete}注解,在任务完成时,Aria会调用该方法
+ */
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskComplete {
+ String[] value() default { AriaConstance.NO_URL };
+ }
+
+ /**
+ * 如果你在方法中添加{@code @Download.onTaskRunning}注解,在任务正在下载,Aria会调用该方法
+ */
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskRunning {
+ String[] value() default { AriaConstance.NO_URL };
+ }
+}
diff --git a/AriaAnnotations/src/main/java/com/arialyy/annotations/Upload.java b/AriaAnnotations/src/main/java/com/arialyy/annotations/Upload.java
index 7906bcc7..609c6663 100644
--- a/AriaAnnotations/src/main/java/com/arialyy/annotations/Upload.java
+++ b/AriaAnnotations/src/main/java/com/arialyy/annotations/Upload.java
@@ -39,14 +39,14 @@ import java.lang.annotation.Target;
/**
* 如果你在方法中添加{@code @Upload.onPre}注解,在预处理完成时,Aria会调用该方法
*/
- @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onPre {
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onPre {
String[] value() default { AriaConstance.NO_URL };
}
/**
* 如果你在方法中添加{@code @Upload.onTaskPre}注解,在任务预处理完成时,Aria会调用该方法
*/
- @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskPre {
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskPre {
String[] value() default { AriaConstance.NO_URL };
}
@@ -59,42 +59,42 @@ import java.lang.annotation.Target;
/**
* 如果你在方法中添加{@code @Upload.onTaskStart}注解,在任务开始下载时,Aria会调用该方法
*/
- @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskStart {
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskStart {
String[] value() default { AriaConstance.NO_URL };
}
/**
* 如果你在方法中添加{@code @Upload.onTaskStop}注解,在任务停止时,Aria会调用该方法
*/
- @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskStop {
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskStop {
String[] value() default { AriaConstance.NO_URL };
}
/**
* 如果你在方法中添加{@code @Upload.onTaskCancel}l注解,在任务取消时,Aria会调用该方法
*/
- @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskCancel {
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskCancel {
String[] value() default { AriaConstance.NO_URL };
}
/**
* 如果你在方法中添加{@code @Upload.onTaskFail)注解,在任务预失败时,Aria会调用该方法
*/
- @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskFail {
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskFail {
String[] value() default { AriaConstance.NO_URL };
}
/**
* 如果你在方法中添加{@code @Upload.onTaskComplete}注解,在任务完成时,Aria会调用该方法
*/
- @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskComplete {
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskComplete {
String[] value() default { AriaConstance.NO_URL };
}
/**
* 如果你在方法中添加{@code @Upload.onTaskRunning}注解,在任务正在下载,Aria会调用该方法
*/
- @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskRunning {
+ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskRunning {
String[] value() default { AriaConstance.NO_URL };
}
@@ -102,7 +102,7 @@ import java.lang.annotation.Target;
* 如果你在方法中添加{@code @Upload.onNoSupportBreakPoint}注解,如果该任务不支持断点,Aria会调用该方法
*/
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD)
- public @interface onNoSupportBreakPoint {
+ @interface onNoSupportBreakPoint {
String[] value() default { AriaConstance.NO_URL };
}
}
diff --git a/AriaCompiler/build.gradle b/AriaCompiler/build.gradle
index 38de01a1..a76e8659 100644
--- a/AriaCompiler/build.gradle
+++ b/AriaCompiler/build.gradle
@@ -14,4 +14,4 @@ dependencies {
compile project(':AriaAnnotations')
}
-//apply from: 'bintray-release.gradle'
\ No newline at end of file
+apply from: 'bintray-release.gradle'
\ No newline at end of file
diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/AriaProcessor.java b/AriaCompiler/src/main/java/com/arialyy/compiler/AriaProcessor.java
index 5ac4a533..814c6945 100644
--- a/AriaCompiler/src/main/java/com/arialyy/compiler/AriaProcessor.java
+++ b/AriaCompiler/src/main/java/com/arialyy/compiler/AriaProcessor.java
@@ -32,16 +32,17 @@ import javax.lang.model.element.TypeElement;
* 事件注解扫描器
*/
@AutoService(Processor.class) public class AriaProcessor extends AbstractProcessor {
- ElementHandle mHandler;
+ ElementHandler mHandler;
@Override public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
PrintLog.init(processingEnv.getMessager());
- mHandler = new ElementHandle(processingEnv.getFiler(), processingEnv.getElementUtils());
+ mHandler = new ElementHandler(processingEnv.getFiler(), processingEnv.getElementUtils());
}
@Override public Set getSupportedAnnotationTypes() {
Set annotataions = new LinkedHashSet<>();
+ //单任务下载的注解
annotataions.add(Download.onPre.class.getCanonicalName());
annotataions.add(Download.onNoSupportBreakPoint.class.getCanonicalName());
annotataions.add(Download.onTaskCancel.class.getCanonicalName());
@@ -52,6 +53,18 @@ import javax.lang.model.element.TypeElement;
annotataions.add(Download.onTaskRunning.class.getCanonicalName());
annotataions.add(Download.onTaskStart.class.getCanonicalName());
annotataions.add(Download.onTaskStop.class.getCanonicalName());
+ //下载任务的注解
+ annotataions.add(Download.onPre.class.getCanonicalName());
+ annotataions.add(Download.onNoSupportBreakPoint.class.getCanonicalName());
+ annotataions.add(Download.onTaskCancel.class.getCanonicalName());
+ annotataions.add(Download.onTaskComplete.class.getCanonicalName());
+ annotataions.add(Download.onTaskFail.class.getCanonicalName());
+ annotataions.add(Download.onTaskPre.class.getCanonicalName());
+ annotataions.add(Download.onTaskResume.class.getCanonicalName());
+ annotataions.add(Download.onTaskRunning.class.getCanonicalName());
+ annotataions.add(Download.onTaskStart.class.getCanonicalName());
+ annotataions.add(Download.onTaskStop.class.getCanonicalName());
+ //上传任务的注解
annotataions.add(Upload.onPre.class.getCanonicalName());
annotataions.add(Upload.onNoSupportBreakPoint.class.getCanonicalName());
annotataions.add(Upload.onTaskCancel.class.getCanonicalName());
@@ -73,6 +86,7 @@ import javax.lang.model.element.TypeElement;
public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) {
mHandler.clean();
mHandler.handleDownload(roundEnv);
+ mHandler.handleDownloadGroup(roundEnv);
mHandler.handleUpload(roundEnv);
mHandler.createProxyFile();
return true;
diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandle.java b/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandle.java
deleted file mode 100644
index a09f4178..00000000
--- a/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandle.java
+++ /dev/null
@@ -1,405 +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.compiler;
-
-import com.arialyy.annotations.Download;
-import com.arialyy.annotations.Upload;
-import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.FieldSpec;
-import com.squareup.javapoet.JavaFile;
-import com.squareup.javapoet.MethodSpec;
-import com.squareup.javapoet.ParameterSpec;
-import com.squareup.javapoet.TypeSpec;
-import com.squareup.javapoet.ParameterizedTypeName;
-import java.io.IOException;
-import java.lang.annotation.Annotation;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.annotation.processing.Filer;
-import javax.annotation.processing.RoundEnvironment;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.util.Elements;
-
-/**
- * Created by lyy on 2017/6/6.
- * 元素处理
- */
-class ElementHandle {
-
- private Filer mFiler;
- private Elements mElementUtil;
- private Map mMethods = new HashMap<>();
-
- ElementHandle(Filer filer, Elements elements) {
- mFiler = filer;
- mElementUtil = elements;
- }
-
- /**
- * VariableElement 一般代表成员变量
- * ExecutableElement 一般代表类中的方法
- * TypeElement 一般代表代表类
- * PackageElement 一般代表Package
- */
- void handleDownload(RoundEnvironment roundEnv) {
- saveMethod(true, roundEnv, Download.onNoSupportBreakPoint.class,
- ProxyConstance.DOWNLOAD_TASK_NO_SUPPORT_BREAKPOINT);
- saveMethod(true, roundEnv, Download.onPre.class, ProxyConstance.DOWNLOAD_PRE);
- saveMethod(true, roundEnv, Download.onTaskCancel.class, ProxyConstance.DOWNLOAD_TASK_CANCEL);
- saveMethod(true, roundEnv, Download.onTaskComplete.class,
- ProxyConstance.DOWNLOAD_TASK_COMPLETE);
- saveMethod(true, roundEnv, Download.onTaskFail.class, ProxyConstance.DOWNLOAD_TASK_FAIL);
- saveMethod(true, roundEnv, Download.onTaskPre.class, ProxyConstance.DOWNLOAD_TASK_PRE);
- saveMethod(true, roundEnv, Download.onTaskResume.class, ProxyConstance.DOWNLOAD_TASK_RESUME);
- saveMethod(true, roundEnv, Download.onTaskRunning.class, ProxyConstance.DOWNLOAD_TASK_RUNNING);
- saveMethod(true, roundEnv, Download.onTaskStart.class, ProxyConstance.DOWNLOAD_TASK_START);
- saveMethod(true, roundEnv, Download.onTaskStop.class, ProxyConstance.DOWNLOAD_TASK_STOP);
- }
-
- void handleUpload(RoundEnvironment roundEnv) {
- saveMethod(false, roundEnv, Upload.onNoSupportBreakPoint.class,
- ProxyConstance.UPLOAD_TASK_NO_SUPPORT_BREAKPOINT);
- saveMethod(false, roundEnv, Upload.onPre.class, ProxyConstance.UPLOAD_PRE);
- saveMethod(false, roundEnv, Upload.onTaskCancel.class, ProxyConstance.UPLOAD_TASK_CANCEL);
- saveMethod(false, roundEnv, Upload.onTaskComplete.class, ProxyConstance.UPLOAD_TASK_COMPLETE);
- saveMethod(false, roundEnv, Upload.onTaskFail.class, ProxyConstance.UPLOAD_TASK_FAIL);
- saveMethod(false, roundEnv, Upload.onTaskPre.class, ProxyConstance.UPLOAD_TASK_PRE);
- //saveMethod(false, roundEnv, Upload.onTaskResume.class);
- saveMethod(false, roundEnv, Upload.onTaskRunning.class, ProxyConstance.UPLOAD_TASK_RUNNING);
- saveMethod(false, roundEnv, Upload.onTaskStart.class, ProxyConstance.UPLOAD_TASK_START);
- saveMethod(false, roundEnv, Upload.onTaskStop.class, ProxyConstance.UPLOAD_TASK_STOP);
- }
-
- /**
- * 在build文件夹中生成如下代码的文件
- *
- *
- * package com.arialyy.simple.download;
- *
- * import com.arialyy.aria.core.download.DownloadTask;
- * import com.arialyy.aria.core.scheduler.AbsSchedulerListener;
- *
- * public final class SingleTaskActivity$$DownloadListenerProxy extends
- * AbsSchedulerListener {
- * private SingleTaskActivity obj;
- *
- * public void onPre(final DownloadTask task) {
- * obj.onPre((DownloadTask)task);
- * }
- *
- * public void onTaskStart(final DownloadTask task) {
- * obj.onStart((DownloadTask)task);
- * }
- *
- * public void setListener(final Object obj) {
- * this.obj = (SingleTaskActivity)obj;
- * }
- * }
- *
- *
- */
- void createProxyFile() {
- Set keys = mMethods.keySet();
- try {
- for (String key : keys) {
- ProxyEntity entity = mMethods.get(key);
- JavaFile jf = JavaFile.builder(entity.packageName, createProxyClass(entity)).build();
-
- jf.writeTo(mFiler);
- // 如果需要在控制台打印生成的文件,则去掉下面的注释
- //jf.writeTo(System.out);
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * 创建代理方法
- *
- * @param isDownload 是否是下载的注解
- * @param annotation {@link Download}、{@link Upload}
- * @param methodName 被代理类注解的方法名
- */
- private MethodSpec createProxyMethod(boolean isDownload, Class extends Annotation> annotation,
- String methodName) {
- ClassName task = ClassName.get(
- isDownload ? "com.arialyy.aria.core.download" : "com.arialyy.aria.core.upload",
- isDownload ? "DownloadTask" : "UploadTask");
- ParameterSpec parameterSpec =
- ParameterSpec.builder(task, "task").addModifiers(Modifier.FINAL).build();
- StringBuilder sb = new StringBuilder();
- sb.append("Set keys = keyMapping.get(\"")
- .append(methodName)
- .append("\");\n");
- sb.append("if (keys != null) {\n\tif (keys.contains(task.getKey())) {\n")
- .append("\t\tobj.")
- .append(methodName)
- .append("(")
- .append(isDownload ? "(DownloadTask)" : "(UploadTask)")
- .append("task);\n")
- .append("\t}\n} else {\n")
- .append("\tobj.")
- .append(methodName)
- .append("(")
- .append(isDownload ? "(DownloadTask)" : "(UploadTask)")
- .append("task);\n}\n");
-
- return MethodSpec.methodBuilder(annotation.getSimpleName())
- .addModifiers(Modifier.PUBLIC)
- .returns(void.class)
- .addParameter(parameterSpec)
- .addAnnotation(Override.class)
- .addCode(sb.toString())
- .build();
- }
-
- /**
- * 创建代理类
- */
- private TypeSpec createProxyClass(ProxyEntity entity) {
- TypeSpec.Builder builder = TypeSpec.classBuilder(
- entity.className + (entity.isDownlaod ? ProxyConstance.DOWNLOAD_PROXY_CLASS_SUFFIX
- : ProxyConstance.UPLOAD_PROXY_CLASS_SUFFIX))
- .addModifiers(Modifier.PUBLIC, Modifier.FINAL);
-
- //添加被代理的类的字段
- ClassName obj = ClassName.get(entity.packageName, entity.className);
- FieldSpec observerField = FieldSpec.builder(obj, "obj").addModifiers(Modifier.PRIVATE).build();
- builder.addField(observerField);
-
- //添加url映射表
- FieldSpec mappingField = FieldSpec.builder(
- ParameterizedTypeName.get(ClassName.get(Map.class), ClassName.get(String.class),
- ParameterizedTypeName.get(ClassName.get(Set.class), ClassName.get(String.class))),
- "keyMapping").addModifiers(Modifier.PRIVATE).initializer("new $T()", HashMap.class).build();
- builder.addField(mappingField);
-
- //添加注解方法
- for (Class extends Annotation> annotation : entity.methods.keySet()) {
- MethodSpec method =
- createProxyMethod(entity.isDownlaod, annotation, entity.methods.get(annotation));
- builder.addMethod(method);
- }
-
- //增加构造函数
- CodeBlock.Builder cb = CodeBlock.builder();
- cb.add("Set set = null;\n");
- for (String methodName : entity.keyMappings.keySet()) {
- Set keys = entity.keyMappings.get(methodName);
- if (keys == null || keys.size() == 0) continue;
- StringBuilder sb = new StringBuilder();
- sb.append("set = new $T();\n");
- for (String key : keys) {
- if (key.isEmpty()) continue;
- sb.append("set.add(\"").append(key).append("\");\n");
- }
-
- sb.append("keyMapping.put(\"").append(methodName).append("\", ").append("set);\n");
- cb.add(sb.toString(), ClassName.get(HashSet.class));
- }
- MethodSpec structure =
- MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC).addCode(cb.build()).build();
- builder.addMethod(structure);
-
- //添加设置代理的类
- ParameterSpec parameterSpec =
- ParameterSpec.builder(Object.class, "obj").addModifiers(Modifier.FINAL).build();
- MethodSpec listener = MethodSpec.methodBuilder(ProxyConstance.SET_LISTENER)
- .addModifiers(Modifier.PUBLIC)
- .returns(void.class)
- .addParameter(parameterSpec)
- .addAnnotation(Override.class)
- .addCode("this.obj = (" + entity.className + ")obj;\n")
- .build();
- builder.addJavadoc("该文件为Aria自动生成的代理文件,请不要修改该文件的任何代码!\n");
-
- //创建父类参数
- ClassName superClass = ClassName.get("com.arialyy.aria.core.scheduler", "AbsSchedulerListener");
- //创建泛型
- ClassName typeVariableName = ClassName.get(
- entity.isDownlaod ? "com.arialyy.aria.core.download" : "com.arialyy.aria.core.upload",
- entity.isDownlaod ? "DownloadTask" : "UploadTask");
- builder.superclass(ParameterizedTypeName.get(superClass, typeVariableName));
- builder.addMethod(listener);
- return builder.build();
- }
-
- void clean() {
- mMethods.clear();
- }
-
- /**
- * 查找并保存扫描到的方法
- */
- private void saveMethod(boolean isDownload, RoundEnvironment roundEnv,
- Class extends Annotation> annotationClazz, int annotationType) {
- for (Element element : roundEnv.getElementsAnnotatedWith(annotationClazz)) {
- ElementKind kind = element.getKind();
- if (kind == ElementKind.METHOD) {
- ExecutableElement method = (ExecutableElement) element;
- TypeElement classElement = (TypeElement) method.getEnclosingElement();
- PackageElement packageElement = mElementUtil.getPackageOf(classElement);
- checkDownloadMethod(isDownload, method);
- String methodName = method.getSimpleName().toString();
- String className = method.getEnclosingElement().toString(); //全类名
- ProxyEntity proxyEntity = mMethods.get(className);
- if (proxyEntity == null) {
- proxyEntity = new ProxyEntity();
- proxyEntity.isDownlaod = isDownload;
- proxyEntity.packageName = packageElement.getQualifiedName().toString();
- proxyEntity.className = classElement.getSimpleName().toString();
- mMethods.put(className, proxyEntity);
- }
- proxyEntity.methods.put(annotationClazz, methodName);
- proxyEntity.keyMappings.put(methodName, getValues(method, isDownload, annotationType));
- }
- }
- }
-
- /**
- * 获取注解的内容
- */
- private Set getValues(ExecutableElement method, boolean isDownload, int annotationType) {
- String[] keys = null;
- if (isDownload) {
- switch (annotationType) {
- case ProxyConstance.DOWNLOAD_PRE:
- keys = method.getAnnotation(Download.onPre.class).value();
- break;
- case ProxyConstance.DOWNLOAD_TASK_PRE:
- keys = method.getAnnotation(Download.onTaskPre.class).value();
- break;
- case ProxyConstance.DOWNLOAD_TASK_RESUME:
- keys = method.getAnnotation(Download.onTaskResume.class).value();
- break;
- case ProxyConstance.DOWNLOAD_TASK_START:
- keys = method.getAnnotation(Download.onTaskStart.class).value();
- break;
- case ProxyConstance.DOWNLOAD_TASK_RUNNING:
- keys = method.getAnnotation(Download.onTaskRunning.class).value();
- break;
- case ProxyConstance.DOWNLOAD_TASK_STOP:
- keys = method.getAnnotation(Download.onTaskStop.class).value();
- break;
- case ProxyConstance.DOWNLOAD_TASK_COMPLETE:
- keys = method.getAnnotation(Download.onTaskComplete.class).value();
- break;
- case ProxyConstance.DOWNLOAD_TASK_CANCEL:
- keys = method.getAnnotation(Download.onTaskCancel.class).value();
- break;
- case ProxyConstance.DOWNLOAD_TASK_FAIL:
- keys = method.getAnnotation(Download.onTaskFail.class).value();
- break;
- case ProxyConstance.DOWNLOAD_TASK_NO_SUPPORT_BREAKPOINT:
- keys = method.getAnnotation(Download.onNoSupportBreakPoint.class).value();
- break;
- }
- } else {
- switch (annotationType) {
- case ProxyConstance.UPLOAD_PRE:
- keys = method.getAnnotation(Upload.onPre.class).value();
- break;
- case ProxyConstance.UPLOAD_TASK_PRE:
- keys = method.getAnnotation(Upload.onTaskPre.class).value();
- break;
- case ProxyConstance.UPLOAD_TASK_RESUME:
- //keys = method.getAnnotation(Upload.onTaskResume.class).value();
- break;
- case ProxyConstance.UPLOAD_TASK_START:
- keys = method.getAnnotation(Upload.onTaskStart.class).value();
- break;
- case ProxyConstance.UPLOAD_TASK_RUNNING:
- keys = method.getAnnotation(Upload.onTaskRunning.class).value();
- break;
- case ProxyConstance.UPLOAD_TASK_STOP:
- keys = method.getAnnotation(Upload.onTaskStop.class).value();
- break;
- case ProxyConstance.UPLOAD_TASK_COMPLETE:
- keys = method.getAnnotation(Upload.onTaskComplete.class).value();
- break;
- case ProxyConstance.UPLOAD_TASK_CANCEL:
- keys = method.getAnnotation(Upload.onTaskCancel.class).value();
- break;
- case ProxyConstance.UPLOAD_TASK_FAIL:
- keys = method.getAnnotation(Upload.onTaskFail.class).value();
- break;
- case ProxyConstance.UPLOAD_TASK_NO_SUPPORT_BREAKPOINT:
- keys = method.getAnnotation(Upload.onNoSupportBreakPoint.class).value();
- break;
- }
- }
-
- return keys == null ? null : convertSet(keys);
- }
-
- /**
- * 检查和下载相关的方法,如果被注解的方法为private或参数不合法,则抛异常
- */
- private void checkDownloadMethod(boolean isDownload, ExecutableElement method) {
- String methodName = method.getSimpleName().toString();
- String className = method.getEnclosingElement().toString();
- Set modifiers = method.getModifiers();
- if (modifiers.contains(Modifier.PRIVATE)) {
- throw new IllegalAccessError(className + "." + methodName + "不能为private方法");
- }
- List params = (List) method.getParameters();
- if (params.size() > 1) {
- throw new IllegalArgumentException(
- className + "." + methodName + "参数错误, 参数只有一个,且参数必须是" + getCheckParams(isDownload));
- }
- if (!params.get(0).asType().toString().equals(getCheckParams(isDownload))) {
- throw new IllegalArgumentException(className
- + "."
- + methodName
- + "参数【"
- + params.get(0).getSimpleName()
- + "】类型错误,参数必须是"
- + getCheckParams(isDownload));
- }
- }
-
- /**
- * 字符串数组转set
- *
- * @param keys 注解中查到的key
- */
- private Set convertSet(final String[] keys) {
- if (keys == null || keys.length == 0) {
- return null;
- }
- if (keys[0].isEmpty()) return null;
- Set set = new HashSet<>();
- Collections.addAll(set, keys);
- return set;
- }
-
- private String getCheckParams(boolean isDownload) {
- return isDownload ? "com.arialyy.aria.core.download.DownloadTask"
- : "com.arialyy.aria.core.upload.UploadTask";
- }
-}
diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandler.java b/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandler.java
new file mode 100644
index 00000000..5cbdd005
--- /dev/null
+++ b/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandler.java
@@ -0,0 +1,601 @@
+/*
+ * 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.compiler;
+
+import com.arialyy.annotations.Download;
+import com.arialyy.annotations.DownloadGroup;
+import com.arialyy.annotations.Upload;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.CodeBlock;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterSpec;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.ParameterizedTypeName;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.processing.Filer;
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.util.Elements;
+
+/**
+ * Created by lyy on 2017/6/6.
+ * 元素处理
+ */
+class ElementHandler {
+ private static final boolean DEBUG = false;
+
+ private Filer mFiler;
+ private Elements mElementUtil;
+ private Map mMethods = new HashMap<>();
+ private Map> mListenerClass = new HashMap<>();
+
+ ElementHandler(Filer filer, Elements elements) {
+ mFiler = filer;
+ mElementUtil = elements;
+ }
+
+ /**
+ * VariableElement 一般代表成员变量
+ * ExecutableElement 一般代表类中的方法
+ * TypeElement 一般代表代表类
+ * PackageElement 一般代表Package
+ */
+ void handleDownload(RoundEnvironment roundEnv) {
+ saveMethod(TaskEnum.DOWNLOAD, roundEnv, Download.onNoSupportBreakPoint.class,
+ ProxyConstance.TASK_NO_SUPPORT_BREAKPOINT);
+ saveMethod(TaskEnum.DOWNLOAD, roundEnv, Download.onPre.class, ProxyConstance.PRE);
+ saveMethod(TaskEnum.DOWNLOAD, roundEnv, Download.onTaskCancel.class,
+ ProxyConstance.TASK_CANCEL);
+ saveMethod(TaskEnum.DOWNLOAD, roundEnv, Download.onTaskComplete.class,
+ ProxyConstance.TASK_COMPLETE);
+ saveMethod(TaskEnum.DOWNLOAD, roundEnv, Download.onTaskFail.class, ProxyConstance.TASK_FAIL);
+ saveMethod(TaskEnum.DOWNLOAD, roundEnv, Download.onTaskPre.class, ProxyConstance.TASK_PRE);
+ saveMethod(TaskEnum.DOWNLOAD, roundEnv, Download.onTaskResume.class,
+ ProxyConstance.TASK_RESUME);
+ saveMethod(TaskEnum.DOWNLOAD, roundEnv, Download.onTaskRunning.class,
+ ProxyConstance.TASK_RUNNING);
+ saveMethod(TaskEnum.DOWNLOAD, roundEnv, Download.onTaskStart.class, ProxyConstance.TASK_START);
+ saveMethod(TaskEnum.DOWNLOAD, roundEnv, Download.onTaskStop.class, ProxyConstance.TASK_STOP);
+ }
+
+ /**
+ * 处理搜索到的下载任务组注解
+ */
+ void handleDownloadGroup(RoundEnvironment roundEnv) {
+ saveMethod(TaskEnum.DOWNLOAD_GROUP, roundEnv, DownloadGroup.onPre.class, ProxyConstance.PRE);
+ saveMethod(TaskEnum.DOWNLOAD_GROUP, roundEnv, DownloadGroup.onTaskCancel.class,
+ ProxyConstance.TASK_CANCEL);
+ saveMethod(TaskEnum.DOWNLOAD_GROUP, roundEnv, DownloadGroup.onTaskComplete.class,
+ ProxyConstance.TASK_COMPLETE);
+ saveMethod(TaskEnum.DOWNLOAD_GROUP, roundEnv, DownloadGroup.onTaskFail.class,
+ ProxyConstance.TASK_FAIL);
+ saveMethod(TaskEnum.DOWNLOAD_GROUP, roundEnv, DownloadGroup.onTaskPre.class,
+ ProxyConstance.TASK_PRE);
+ saveMethod(TaskEnum.DOWNLOAD_GROUP, roundEnv, DownloadGroup.onTaskResume.class,
+ ProxyConstance.TASK_RESUME);
+ saveMethod(TaskEnum.DOWNLOAD_GROUP, roundEnv, DownloadGroup.onTaskRunning.class,
+ ProxyConstance.TASK_RUNNING);
+ saveMethod(TaskEnum.DOWNLOAD_GROUP, roundEnv, DownloadGroup.onTaskStart.class,
+ ProxyConstance.TASK_START);
+ saveMethod(TaskEnum.DOWNLOAD_GROUP, roundEnv, DownloadGroup.onTaskStop.class,
+ ProxyConstance.TASK_STOP);
+ }
+
+ /**
+ * 处理搜索到的上传注解F
+ */
+ void handleUpload(RoundEnvironment roundEnv) {
+ saveMethod(TaskEnum.UPLOAD, roundEnv, Upload.onNoSupportBreakPoint.class,
+ ProxyConstance.TASK_NO_SUPPORT_BREAKPOINT);
+ saveMethod(TaskEnum.UPLOAD, roundEnv, Upload.onPre.class, ProxyConstance.PRE);
+ saveMethod(TaskEnum.UPLOAD, roundEnv, Upload.onTaskCancel.class, ProxyConstance.TASK_CANCEL);
+ saveMethod(TaskEnum.UPLOAD, roundEnv, Upload.onTaskComplete.class,
+ ProxyConstance.TASK_COMPLETE);
+ saveMethod(TaskEnum.UPLOAD, roundEnv, Upload.onTaskFail.class, ProxyConstance.TASK_FAIL);
+ saveMethod(TaskEnum.UPLOAD, roundEnv, Upload.onTaskPre.class, ProxyConstance.TASK_PRE);
+ //saveMethod(false, roundEnv, Upload.onTaskResume.class);
+ saveMethod(TaskEnum.UPLOAD, roundEnv, Upload.onTaskRunning.class, ProxyConstance.TASK_RUNNING);
+ saveMethod(TaskEnum.UPLOAD, roundEnv, Upload.onTaskStart.class, ProxyConstance.TASK_START);
+ saveMethod(TaskEnum.UPLOAD, roundEnv, Upload.onTaskStop.class, ProxyConstance.TASK_STOP);
+ }
+
+ /**
+ * 在build文件夹中生成如下代码的文件
+ *
+ *
+ * package com.arialyy.simple.download;
+ *
+ * import com.arialyy.aria.core.download.DownloadTask;
+ * import com.arialyy.aria.core.scheduler.AbsSchedulerListener;
+ *
+ * public final class SingleTaskActivity$$DownloadListenerProxy extends
+ * AbsSchedulerListener {
+ * private SingleTaskActivity obj;
+ *
+ * public void onPre(final DownloadTask task) {
+ * obj.onPre((DownloadTask)task);
+ * }
+ *
+ * public void onTaskStart(final DownloadTask task) {
+ * obj.onStart((DownloadTask)task);
+ * }
+ *
+ * public void setListener(final Object obj) {
+ * this.obj = (SingleTaskActivity)obj;
+ * }
+ * }
+ *
+ *
+ */
+ void createProxyFile() {
+ try {
+ createProxyListenerFile();
+ createProxyClassFile();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 创建事件代理文件
+ */
+ private void createProxyListenerFile() throws IOException {
+ Set keys = mMethods.keySet();
+ for (String key : keys) {
+ ProxyMethodParam entity = mMethods.get(key);
+ for (TaskEnum taskEnum : entity.taskEnums) {
+ JavaFile jf =
+ JavaFile.builder(entity.packageName, createProxyClass(entity, taskEnum)).build();
+ createFile(jf);
+ }
+ }
+ }
+
+ private void createFile(JavaFile jf) throws IOException {
+ if (DEBUG) {
+ // 如果需要在控制台打印生成的文件,则去掉下面的注释
+ jf.writeTo(System.out);
+ } else {
+ jf.writeTo(mFiler);
+ }
+ }
+
+ /**
+ * 每一种注解对应的类集合
+ */
+ private void createProxyClassFile() throws IOException {
+ Set keys = mListenerClass.keySet();
+ TypeSpec.Builder builder = TypeSpec.classBuilder(ProxyConstance.PROXY_COUNTER_NAME)
+ .addModifiers(Modifier.PUBLIC, Modifier.FINAL);
+
+ FieldSpec mappingField = FieldSpec.builder(
+ ParameterizedTypeName.get(ClassName.get(Map.class), ClassName.get(String.class),
+ ParameterizedTypeName.get(ClassName.get(Set.class), ClassName.get(String.class))),
+ ProxyConstance.PROXY_COUNTER_MAP)
+ .addModifiers(Modifier.PRIVATE)
+ .initializer("new $T()", HashMap.class)
+ .build();
+ builder.addField(mappingField);
+
+ //增加构造函数
+ CodeBlock.Builder cb = CodeBlock.builder();
+ cb.add("Set set = null;\n");
+ for (String key : keys) {
+ addTypeData(key, mListenerClass.get(key), cb);
+ }
+ MethodSpec structure =
+ MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC).addCode(cb.build()).build();
+ builder.addMethod(structure);
+
+ builder.addMethod(
+ creatMethod(ProxyConstance.COUNT_METHOD_DOWNLOAD, ProxyConstance.COUNT_DOWNLOAD));
+ builder.addMethod(creatMethod(ProxyConstance.COUNT_METHOD_UPLOAD, ProxyConstance.COUNT_UPLOAD));
+ builder.addMethod(creatMethod(ProxyConstance.COUNT_METHOD_DOWNLOAD_GROUP,
+ ProxyConstance.COUNT_DOWNLOAD_GROUP));
+
+ JavaFile jf = JavaFile.builder(ProxyConstance.PROXY_COUNTER_PACKAGE, builder.build()).build();
+ createFile(jf);
+ }
+
+ /**
+ * 创建不同任务类型的代理类集合
+ *
+ * @param key {@link #addListenerMapping(String, String)}
+ */
+ private MethodSpec creatMethod(String methodName, String key) {
+ MethodSpec.Builder builder = MethodSpec.methodBuilder(methodName);
+ ParameterizedTypeName returnName =
+ ParameterizedTypeName.get(ClassName.get(Set.class), ClassName.get(String.class));
+ builder.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
+ .returns(returnName)
+ .addCode("return " + ProxyConstance.PROXY_COUNTER_MAP + ".get(\"" + key + "\");\n");
+ return builder.build();
+ }
+
+ /**
+ * 添加每一种注解对应类
+ *
+ * @param type {@link #addListenerMapping(String, String)}
+ */
+ private void addTypeData(String type, Set clsNames, CodeBlock.Builder cb) {
+ if (clsNames == null || clsNames.isEmpty()) return;
+ StringBuilder sb = new StringBuilder();
+ sb.append("set = new $T();\n");
+ for (String clsName : clsNames) {
+ sb.append("set.add(\"").append(clsName).append("\");\n");
+ }
+ sb.append("typeMapping.put(\"").append(type).append("\", ").append("set);\n");
+ cb.add(sb.toString(), ClassName.get(HashSet.class));
+ }
+
+ /**
+ * 创建代理方法
+ *
+ * @param taskEnum 任务类型枚举{@link TaskEnum}
+ * @param annotation {@link Download}、{@link Upload}
+ * @param methodName 被代理类注解的方法名
+ */
+ private MethodSpec createProxyMethod(TaskEnum taskEnum, Class extends Annotation> annotation,
+ String methodName) {
+ ClassName task = ClassName.get(taskEnum.getPkg(), taskEnum.getClassName());
+
+ ParameterSpec parameterSpec =
+ ParameterSpec.builder(task, "task").addModifiers(Modifier.FINAL).build();
+ StringBuilder sb = new StringBuilder();
+ sb.append("Set keys = keyMapping.get(\"").append(methodName).append("\");\n");
+ sb.append("if (keys != null) {\n\tif (keys.contains(task.getKey())) {\n")
+ .append("\t\tobj.")
+ .append(methodName)
+ .append("((")
+ .append(taskEnum.getClassName())
+ .append(")task);\n")
+ .append("\t}\n} else {\n")
+ .append("\tobj.")
+ .append(methodName)
+ .append("((")
+ .append(taskEnum.getClassName())
+ .append(")task);\n}\n");
+
+ return MethodSpec.methodBuilder(annotation.getSimpleName())
+ .addModifiers(Modifier.PUBLIC)
+ .returns(void.class)
+ .addParameter(parameterSpec)
+ .addAnnotation(Override.class)
+ .addCode(sb.toString())
+ .build();
+ }
+
+ /**
+ * 创建代理类
+ */
+ private TypeSpec createProxyClass(ProxyMethodParam entity, TaskEnum taskEnum) {
+ TypeSpec.Builder builder = TypeSpec.classBuilder(entity.className + taskEnum.getProxySuffix())
+ .addModifiers(Modifier.PUBLIC, Modifier.FINAL);
+
+ //添加被代理的类的字段
+ ClassName obj = ClassName.get(entity.packageName, entity.className);
+ FieldSpec observerField = FieldSpec.builder(obj, "obj").addModifiers(Modifier.PRIVATE).build();
+ builder.addField(observerField);
+
+ //添加url映射表
+ FieldSpec mappingField = FieldSpec.builder(
+ ParameterizedTypeName.get(ClassName.get(Map.class), ClassName.get(String.class),
+ ParameterizedTypeName.get(ClassName.get(Set.class), ClassName.get(String.class))),
+ "keyMapping").addModifiers(Modifier.PRIVATE).initializer("new $T()", HashMap.class).build();
+ builder.addField(mappingField);
+
+ //添加注解方法
+ Map, String> temp = entity.methods.get(taskEnum);
+ if (temp != null) {
+ for (Class extends Annotation> annotation : temp.keySet()) {
+ MethodSpec method = createProxyMethod(taskEnum, annotation, temp.get(annotation));
+ builder.addMethod(method);
+ }
+ }
+
+ //增加构造函数
+ CodeBlock.Builder cb = CodeBlock.builder();
+ cb.add("Set set = null;\n");
+ for (String methodName : entity.keyMappings.keySet()) {
+ Set keys = entity.keyMappings.get(methodName);
+ if (keys == null || keys.size() == 0) continue;
+ StringBuilder sb = new StringBuilder();
+ sb.append("set = new $T();\n");
+ for (String key : keys) {
+ if (key.isEmpty()) continue;
+ sb.append("set.add(\"").append(key).append("\");\n");
+ }
+
+ sb.append("keyMapping.put(\"").append(methodName).append("\", ").append("set);\n");
+ cb.add(sb.toString(), ClassName.get(HashSet.class));
+ }
+ MethodSpec structure =
+ MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC).addCode(cb.build()).build();
+ builder.addMethod(structure);
+
+ //添加设置代理的类
+ ParameterSpec parameterSpec =
+ ParameterSpec.builder(Object.class, "obj").addModifiers(Modifier.FINAL).build();
+ MethodSpec listener = MethodSpec.methodBuilder(ProxyConstance.SET_LISTENER)
+ .addModifiers(Modifier.PUBLIC)
+ .returns(void.class)
+ .addParameter(parameterSpec)
+ .addAnnotation(Override.class)
+ .addCode("this.obj = (" + entity.className + ")obj;\n")
+ .build();
+ builder.addJavadoc("该文件为Aria自动生成的代理文件,请不要修改该文件的任何代码!\n");
+
+ //创建父类参数
+ ClassName superClass = ClassName.get("com.arialyy.aria.core.scheduler", "AbsSchedulerListener");
+ //创建泛型
+ ClassName typeVariableName = ClassName.get(taskEnum.getPkg(), taskEnum.getClassName());
+ builder.superclass(ParameterizedTypeName.get(superClass, typeVariableName));
+ builder.addMethod(listener);
+ return builder.build();
+ }
+
+ void clean() {
+ mMethods.clear();
+ }
+
+ /**
+ * 查找并保存扫描到的方法
+ */
+ private void saveMethod(TaskEnum taskEnum, RoundEnvironment roundEnv,
+ Class extends Annotation> annotationClazz, int annotationType) {
+ for (Element element : roundEnv.getElementsAnnotatedWith(annotationClazz)) {
+ ElementKind kind = element.getKind();
+ if (kind == ElementKind.METHOD) {
+ ExecutableElement method = (ExecutableElement) element;
+ TypeElement classElement = (TypeElement) method.getEnclosingElement();
+ PackageElement packageElement = mElementUtil.getPackageOf(classElement);
+ checkDownloadMethod(taskEnum, method);
+ String methodName = method.getSimpleName().toString();
+ String className = method.getEnclosingElement().toString(); //全类名
+ ProxyMethodParam proxyEntity = mMethods.get(className);
+ if (proxyEntity == null) {
+ proxyEntity = new ProxyMethodParam();
+ proxyEntity.taskEnums = new HashSet<>();
+ proxyEntity.packageName = packageElement.getQualifiedName().toString();
+ proxyEntity.className = classElement.getSimpleName().toString();
+ mMethods.put(className, proxyEntity);
+ }
+ proxyEntity.taskEnums.add(taskEnum);
+ if (proxyEntity.methods.get(taskEnum) == null) {
+ proxyEntity.methods.put(taskEnum, new HashMap, String>());
+ }
+ proxyEntity.methods.get(taskEnum).put(annotationClazz, methodName);
+ proxyEntity.keyMappings.put(methodName, getValues(taskEnum, method, annotationType));
+ }
+ }
+ }
+
+ /**
+ * 获取注解的内容
+ */
+ private Set getValues(TaskEnum taskEnum, ExecutableElement method, int annotationType) {
+ String clsName = method.getEnclosingElement().toString();
+ String[] keys = null;
+ switch (taskEnum) {
+ case DOWNLOAD:
+ keys = getDownloadValues(method, annotationType);
+ addListenerMapping(clsName, ProxyConstance.COUNT_DOWNLOAD);
+ break;
+ case UPLOAD:
+ keys = getUploadValues(method, annotationType);
+ addListenerMapping(clsName, ProxyConstance.COUNT_UPLOAD);
+ break;
+ case DOWNLOAD_GROUP:
+ keys = getDownloadGroupValues(method, annotationType);
+ addListenerMapping(clsName, ProxyConstance.COUNT_DOWNLOAD_GROUP);
+ break;
+ }
+ return keys == null ? null : convertSet(keys);
+ }
+
+ /**
+ * 添加方法映射
+ *
+ * @param clsName 注解事件的类
+ * @param key {@link ProxyConstance#COUNT_DOWNLOAD}、{@link ProxyConstance#COUNT_UPLOAD}、{@link
+ * ProxyConstance#COUNT_DOWNLOAD_GROUP}
+ */
+ private void addListenerMapping(String clsName, String key) {
+ Set cls = mListenerClass.get(key);
+ if (cls == null) {
+ cls = new HashSet<>();
+ mListenerClass.put(key, cls);
+ }
+ cls.add(clsName);
+ }
+
+ /**
+ * 获取下载任务组的注解数据
+ */
+ private String[] getDownloadGroupValues(ExecutableElement method, int annotationType) {
+ String[] values = null;
+ switch (annotationType) {
+ case ProxyConstance.PRE:
+ values = method.getAnnotation(DownloadGroup.onPre.class).value();
+ break;
+ case ProxyConstance.TASK_PRE:
+ values = method.getAnnotation(DownloadGroup.onTaskPre.class).value();
+ break;
+ case ProxyConstance.TASK_RESUME:
+ values = method.getAnnotation(DownloadGroup.onTaskResume.class).value();
+ break;
+ case ProxyConstance.TASK_START:
+ values = method.getAnnotation(DownloadGroup.onTaskStart.class).value();
+ break;
+ case ProxyConstance.TASK_RUNNING:
+ values = method.getAnnotation(DownloadGroup.onTaskRunning.class).value();
+ break;
+ case ProxyConstance.TASK_STOP:
+ values = method.getAnnotation(DownloadGroup.onTaskStop.class).value();
+ break;
+ case ProxyConstance.TASK_COMPLETE:
+ values = method.getAnnotation(DownloadGroup.onTaskComplete.class).value();
+ break;
+ case ProxyConstance.TASK_CANCEL:
+ values = method.getAnnotation(DownloadGroup.onTaskCancel.class).value();
+ break;
+ case ProxyConstance.TASK_FAIL:
+ values = method.getAnnotation(DownloadGroup.onTaskFail.class).value();
+ break;
+ }
+ return values;
+ }
+
+ /**
+ * 获取上传的注解数据
+ */
+ private String[] getUploadValues(ExecutableElement method, int annotationType) {
+ String[] values = null;
+ switch (annotationType) {
+ case ProxyConstance.PRE:
+ values = method.getAnnotation(Upload.onPre.class).value();
+ break;
+ case ProxyConstance.TASK_PRE:
+ values = method.getAnnotation(Upload.onTaskPre.class).value();
+ break;
+ case ProxyConstance.TASK_RESUME:
+ //values = method.getAnnotation(Upload.onTaskResume.class).value();
+ break;
+ case ProxyConstance.TASK_START:
+ values = method.getAnnotation(Upload.onTaskStart.class).value();
+ break;
+ case ProxyConstance.TASK_RUNNING:
+ values = method.getAnnotation(Upload.onTaskRunning.class).value();
+ break;
+ case ProxyConstance.TASK_STOP:
+ values = method.getAnnotation(Upload.onTaskStop.class).value();
+ break;
+ case ProxyConstance.TASK_COMPLETE:
+ values = method.getAnnotation(Upload.onTaskComplete.class).value();
+ break;
+ case ProxyConstance.TASK_CANCEL:
+ values = method.getAnnotation(Upload.onTaskCancel.class).value();
+ break;
+ case ProxyConstance.TASK_FAIL:
+ values = method.getAnnotation(Upload.onTaskFail.class).value();
+ break;
+ case ProxyConstance.TASK_NO_SUPPORT_BREAKPOINT:
+ //values = method.getAnnotation(Upload.onNoSupportBreakPoint.class).value();
+ break;
+ }
+ return values;
+ }
+
+ /**
+ * 获取下载的注解数据
+ */
+ private String[] getDownloadValues(ExecutableElement method, int annotationType) {
+ String[] values = null;
+ switch (annotationType) {
+ case ProxyConstance.PRE:
+ values = method.getAnnotation(Download.onPre.class).value();
+ break;
+ case ProxyConstance.TASK_PRE:
+ values = method.getAnnotation(Download.onTaskPre.class).value();
+ break;
+ case ProxyConstance.TASK_RESUME:
+ values = method.getAnnotation(Download.onTaskResume.class).value();
+ break;
+ case ProxyConstance.TASK_START:
+ values = method.getAnnotation(Download.onTaskStart.class).value();
+ break;
+ case ProxyConstance.TASK_RUNNING:
+ values = method.getAnnotation(Download.onTaskRunning.class).value();
+ break;
+ case ProxyConstance.TASK_STOP:
+ values = method.getAnnotation(Download.onTaskStop.class).value();
+ break;
+ case ProxyConstance.TASK_COMPLETE:
+ values = method.getAnnotation(Download.onTaskComplete.class).value();
+ break;
+ case ProxyConstance.TASK_CANCEL:
+ values = method.getAnnotation(Download.onTaskCancel.class).value();
+ break;
+ case ProxyConstance.TASK_FAIL:
+ values = method.getAnnotation(Download.onTaskFail.class).value();
+ break;
+ case ProxyConstance.TASK_NO_SUPPORT_BREAKPOINT:
+ values = method.getAnnotation(Download.onNoSupportBreakPoint.class).value();
+ break;
+ }
+ return values;
+ }
+
+ /**
+ * 检查和下载相关的方法,如果被注解的方法为private或参数不合法,则抛异常
+ */
+ private void checkDownloadMethod(TaskEnum taskEnum, ExecutableElement method) {
+ String methodName = method.getSimpleName().toString();
+ String className = method.getEnclosingElement().toString();
+ Set modifiers = method.getModifiers();
+ if (modifiers.contains(Modifier.PRIVATE)) {
+ throw new IllegalAccessError(className + "." + methodName + "不能为private方法");
+ }
+ List params = (List) method.getParameters();
+ if (params.size() > 1) {
+ throw new IllegalArgumentException(
+ className + "." + methodName + "参数错误, 参数只有一个,且参数必须是" + getCheckParams(taskEnum));
+ }
+ if (!params.get(0).asType().toString().equals(getCheckParams(taskEnum))) {
+ throw new IllegalArgumentException(className
+ + "."
+ + methodName
+ + "参数【"
+ + params.get(0).getSimpleName()
+ + "】类型错误,参数必须是"
+ + getCheckParams(taskEnum));
+ }
+ }
+
+ /**
+ * 字符串数组转set
+ *
+ * @param keys 注解中查到的key
+ */
+ private Set convertSet(final String[] keys) {
+ if (keys == null || keys.length == 0) {
+ return null;
+ }
+ if (keys[0].isEmpty()) return null;
+ Set set = new HashSet<>();
+ Collections.addAll(set, keys);
+ return set;
+ }
+
+ private String getCheckParams(TaskEnum taskEnum) {
+ return taskEnum.pkg + "." + taskEnum.getClassName();
+ }
+}
diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/PrintLog.java b/AriaCompiler/src/main/java/com/arialyy/compiler/PrintLog.java
index 1350de4b..161a2214 100644
--- a/AriaCompiler/src/main/java/com/arialyy/compiler/PrintLog.java
+++ b/AriaCompiler/src/main/java/com/arialyy/compiler/PrintLog.java
@@ -22,7 +22,6 @@ import javax.tools.Diagnostic;
/**
* Created by Aria.Lao on 2017/6/6.
*/
-
class PrintLog {
private volatile static PrintLog INSTANCE = null;
diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyConstance.java b/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyConstance.java
index 6ea65c33..98fcb980 100644
--- a/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyConstance.java
+++ b/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyConstance.java
@@ -17,43 +17,44 @@ package com.arialyy.compiler;
/**
* Created by lyy on 2017/6/7.
+ * 扫描器常量
*/
-
-public interface ProxyConstance {
+interface ProxyConstance {
/**
* 设置观察者的方法
*/
String SET_LISTENER = "setListener";
/**
- * 下载的动态生成的代理类后缀
+ * 代理配置类
+ */
+ String PROXY_COUNTER_PACKAGE = "com.arialyy.aria";
+ /**
+ * 代理分类统计
*/
- String DOWNLOAD_PROXY_CLASS_SUFFIX = "$$DownloadListenerProxy";
+ String PROXY_COUNTER_NAME = "ProxyClassCounter";
/**
- * 上传的动态生成的代理类后缀
+ * 代理分类统计映射表
*/
- String UPLOAD_PROXY_CLASS_SUFFIX = "$$UploadListenerProxy";
+ String PROXY_COUNTER_MAP = "typeMapping";
+
+ String COUNT_DOWNLOAD = "download";
+ String COUNT_DOWNLOAD_GROUP = "downloadGroup";
+ String COUNT_UPLOAD = "upload";
- int DOWNLOAD_PRE = 0X11;
- int DOWNLOAD_TASK_PRE = 0X12;
- int DOWNLOAD_TASK_RESUME = 0X13;
- int DOWNLOAD_TASK_START = 0X14;
- int DOWNLOAD_TASK_STOP = 0X15;
- int DOWNLOAD_TASK_CANCEL = 0X16;
- int DOWNLOAD_TASK_FAIL = 0X17;
- int DOWNLOAD_TASK_COMPLETE = 0X18;
- int DOWNLOAD_TASK_RUNNING = 0X19;
- int DOWNLOAD_TASK_NO_SUPPORT_BREAKPOINT = 0X1A;
+ String COUNT_METHOD_DOWNLOAD = "getDownloadCounter";
+ String COUNT_METHOD_DOWNLOAD_GROUP = "getDownloadGroupCounter";
+ String COUNT_METHOD_UPLOAD = "getUploadCounter";
- int UPLOAD_PRE = 0X11;
- int UPLOAD_TASK_PRE = 0X12;
- int UPLOAD_TASK_RESUME = 0X13;
- int UPLOAD_TASK_START = 0X14;
- int UPLOAD_TASK_STOP = 0X15;
- int UPLOAD_TASK_CANCEL = 0X16;
- int UPLOAD_TASK_FAIL = 0X17;
- int UPLOAD_TASK_COMPLETE = 0X18;
- int UPLOAD_TASK_RUNNING = 0X19;
- int UPLOAD_TASK_NO_SUPPORT_BREAKPOINT = 0X1A;
+ int PRE = 0X11;
+ int TASK_PRE = 0X12;
+ int TASK_RESUME = 0X13;
+ int TASK_START = 0X14;
+ int TASK_STOP = 0X15;
+ int TASK_CANCEL = 0X16;
+ int TASK_FAIL = 0X17;
+ int TASK_COMPLETE = 0X18;
+ int TASK_RUNNING = 0X19;
+ int TASK_NO_SUPPORT_BREAKPOINT = 0X1A;
}
diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyEntity.java b/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyMethodParam.java
similarity index 75%
rename from AriaCompiler/src/main/java/com/arialyy/compiler/ProxyEntity.java
rename to AriaCompiler/src/main/java/com/arialyy/compiler/ProxyMethodParam.java
index 41573cfc..3cc813aa 100644
--- a/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyEntity.java
+++ b/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyMethodParam.java
@@ -22,12 +22,12 @@ import java.util.Set;
/**
* Created by Aria.Lao on 2017/6/7.
+ * 创建代理方法的参数
*/
-
-class ProxyEntity {
- public String packageName;
- public String className;
- public boolean isDownlaod = true;
- public Map> keyMappings = new HashMap<>();
- public Map, String> methods = new HashMap<>();
+class ProxyMethodParam {
+ String packageName;
+ String className;
+ Set taskEnums;
+ Map> keyMappings = new HashMap<>();
+ Map, String>> methods = new HashMap<>();
}
diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/TaskEnum.java b/AriaCompiler/src/main/java/com/arialyy/compiler/TaskEnum.java
new file mode 100644
index 00000000..7620f1df
--- /dev/null
+++ b/AriaCompiler/src/main/java/com/arialyy/compiler/TaskEnum.java
@@ -0,0 +1,53 @@
+/*
+ * 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.compiler;
+
+/**
+ * Created by Aria.Lao on 2017/7/10.
+ * 任务类型枚举
+ */
+enum TaskEnum {
+ DOWNLOAD("com.arialyy.aria.core.download", "DownloadTask",
+ "$$DownloadListenerProxy"), DOWNLOAD_GROUP("com.arialyy.aria.core.download",
+ "DownloadGroupTask", "$$DownloadGroupListenerProxy"), UPLOAD("com.arialyy.aria.core.upload",
+ "UploadTask", "$$UploadListenerProxy"), UPLOAD_GROUP("com.arialyy.aria.core.upload",
+ "UploadGroupTask", "$$UploadGroupListenerProxy");
+
+ String pkg, className, proxySuffix;
+
+ public String getClassName() {
+ return className;
+ }
+
+ public String getProxySuffix() {
+ return proxySuffix;
+ }
+
+ public String getPkg() {
+ return pkg;
+ }
+
+ /**
+ * @param pkg 包名
+ * @param className 任务完整类名
+ * @param proxySuffix 事件代理后缀
+ */
+ TaskEnum(String pkg, String className, String proxySuffix) {
+ this.pkg = pkg;
+ this.className = className;
+ this.proxySuffix = proxySuffix;
+ }
+}
diff --git a/README.md b/README.md
index e2776f14..1e8af13e 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# Aria
![图标](https://github.com/AriaLyy/DownloadUtil/blob/v_2.0/app/src/main/res/mipmap-hdpi/ic_launcher.png)
## [ENGLISH DOC](https://github.com/AriaLyy/Aria/blob/master/ENGLISH_README.md)
-Aria项目源于15年工作中遇到的一个文件下载管理的需求,当时被下载折磨的痛不欲生,从那时起便萌生了编写一个简单易用,稳当高效的下载框架,aria经历了1.0到3.0的开发,算是越来越接近当初所制定的目标了。
+Aria项目源于工作中遇到的一个文件下载管理的需求,当时被下载折磨的痛不欲生,从那时起便萌生了编写一个简单易用,稳当高效的下载框架,aria经历了1.0到3.0的开发,算是越来越接近当初所制定的目标了。
Aria有以下特点:
+ 简单、方便
@@ -13,7 +13,7 @@ Aria有以下特点:
- [一句代码实现速度限制](#常用接口)
- [通过修改配置文件很容易就能修改下载线程数](#配置文件设置参数)
- [优先下载某一个任务](#常用接口)
-
+ - [支持任务组下载,多个任务可共享一个progress](#一组任务下载)
+ 支持https地址下载
- 在配置文件中很容易就可以设置CA证书的信息
+ 支持300、301、302重定向下载链接下载
@@ -30,13 +30,14 @@ Aria怎样使用?
[![Download](https://api.bintray.com/packages/arialyy/maven/AriaApi/images/download.svg)](https://bintray.com/arialyy/maven/AriaApi/_latestVersion)
[![Download](https://api.bintray.com/packages/arialyy/maven/AriaCompiler/images/download.svg)](https://bintray.com/arialyy/maven/AriaCompiler/_latestVersion)
```java
-compile 'com.arialyy.aria:aria-core:3.2.0'
-annotationProcessor 'com.arialyy.aria:aria-compiler:3.2.0'
+compile 'com.arialyy.aria:aria-core:3.2.6'
+annotationProcessor 'com.arialyy.aria:aria-compiler:3.2.6'
```
## 示例
![多任务下载](https://github.com/AriaLyy/DownloadUtil/blob/master/img/download_img.gif)
![网速下载限制](https://github.com/AriaLyy/DownloadUtil/blob/master/img/max_speed.gif)
+![下载任务组](https://github.com/AriaLyy/DownloadUtil/blob/master/img/download_group.gif)
## 性能
![性能展示](https://github.com/AriaLyy/DownloadUtil/blob/master/img/performance.png)
@@ -51,15 +52,8 @@ annotationProcessor 'com.arialyy.aria:aria-compiler:3.2.0'
```
## 使用Aria进行下载
-* 添加任务(不进行下载),当其他下载任务完成时,将自动下载等待中的任务
- ```java
- Aria.download(this)
- .load(DOWNLOAD_URL)
- .setDownloadPath(DOWNLOAD_PATH) //文件保存路径
- .add();
- ```
-
-* 下载
+### 普通任务下载
+* 下载\恢复下载
```java
Aria.download(this)
@@ -72,15 +66,33 @@ annotationProcessor 'com.arialyy.aria:aria-compiler:3.2.0'
```java
Aria.download(this).load(DOWNLOAD_URL).pause();
```
-* 恢复下载
+
+* 取消下载
```java
- Aria.download(this).load(DOWNLOAD_URL).resume();
+ Aria.download(this).load(DOWNLOAD_URL).cancel();
```
+### 一组任务下载
+任务组的下载和普通任务的下载基本上差不多,区别在于,任务组下载不需要对每一个子任务设置保存路径,**但是需要设置任务组保存文件夹路径,所有子任务都保存在该文件夹下**
+
+* 下载\恢复下载
+
+ ```java
+ Aria.download(this)
+ .load(urls) //设置一主任务,参数为List
+ .setDownloadDirPath(groupDirPath) //设置任务组的文件夹路径
+ .start(); //启动下载
+ ```
+* 暂停
+
+ ```java
+ Aria.download(this).load(urls).pause();
+ ```
+
* 取消下载
```java
- Aria.download(this).load(DOWNLOAD_URL).cancel();
+ Aria.download(this).load(urls).cancel();
```
### 下载状态获取
@@ -97,12 +109,13 @@ annotationProcessor 'com.arialyy.aria:aria-compiler:3.2.0'
}
```
-2. 使用`@Download`或`@Upload`注解你的函数
- **注意:**
- - 注解回掉采用Apt的方式实现,所以,你不需要担心这会影响你机器的性能
- - 被注解的方法**不能被private修饰**
- - 被注解的方法**只能有一个参数,并且参数类型必须是`DownloadTask`或`UploadTask`**
- - 方法名可以为任意字符串
+2. 使用`@Download`或`@Upload`或`@DownloadGroup`注解你的函数
+
+ **注意:**
+ - 注解回掉采用Apt的方式实现,所以,你不需要担心这会影响你机器的性能
+ - 被注解的方法**不能被private修饰**
+ - 被注解的方法**只能有一个参数,并且参数类型必须是`DownloadTask`或`UploadTask`或`DownloadGroupTask`**
+ - 方法名可以为任意字符串
3. 除了在widget(Activity、Fragment、Dialog、Popupwindow)中使用注解方法外,你还可以在Service、Notification等组件中使用注解函数。
@@ -336,6 +349,7 @@ Aria.download(this).load(DOWNLOAD_URL).setExtendField(str)
## 开发日志
+ + v_3.2.6 移除广播事件,增加任务组下载功能
+ v_3.1.9 修复stopAll队列没有任务时崩溃的问题,增加针对单个任务监听的功能
+ v_3.1.7 修复某些文件下载不了的bug,增加apt注解方法,事件获取更加简单了
+ v_3.1.6 取消任务时onTaskCancel回调两次的bug
@@ -345,16 +359,6 @@ Aria.download(this).load(DOWNLOAD_URL).setExtendField(str)
+ v_3.0.3 修复暂停后删除任务,闪退问题,添加删除记录的api
+ v_3.0.2 支持30x重定向链接下载
+ v_3.0.0 添加上传任务支持,修复一些已发现的bug
- + v_2.4.4 修复不支持断点的下载链接拿不到文件大小的问题
- + v_2.4.3 修复404链接卡顿的问题
- + v_2.4.2 修复失败重试无效的bug
- + v_2.4.1 修复下载慢的问题,修复application、service 不能使用的问题
- + v_2.4.0 支持https链接下载
- + v_2.3.8 修复数据错乱的bug、添加fragment支持
- + v_2.3.6 添加dialog、popupWindow支持
- + v_2.3.3 添加断点支持、修改下载逻辑,让使用更加简单、修复一个内存泄露的bug
- + v_2.3.1 重命名为Aria,下载流程简化
- + v_2.1.1 增加,选择最大下载任务数接口
License
-------
diff --git a/app/build.gradle b/app/build.gradle
index 247814e2..c0683d76 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,7 +2,7 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 23
- buildToolsVersion '25.0.2'
+ buildToolsVersion '25.0.3'
defaultConfig {
applicationId "com.arialyy.simple"
@@ -42,7 +42,6 @@ dependencies {
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.arialyy.frame:MVVM2:2.2.0'
compile project(':Aria')
-// compile 'com.arialyy.aria:aria-core:3.1.8'
-// annotationProcessor 'com.arialyy.aria:aria-compiler:3.1.8'
+ compile project(':AriaCompiler')
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b91acce7..4443482d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -31,6 +31,7 @@
+
diff --git a/app/src/main/assets/aria_config.xml b/app/src/main/assets/aria_config.xml
index f9ed36f3..474752d0 100644
--- a/app/src/main/assets/aria_config.xml
+++ b/app/src/main/assets/aria_config.xml
@@ -7,9 +7,6 @@
-
-
-
@@ -34,11 +31,12 @@
+
+
+
-
-
diff --git a/app/src/main/java/com/arialyy/simple/MainActivity.java b/app/src/main/java/com/arialyy/simple/MainActivity.java
index 7b315dab..5867a402 100644
--- a/app/src/main/java/com/arialyy/simple/MainActivity.java
+++ b/app/src/main/java/com/arialyy/simple/MainActivity.java
@@ -18,14 +18,12 @@ package com.arialyy.simple;
import android.content.Intent;
import android.os.Bundle;
-import android.support.v7.widget.Toolbar;
import android.view.View;
-import butterknife.Bind;
import butterknife.OnClick;
-import com.arialyy.aria.core.Aria;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.ActivityMainBinding;
import com.arialyy.simple.download.DownloadActivity;
+import com.arialyy.simple.download.group.DownloadGroupActivity;
import com.arialyy.simple.test.TestMutilTaskSysDownload;
import com.arialyy.simple.upload.UploadActivity;
@@ -45,15 +43,20 @@ public class MainActivity extends BaseActivity {
return R.layout.activity_main;
}
- @OnClick(R.id.download) public void downloadDemo() {
- startActivity(new Intent(this, DownloadActivity.class));
- }
- @OnClick(R.id.upload) public void uploadDemo() {
- startActivity(new Intent(this, UploadActivity.class));
- }
+ @OnClick({R.id.download, R.id.upload, R.id.download_task_group})
+ public void funcation(View view){
+ switch (view.getId()){
+ case R.id.download:
+ startActivity(new Intent(this, DownloadActivity.class));
+ break;
+ case R.id.upload:
+ startActivity(new Intent(this, UploadActivity.class));
+ break;
+ case R.id.download_task_group:
+ startActivity(new Intent(this, DownloadGroupActivity.class));
+ break;
+ }
- @OnClick(R.id.multi_test) public void mutliTest() {
- startActivity(new Intent(this, TestMutilTaskSysDownload.class));
}
}
diff --git a/app/src/main/java/com/arialyy/simple/base/BaseApplication.java b/app/src/main/java/com/arialyy/simple/base/BaseApplication.java
index 117a34dd..29cda1b9 100644
--- a/app/src/main/java/com/arialyy/simple/base/BaseApplication.java
+++ b/app/src/main/java/com/arialyy/simple/base/BaseApplication.java
@@ -17,7 +17,10 @@
package com.arialyy.simple.base;
import android.app.Application;
+import android.os.Build;
+import android.os.StrictMode;
import com.arialyy.frame.core.AbsFrame;
+import com.arialyy.simple.BuildConfig;
/**
* Created by Lyy on 2016/9/27.
@@ -26,5 +29,11 @@ public class BaseApplication extends Application {
@Override public void onCreate() {
super.onCreate();
AbsFrame.init(this);
+
+ if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
+ StrictMode.setThreadPolicy(
+ new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
+ StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build());
+ }
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/arialyy/simple/base/adapter/AbsRVAdapter.java b/app/src/main/java/com/arialyy/simple/base/adapter/AbsRVAdapter.java
index 744ccd94..e7eecd4a 100644
--- a/app/src/main/java/com/arialyy/simple/base/adapter/AbsRVAdapter.java
+++ b/app/src/main/java/com/arialyy/simple/base/adapter/AbsRVAdapter.java
@@ -16,6 +16,8 @@
package com.arialyy.simple.base.adapter;
import android.content.Context;
+import android.databinding.DataBindingUtil;
+import android.databinding.ViewDataBinding;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
@@ -45,6 +47,9 @@ public abstract class AbsRVAdapter
@Override public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
View view =
LayoutInflater.from(parent.getContext()).inflate(setLayoutId(viewType), parent, false);
+ //LayoutInflater inflater = LayoutInflater.from(parent.getContext());
+ //VD binding = DataBindingUtil.inflate(inflater, setLayoutId(viewType), parent, false);
+ //;
holder = getViewHolder(view, viewType);
return holder;
}
@@ -55,6 +60,14 @@ public abstract class AbsRVAdapter
bindData(holder, position, mData.get(position));
}
+ @Override public void onBindViewHolder(Holder holder, int position, List payloads) {
+ if (payloads == null || payloads.isEmpty()) {
+ bindData(holder, position, mData.get(position));
+ } else {
+ bindData(holder, position, mData.get(position), payloads);
+ }
+ }
+
public Context getContext() {
return mContext;
}
@@ -69,4 +82,8 @@ public abstract class AbsRVAdapter
protected abstract int setLayoutId(int type);
protected abstract void bindData(Holder holder, int position, T item);
+
+ protected void bindData(Holder holder, int position, T item, List payloads) {
+
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/arialyy/simple/download/DownloadModule.java b/app/src/main/java/com/arialyy/simple/download/DownloadModule.java
index f4c2e831..faef1cf3 100644
--- a/app/src/main/java/com/arialyy/simple/download/DownloadModule.java
+++ b/app/src/main/java/com/arialyy/simple/download/DownloadModule.java
@@ -16,27 +16,16 @@
package com.arialyy.simple.download;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.content.res.Resources;
import android.os.Environment;
-import android.os.Handler;
-import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadEntity;
-import com.arialyy.aria.util.CommonUtil;
-import com.arialyy.frame.util.AndroidUtils;
-import com.arialyy.frame.util.StringUtil;
-import com.arialyy.frame.util.show.L;
import com.arialyy.simple.R;
import com.arialyy.simple.download.multi_download.FileListEntity;
import com.arialyy.simple.base.BaseModule;
-import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
-import java.util.Random;
/**
* Created by Lyy on 2016/9/27.
@@ -92,69 +81,4 @@ public class DownloadModule extends BaseModule {
return entity;
}
- /**
- * 下载广播过滤器
- */
- public IntentFilter getDownloadFilter() {
- IntentFilter filter = new IntentFilter();
- filter.addDataScheme(getContext().getPackageName());
- filter.addAction(Aria.ACTION_PRE);
- filter.addAction(Aria.ACTION_POST_PRE);
- filter.addAction(Aria.ACTION_RESUME);
- filter.addAction(Aria.ACTION_START);
- filter.addAction(Aria.ACTION_RUNNING);
- filter.addAction(Aria.ACTION_STOP);
- filter.addAction(Aria.ACTION_CANCEL);
- filter.addAction(Aria.ACTION_COMPLETE);
- filter.addAction(Aria.ACTION_FAIL);
- return filter;
- }
-
- /**
- * 创建Receiver
- */
- public BroadcastReceiver createReceiver(final Handler handler) {
-
- return new BroadcastReceiver() {
- long len = 0;
-
- @Override public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- switch (action) {
- case Aria.ACTION_POST_PRE:
- DownloadEntity entity = intent.getParcelableExtra(Aria.DOWNLOAD_ENTITY);
- len = entity.getFileSize();
- L.d(TAG, "download onPre");
- handler.obtainMessage(SingleTaskActivity.DOWNLOAD_PRE, len).sendToTarget();
- break;
- case Aria.ACTION_START:
- L.d(TAG, "download start");
- break;
- case Aria.ACTION_RESUME:
- L.d(TAG, "download resume");
- long location = intent.getLongExtra(Aria.CURRENT_LOCATION, 1);
- handler.obtainMessage(SingleTaskActivity.DOWNLOAD_RESUME, location).sendToTarget();
- break;
- case Aria.ACTION_RUNNING:
- long current = intent.getLongExtra(Aria.CURRENT_LOCATION, 0);
- int progress = len == 0 ? 0 : (int) ((current * 100) / len);
- handler.obtainMessage(SingleTaskActivity.DOWNLOAD_RUNNING, progress).sendToTarget();
- break;
- case Aria.ACTION_STOP:
- L.d(TAG, "download stop");
- handler.sendEmptyMessage(SingleTaskActivity.DOWNLOAD_STOP);
- break;
- case Aria.ACTION_COMPLETE:
- handler.sendEmptyMessage(SingleTaskActivity.DOWNLOAD_COMPLETE);
- break;
- case Aria.ACTION_CANCEL:
- handler.sendEmptyMessage(SingleTaskActivity.DOWNLOAD_CANCEL);
- break;
- case Aria.ACTION_FAIL:
- handler.sendEmptyMessage(SingleTaskActivity.DOWNLOAD_FAILE);
- break;
- }
- }
- };
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/arialyy/simple/download/HighestPriorityActivity.java b/app/src/main/java/com/arialyy/simple/download/HighestPriorityActivity.java
index aee06f79..611861dd 100644
--- a/app/src/main/java/com/arialyy/simple/download/HighestPriorityActivity.java
+++ b/app/src/main/java/com/arialyy/simple/download/HighestPriorityActivity.java
@@ -29,6 +29,7 @@ import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTarget;
import com.arialyy.aria.core.download.DownloadTask;
+import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.frame.util.show.L;
import com.arialyy.simple.R;
@@ -58,7 +59,7 @@ public class HighestPriorityActivity extends BaseActivity mData = new ArrayList<>();
+ private List mData = new ArrayList<>();
private Set mRecord = new HashSet<>();
@Override protected int setLayoutId() {
@@ -83,7 +84,7 @@ public class HighestPriorityActivity extends BaseActivity temp = Aria.download(this).getTaskList();
+ List temp = Aria.download(this).getSimpleTaskList();
if (temp != null && !temp.isEmpty()) {
for (DownloadEntity entity : temp) {
if (entity.getDownloadUrl().equals(DOWNLOAD_URL)) continue;
diff --git a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java
index 6e3b468e..5e4612fa 100644
--- a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java
+++ b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java
@@ -16,15 +16,8 @@
package com.arialyy.simple.download;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
-import android.os.Handler;
-import android.os.Message;
-import android.support.v7.widget.Toolbar;
-import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -36,33 +29,20 @@ import butterknife.Bind;
import com.arialyy.annotations.Download;
import com.arialyy.aria.core.download.DownloadTarget;
import com.arialyy.aria.core.Aria;
-import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.inf.IEntity;
-import com.arialyy.aria.util.CommonUtil;
-import com.arialyy.frame.util.FileUtil;
-import com.arialyy.frame.util.show.L;
import com.arialyy.frame.util.show.T;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.ActivitySingleBinding;
-import com.arialyy.simple.widget.HorizontalProgressBarWithNumber;
-import java.io.File;
public class SingleTaskActivity extends BaseActivity {
- public static final int DOWNLOAD_PRE = 0x01;
- public static final int DOWNLOAD_STOP = 0x02;
- public static final int DOWNLOAD_FAILE = 0x03;
- public static final int DOWNLOAD_CANCEL = 0x04;
- public static final int DOWNLOAD_RESUME = 0x05;
- public static final int DOWNLOAD_COMPLETE = 0x06;
- public static final int DOWNLOAD_RUNNING = 0x07;
- public static final int DOWNLOAD_START = 0x08;
private static final String DOWNLOAD_URL =
//"http://kotlinlang.org/docs/kotlin-docs.pdf";
//"https://atom-installer.github.com/v1.13.0/AtomSetup.exe?s=1484074138&ext=.exe";
"http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk";
+ //"http://down2.xiaoshuofuwuqi.com/d/file/filetxt/20170608/14/%BA%DA%CE%D7%CA%A6%E1%C8%C6%F0.txt";
//"http://tinghuaapp.oss-cn-shanghai.aliyuncs.com/20170612201739607815";
//"http://static.gaoshouyou.com/d/36/69/2d3699acfa69e9632262442c46516ad8.apk";
//"http://oqcpqqvuf.bkt.clouddn.com/ceshi.txt";
@@ -70,65 +50,11 @@ public class SingleTaskActivity extends BaseActivity {
//不支持断点的链接
//"http://ox.konsung.net:5555/ksdc-web/download/downloadFile/?fileName=ksdc_1.0.2.apk&rRange=0-";
//"http://172.18.104.50:8080/download/_302turn";
- @Bind(R.id.progressBar) HorizontalProgressBarWithNumber mPb;
@Bind(R.id.start) Button mStart;
@Bind(R.id.stop) Button mStop;
@Bind(R.id.cancel) Button mCancel;
- @Bind(R.id.size) TextView mSize;
- @Bind(R.id.speed) TextView mSpeed;
@Bind(R.id.speeds) RadioGroup mRg;
- private Handler mUpdateHandler = new Handler() {
- @Override public void handleMessage(Message msg) {
- super.handleMessage(msg);
- switch (msg.what) {
- case DOWNLOAD_RUNNING:
- DownloadTask task = (DownloadTask) msg.obj;
- long current = task.getCurrentProgress();
- long len = task.getFileSize();
- if (len == 0) {
- mPb.setProgress(0);
- } else {
- mPb.setProgress((int) ((current * 100) / len));
- }
- mSpeed.setText(task.getConvertSpeed());
- break;
- case DOWNLOAD_PRE:
- setBtState(false);
- break;
- case DOWNLOAD_START:
- mSize.setText(CommonUtil.formatFileSize((Long) msg.obj));
- break;
- case DOWNLOAD_FAILE:
- Toast.makeText(SingleTaskActivity.this, "下载失败", Toast.LENGTH_SHORT).show();
- setBtState(true);
- break;
- case DOWNLOAD_STOP:
- Toast.makeText(SingleTaskActivity.this, "暂停下载", Toast.LENGTH_SHORT).show();
- mStart.setText("恢复");
- setBtState(true);
- break;
- case DOWNLOAD_CANCEL:
- mPb.setProgress(0);
- Toast.makeText(SingleTaskActivity.this, "取消下载", Toast.LENGTH_SHORT).show();
- mStart.setText("开始");
- setBtState(true);
- break;
- case DOWNLOAD_RESUME:
- mStart.setText("暂停");
- setBtState(false);
- break;
- case DOWNLOAD_COMPLETE:
- mPb.setProgress(100);
- Toast.makeText(SingleTaskActivity.this, "下载完成", Toast.LENGTH_SHORT).show();
- mStart.setText("重新开始?");
- mCancel.setEnabled(false);
- setBtState(true);
- break;
- }
- }
- };
-
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Aria.download(this).register();
@@ -153,7 +79,7 @@ public class SingleTaskActivity extends BaseActivity {
switch (item.getItemId()) {
case R.id.help:
msg = "一些小知识点:\n"
- + "1、你可以通过task.getKey().equals(DOWNLOAD_URL)判断是否是当前页面的下载,以防止progress乱跳\n"
+ + "1、你可以在注解中增加链接,用于指定被注解的方法只能被特定的下载任务回调,以防止progress乱跳\n"
+ "2、当遇到网络慢的情况时,你可以先使用onPre()更新UI界面,待连接成功时,再在onTaskPre()获取完整的task数据,然后给UI界面设置正确的数据\n"
+ "3、你可以在界面初始化时通过Aria.download(this).load(DOWNLOAD_URL).getPercent()等方法快速获取相关任务的一些数据";
showMsgDialog("tip", msg);
@@ -183,40 +109,54 @@ public class SingleTaskActivity extends BaseActivity {
}
@Download.onPre(DOWNLOAD_URL) protected void onPre(DownloadTask task) {
- mUpdateHandler.obtainMessage(DOWNLOAD_PRE, task.getDownloadEntity().getFileSize())
- .sendToTarget();
+ setBtState(false);
}
@Download.onTaskStart(DOWNLOAD_URL) void taskStart(DownloadTask task) {
- mUpdateHandler.obtainMessage(DOWNLOAD_START, task.getDownloadEntity().getFileSize())
- .sendToTarget();
+ getBinding().setFileSize(task.getConvertFileSize());
}
@Download.onTaskRunning(DOWNLOAD_URL) protected void running(DownloadTask task) {
- mUpdateHandler.obtainMessage(DOWNLOAD_RUNNING, task).sendToTarget();
+ long len = task.getFileSize();
+ if (len == 0) {
+ getBinding().setProgress(0);
+ } else {
+ getBinding().setProgress(task.getPercent());
+ }
+ getBinding().setSpeed(task.getConvertSpeed());
}
@Download.onTaskResume(DOWNLOAD_URL) void taskResume(DownloadTask task) {
- mUpdateHandler.obtainMessage(DOWNLOAD_START, task.getFileSize()).sendToTarget();
+ mStart.setText("暂停");
+ setBtState(false);
}
@Download.onTaskStop(DOWNLOAD_URL) void taskStop(DownloadTask task) {
- mUpdateHandler.sendEmptyMessage(DOWNLOAD_STOP);
- L.d(TAG, "task__stop");
+ mStart.setText("恢复");
+ setBtState(true);
+ getBinding().setSpeed("");
}
@Download.onTaskCancel(DOWNLOAD_URL) void taskCancel(DownloadTask task) {
- mUpdateHandler.sendEmptyMessage(DOWNLOAD_CANCEL);
- L.d(TAG, "task__cancel");
+ getBinding().setProgress(0);
+ Toast.makeText(SingleTaskActivity.this, "取消下载", Toast.LENGTH_SHORT).show();
+ mStart.setText("开始");
+ setBtState(true);
+ getBinding().setSpeed("");
}
@Download.onTaskFail(DOWNLOAD_URL) void taskFail(DownloadTask task) {
- L.d(TAG, "task__fail");
- mUpdateHandler.sendEmptyMessage(DOWNLOAD_FAILE);
+ Toast.makeText(SingleTaskActivity.this, "下载失败", Toast.LENGTH_SHORT).show();
+ setBtState(true);
}
@Download.onTaskComplete(DOWNLOAD_URL) void taskComplete(DownloadTask task) {
- mUpdateHandler.sendEmptyMessage(DOWNLOAD_COMPLETE);
+ getBinding().setProgress(100);
+ Toast.makeText(SingleTaskActivity.this, "下载完成", Toast.LENGTH_SHORT).show();
+ mStart.setText("重新开始?");
+ mCancel.setEnabled(false);
+ setBtState(true);
+ getBinding().setSpeed("");
}
@Download.onNoSupportBreakPoint(DOWNLOAD_URL)
@@ -232,7 +172,7 @@ public class SingleTaskActivity extends BaseActivity {
super.init(savedInstanceState);
setTitle("单任务下载");
DownloadTarget target = Aria.download(this).load(DOWNLOAD_URL);
- mPb.setProgress(target.getPercent());
+ getBinding().setProgress(target.getPercent());
if (target.getTaskState() == IEntity.STATE_STOP) {
mStart.setText("恢复");
mStart.setTextColor(getResources().getColor(android.R.color.holo_blue_light));
@@ -240,8 +180,7 @@ public class SingleTaskActivity extends BaseActivity {
} else if (target.isDownloading()) {
setBtState(false);
}
- mSize.setText(target.getConvertFileSize());
- Aria.get(this).getDownloadConfig().setOpenBreadCast(true);
+ getBinding().setFileSize(target.getConvertFileSize());
}
public void onClick(View view) {
@@ -251,6 +190,7 @@ public class SingleTaskActivity extends BaseActivity {
if (text.equals("重新开始?") || text.equals("开始")) {
Aria.download(this)
.load(DOWNLOAD_URL)
+ .addHeader("groupName", "value")
.setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/test.apk")
.start();
} else if (text.equals("恢复")) {
diff --git a/app/src/main/java/com/arialyy/simple/download/fragment_download/DownloadFragment.java b/app/src/main/java/com/arialyy/simple/download/fragment_download/DownloadFragment.java
index d78f82fe..8e34589b 100644
--- a/app/src/main/java/com/arialyy/simple/download/fragment_download/DownloadFragment.java
+++ b/app/src/main/java/com/arialyy/simple/download/fragment_download/DownloadFragment.java
@@ -38,25 +38,20 @@ import com.arialyy.simple.widget.HorizontalProgressBarWithNumber;
* Created by Aria.Lao on 2017/1/4.
*/
public class DownloadFragment extends AbsFragment {
- @Bind(R.id.progressBar) HorizontalProgressBarWithNumber mPb;
@Bind(R.id.start) Button mStart;
@Bind(R.id.stop) Button mStop;
@Bind(R.id.cancel) Button mCancel;
- @Bind(R.id.size) TextView mSize;
- @Bind(R.id.speed) TextView mSpeed;
- private static final String DOWNLOAD_URL =
- "http://static.ilongyuan.cn/rayark/RayarkFZ_2.0.7.apk";
+ private static final String DOWNLOAD_URL = "http://static.ilongyuan.cn/rayark/RayarkFZ_2.0.7.apk";
@Override protected void init(Bundle savedInstanceState) {
if (Aria.download(this).taskExists(DOWNLOAD_URL)) {
DownloadTarget target = Aria.download(this).load(DOWNLOAD_URL);
- int p = (int) (target.getCurrentProgress() * 100 / target.getFileSize());
- mPb.setProgress(p);
+ getBinding().setProgress(target.getPercent());
}
DownloadEntity entity = Aria.download(this).getDownloadEntity(DOWNLOAD_URL);
if (entity != null) {
- mSize.setText(CommonUtil.formatFileSize(entity.getFileSize()));
+ getBinding().setFileSize(CommonUtil.formatFileSize(entity.getFileSize()));
int state = entity.getState();
setBtState(state != DownloadEntity.STATE_RUNNING);
} else {
@@ -83,30 +78,29 @@ public class DownloadFragment extends AbsFragment {
}
@Download.onTaskPre public void onTaskPre(DownloadTask task) {
- mSize.setText(CommonUtil.formatFileSize(task.getFileSize()));
+ getBinding().setFileSize(task.getConvertFileSize());
setBtState(false);
}
@Download.onTaskStop public void onTaskStop(DownloadTask task) {
setBtState(true);
- mSpeed.setText("0.0kb/s");
+ getBinding().setSpeed("0.0kb/s");
}
@Download.onTaskCancel public void onTaskCancel(DownloadTask task) {
setBtState(true);
- mPb.setProgress(0);
- mSpeed.setText("0.0kb/s");
+ getBinding().setProgress(0);
+ getBinding().setSpeed("0.0kb/s");
}
@Download.onTaskRunning public void onTaskRunning(DownloadTask task) {
- long current = task.getCurrentProgress();
long len = task.getFileSize();
if (len == 0) {
- mPb.setProgress(0);
+ getBinding().setProgress(0);
} else {
- mPb.setProgress((int) ((current * 100) / len));
+ getBinding().setProgress(task.getPercent());
}
- mSpeed.setText(task.getConvertSpeed());
+ getBinding().setSpeed(task.getConvertSpeed());
}
@Override protected void onDelayLoad() {
diff --git a/app/src/main/java/com/arialyy/simple/download/group/DownloadGroupActivity.java b/app/src/main/java/com/arialyy/simple/download/group/DownloadGroupActivity.java
new file mode 100644
index 00000000..b5471182
--- /dev/null
+++ b/app/src/main/java/com/arialyy/simple/download/group/DownloadGroupActivity.java
@@ -0,0 +1,131 @@
+/*
+ * 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.simple.download.group;
+
+import android.os.Bundle;
+import android.os.Environment;
+import android.view.View;
+import android.widget.Button;
+import butterknife.Bind;
+import com.arialyy.annotations.DownloadGroup;
+import com.arialyy.aria.core.Aria;
+import com.arialyy.aria.core.download.DownloadGroupEntity;
+import com.arialyy.aria.core.download.DownloadGroupTask;
+import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
+import com.arialyy.frame.util.show.L;
+import com.arialyy.frame.util.show.T;
+import com.arialyy.simple.R;
+import com.arialyy.simple.base.BaseActivity;
+import com.arialyy.simple.databinding.ActivityDownloadGroupBinding;
+import com.arialyy.simple.widget.SubStateLinearLayout;
+import java.util.List;
+
+/**
+ * Created by Aria.Lao on 2017/7/6.
+ */
+public class DownloadGroupActivity extends BaseActivity {
+
+ @Bind(R.id.start) Button mStart;
+ @Bind(R.id.stop) Button mStop;
+ @Bind(R.id.cancel) Button mCancel;
+ @Bind(R.id.child_list) SubStateLinearLayout mChildList;
+ List mUrls;
+
+ @Override protected void init(Bundle savedInstanceState) {
+ super.init(savedInstanceState);
+ Aria.download(this).register();
+ setTitle("任务组");
+ mUrls = getModule(GroupModule.class).getUrls();
+ DownloadGroupTaskEntity entity = Aria.download(this).getDownloadGroupTask(mUrls);
+ if (entity != null && entity.getEntity() != null) {
+ DownloadGroupEntity groupEntity = entity.getEntity();
+ mChildList.addData(groupEntity.getSubTask());
+ getBinding().setFileSize(groupEntity.getConvertFileSize());
+ if (groupEntity.getFileSize() == 0) {
+ getBinding().setProgress(0);
+ } else {
+ getBinding().setProgress(groupEntity.isComplete() ? 100
+ : (int) (groupEntity.getCurrentProgress() * 100 / groupEntity.getFileSize()));
+ }
+ }
+ }
+
+ @Override protected int setLayoutId() {
+ return R.layout.activity_download_group;
+ }
+
+ public void onClick(View view) {
+ switch (view.getId()) {
+ case R.id.start:
+ Aria.download(this)
+ .load(mUrls)
+ .setDownloadDirPath(
+ Environment.getExternalStorageDirectory().getPath() + "/Download/group_test_3")
+ .setGroupAlias("任务组测试")
+ .setSubTaskFileName(getModule(GroupModule.class).getSubName())
+ .start();
+ break;
+ case R.id.stop:
+ Aria.download(this).load(mUrls).stop();
+ break;
+ case R.id.cancel:
+ Aria.download(this).load(mUrls).cancel();
+ break;
+ }
+ }
+
+ @DownloadGroup.onPre() protected void onPre(DownloadGroupTask task) {
+ L.d(TAG, "group pre");
+ }
+
+ @DownloadGroup.onTaskPre() protected void onTaskPre(DownloadGroupTask task) {
+ L.d(TAG, "group task pre");
+ getBinding().setFileSize(task.getConvertFileSize());
+ }
+
+ @DownloadGroup.onTaskStart() void taskStart(DownloadGroupTask task) {
+ L.d(TAG, "group task start");
+ }
+
+ @DownloadGroup.onTaskRunning() protected void running(DownloadGroupTask task) {
+ getBinding().setProgress(task.getPercent());
+ getBinding().setSpeed(task.getConvertSpeed());
+ mChildList.updateChildProgress(task.getEntity().getSubTask());
+ }
+
+ @DownloadGroup.onTaskResume() void taskResume(DownloadGroupTask task) {
+ L.d(TAG, "group task resume");
+ }
+
+ @DownloadGroup.onTaskStop() void taskStop(DownloadGroupTask task) {
+ L.d(TAG, "group task stop");
+ getBinding().setSpeed("");
+ }
+
+ @DownloadGroup.onTaskCancel() void taskCancel(DownloadGroupTask task) {
+ getBinding().setSpeed("");
+ getBinding().setProgress(0);
+ }
+
+ @DownloadGroup.onTaskFail() void taskFail(DownloadGroupTask task) {
+ L.d(TAG, "group task fail");
+ }
+
+ @DownloadGroup.onTaskComplete() void taskComplete(DownloadGroupTask task) {
+ getBinding().setProgress(100);
+ T.showShort(this, "任务组下载完成");
+ }
+}
diff --git a/app/src/main/java/com/arialyy/simple/download/group/GroupModule.java b/app/src/main/java/com/arialyy/simple/download/group/GroupModule.java
new file mode 100644
index 00000000..221212e4
--- /dev/null
+++ b/app/src/main/java/com/arialyy/simple/download/group/GroupModule.java
@@ -0,0 +1,54 @@
+/*
+ * 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.simple.download.group;
+
+import android.content.Context;
+import com.arialyy.simple.R;
+import com.arialyy.simple.base.BaseModule;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Created by Aria.Lao on 2017/7/6.
+ */
+public class GroupModule extends BaseModule {
+ public GroupModule(Context context) {
+ super(context);
+ }
+
+ List getUrls() {
+ List urls = new ArrayList<>();
+ String[] str = getContext().getResources().getStringArray(R.array.group_urls);
+ Collections.addAll(urls, str);
+ return urls;
+ }
+
+ List getSubName(){
+ List names = new ArrayList<>();
+ String[] str = getContext().getResources().getStringArray(R.array.group_names);
+ Collections.addAll(names, str);
+ return names;
+ }
+
+ //NormalList