子任务管理器

pull/330/head
AriaLyy 7 years ago
parent 3b30d31b8e
commit ac99cc581f
  1. 103
      Aria/src/main/java/com/arialyy/aria/core/SubTaskManager.java
  2. 3
      Aria/src/main/java/com/arialyy/aria/core/command/AbsCmd.java
  3. 4
      Aria/src/main/java/com/arialyy/aria/core/command/AbsCmdFactory.java
  4. 25
      Aria/src/main/java/com/arialyy/aria/core/command/group/AbsGroupCmd.java
  5. 8
      Aria/src/main/java/com/arialyy/aria/core/command/group/GroupCancelCmd.java
  6. 45
      Aria/src/main/java/com/arialyy/aria/core/command/group/GroupCmdFactory.java
  7. 45
      Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStartCmd.java
  8. 8
      Aria/src/main/java/com/arialyy/aria/core/command/group/GroupStopCmd.java
  9. 5
      Aria/src/main/java/com/arialyy/aria/core/command/normal/NormalCmdFactory.java
  10. 19
      Aria/src/main/java/com/arialyy/aria/core/download/BaseGroupTarget.java
  11. 13
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java
  12. 2
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java
  13. 4
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTaskEntity.java
  14. 2
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java
  15. 52
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/AbsGroupUtil.java
  16. 4
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsDownloadTarget.java
  17. 16
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsGroupEntity.java
  18. 36
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsGroupTask.java
  19. 10
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java
  20. 26
      Aria/src/main/java/com/arialyy/aria/core/inf/BaseGroupTaskEntity.java
  21. 2
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java
  22. 34
      Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java
  23. 79
      AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java
  24. 123
      app/src/main/java/com/arialyy/simple/download/group/ChildHandleDialog.java
  25. 23
      app/src/main/java/com/arialyy/simple/download/group/DownloadGroupActivity.java
  26. 44
      app/src/main/java/com/arialyy/simple/widget/SubStateLinearLayout.java
  27. 5
      app/src/main/res/anim/dialog_enter.xml
  28. 6
      app/src/main/res/anim/dialog_exit.xml
  29. 14
      app/src/main/res/layout/activity_download_group.xml
  30. 76
      app/src/main/res/layout/dialog_sub_task_handler.xml
  31. 14
      app/src/main/res/layout/test_activity_multi.xml
  32. 4
      app/src/main/res/values/strings.xml
  33. 17
      app/src/main/res/values/styles.xml

@ -0,0 +1,103 @@
/*
* 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;
import android.text.TextUtils;
import android.util.Log;
import com.arialyy.aria.core.command.group.GroupCmdFactory;
import com.arialyy.aria.core.inf.BaseGroupTaskEntity;
import com.arialyy.aria.util.CommonUtil;
import java.util.List;
/**
* Created by lyy on 2017/9/4.
* 子任务管理器
*/
public class SubTaskManager {
private String TAG = "SubTaskManager";
private BaseGroupTaskEntity mEntity;
private String mTargetName;
public SubTaskManager(String targetName, BaseGroupTaskEntity entity) {
mTargetName = targetName;
mEntity = entity;
}
/**
* 启动任务组中的子任务
*
* @param url 子任务下载地址
*/
public void startSubTask(String url) {
if (checkUrl(url)) {
AriaManager.getInstance(AriaManager.APP)
.setCmd(
CommonUtil.createGroupCmd(mTargetName, mEntity, GroupCmdFactory.SUB_TASK_START, url))
.exe();
}
}
/**
* 停止任务组中的子任务
*
* @param url 子任务下载地址
*/
public void stopSubTask(String url) {
if (checkUrl(url)) {
AriaManager.getInstance(AriaManager.APP)
.setCmd(
CommonUtil.createGroupCmd(mTargetName, mEntity, GroupCmdFactory.SUB_TASK_STOP, url))
.exe();
}
}
/**
* 删除子任务组中的子任务
*
* @param url 子任务下载地址
*/
public void cancelSubTask(String url) {
if (checkUrl(url)) {
AriaManager.getInstance(AriaManager.APP)
.setCmd(
CommonUtil.createGroupCmd(mTargetName, mEntity, GroupCmdFactory.SUB_TASK_CANCEL, url))
.exe();
}
}
/**
* 检查任务地址
*
* @param url 子任务地址
* @return {@code false} 任务地址不合法
*/
private boolean checkUrl(String url) {
if (TextUtils.isEmpty(url)) {
Log.e(TAG, "子任务地址不能为null");
return false;
}
List<String> urls = mEntity.getEntity().getUrls();
if (urls == null || urls.isEmpty()) {
Log.e(TAG, "任务组任务链接为null");
return false;
}
if (!urls.contains(url)) {
Log.e(TAG, "任务组中没有改Url【+ " + url + "】");
return false;
}
return true;
}
}

@ -22,11 +22,12 @@ import com.arialyy.aria.core.queue.ITaskQueue;
/** /**
* Created by AriaL on 2017/6/29. * Created by AriaL on 2017/6/29.
*/ */
public abstract class AbsCmd<T extends AbsTaskEntity> implements ICmd{ public abstract class AbsCmd<T extends AbsTaskEntity> implements ICmd {
protected ITaskQueue mQueue; protected ITaskQueue mQueue;
protected T mTaskEntity; protected T mTaskEntity;
protected String TAG; protected String TAG;
protected String mTargetName; protected String mTargetName;
/** /**
* 是否是下载任务的命令 * 是否是下载任务的命令
* {@code true} 下载任务的命令{@code false} 上传任务的命令 * {@code true} 下载任务的命令{@code false} 上传任务的命令

@ -21,11 +21,11 @@ import com.arialyy.aria.core.inf.AbsTaskEntity;
* Created by AriaL on 2017/6/29. * Created by AriaL on 2017/6/29.
* 抽象命令工厂 * 抽象命令工厂
*/ */
public abstract class AbsCmdFactory<CMD extends AbsCmd> { public abstract class AbsCmdFactory<TASK_ENTITY extends AbsTaskEntity, CMD extends AbsCmd> {
/** /**
* @param target 创建任务的对象 * @param target 创建任务的对象
* @param entity 下载实体 * @param entity 下载实体
*/ */
public abstract <T extends AbsTaskEntity> CMD createCmd(String target, T entity, int type); public abstract CMD createCmd(String target, TASK_ENTITY entity, int type);
} }

@ -15,21 +15,25 @@
*/ */
package com.arialyy.aria.core.command.group; package com.arialyy.aria.core.command.group;
import android.util.Log;
import com.arialyy.aria.core.command.AbsCmd; import com.arialyy.aria.core.command.AbsCmd;
import com.arialyy.aria.core.download.DownloadGroupTaskEntity; import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.inf.AbsGroupTask;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.BaseGroupTaskEntity;
import com.arialyy.aria.core.queue.DownloadGroupTaskQueue; 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; import com.arialyy.aria.util.CommonUtil;
/** /**
* Created by AriaL on 2017/6/29. * Created by AriaL on 2017/6/29.
* 任务组命令 * 任务组命令
*/ */
abstract class AbsGroupCmd<T extends AbsTaskEntity> extends AbsCmd<T> { public abstract class AbsGroupCmd<T extends BaseGroupTaskEntity> extends AbsCmd<T> {
/**
* 需要控制的子任务url
*/
String childUrl;
AbsGroupTask tempTask;
/** /**
* @param targetName 创建任务的对象名 * @param targetName 创建任务的对象名
@ -43,4 +47,13 @@ abstract class AbsGroupCmd<T extends AbsTaskEntity> extends AbsCmd<T> {
isDownloadCmd = true; isDownloadCmd = true;
} }
} }
boolean checkTask() {
tempTask = (AbsGroupTask) mQueue.getTask(mTaskEntity.getEntity());
if (tempTask == null || !tempTask.isRunning()) {
Log.d(TAG, "任务组没有执行,先执行任务组任务才能够执行子任务");
return false;
}
return true;
}
} }

@ -15,13 +15,13 @@
*/ */
package com.arialyy.aria.core.command.group; package com.arialyy.aria.core.command.group;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.BaseGroupTaskEntity;
/** /**
* Created by AriaL on 2017/6/29. * Created by AriaL on 2017/6/29.
* 删除任务组 * 删除任务组
*/ */
class GroupCancelCmd<T extends AbsTaskEntity> extends AbsGroupCmd<T> { class GroupCancelCmd<T extends BaseGroupTaskEntity> extends AbsGroupCmd<T> {
/** /**
* @param targetName 创建任务的对象名 * @param targetName 创建任务的对象名
*/ */
@ -30,6 +30,8 @@ class GroupCancelCmd<T extends AbsTaskEntity> extends AbsGroupCmd<T> {
} }
@Override public void executeCmd() { @Override public void executeCmd() {
if (checkTask()) {
tempTask.cancelSubTask(childUrl);
}
} }
} }

@ -16,25 +16,25 @@
package com.arialyy.aria.core.command.group; package com.arialyy.aria.core.command.group;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.command.AbsCmdFactory; import com.arialyy.aria.core.inf.BaseGroupTaskEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
/** /**
* Created by AriaL on 2017/6/29. * Created by AriaL on 2017/6/29.
* 任务组子任务控制命令
*/ */
class GroupCmdFactory extends AbsCmdFactory<AbsGroupCmd> { public class GroupCmdFactory {
/** /**
* 启动任务 * 启动任务
*/ */
public static final int TASK_START = 0xa1; public static final int SUB_TASK_START = 0xa1;
/** /**
* 停止任务 * 停止任务
*/ */
public static final int TASK_STOP = 0xa2; public static final int SUB_TASK_STOP = 0xa2;
/** /**
* 取消任务 * 取消任务
*/ */
public static final int TASK_CANCEL = 0xa3; public static final int SUB_TASK_CANCEL = 0xa3;
private static volatile GroupCmdFactory INSTANCE = null; private static volatile GroupCmdFactory INSTANCE = null;
@ -54,18 +54,25 @@ class GroupCmdFactory extends AbsCmdFactory<AbsGroupCmd> {
/** /**
* @param target 创建任务的对象 * @param target 创建任务的对象
* @param entity 下载实体 * @param entity 下载实体
* @param type 命令类型{@link #TASK_START}{@link #TASK_CANCEL}{@link #TASK_STOP} * @param type 命令类型{@link #SUB_TASK_START}{@link #SUB_TASK_STOP}{@link #SUB_TASK_CANCEL}
* @param childUrl 需要控制的子任务url
*/ */
public <T extends AbsTaskEntity> AbsGroupCmd<T> createCmd(String target, T entity, int type) { public AbsGroupCmd createCmd(String target, BaseGroupTaskEntity entity, int type,
String childUrl) {
AbsGroupCmd cmd = null;
switch (type) { switch (type) {
case TASK_START: case SUB_TASK_START:
return new GroupStartCmd<>(target, entity); cmd = new GroupStartCmd<>(target, entity);
case TASK_STOP: break;
return new GroupStopCmd<>(target, entity); case SUB_TASK_STOP:
case TASK_CANCEL: cmd = new GroupStopCmd<>(target, entity);
return new GroupCancelCmd<>(target, entity); break;
default: case SUB_TASK_CANCEL:
return null; cmd = new GroupCancelCmd<>(target, entity);
} }
if (cmd != null) {
cmd.childUrl = childUrl;
}
return cmd;
} }
} }

@ -15,18 +15,13 @@
*/ */
package com.arialyy.aria.core.command.group; package com.arialyy.aria.core.command.group;
import android.text.TextUtils; import com.arialyy.aria.core.inf.BaseGroupTaskEntity;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.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. * Created by AriaL on 2017/6/29.
* 任务组开始命令该命令负责开始下载或恢复下载的操 * 任务组开始命令该命令负责处理任务组子任务的开始\恢复等工作
*/ */
class GroupStartCmd<T extends AbsTaskEntity> extends AbsGroupCmd<T> { class GroupStartCmd<T extends BaseGroupTaskEntity> extends AbsGroupCmd<T> {
/** /**
* @param targetName 创建任务的对象名 * @param targetName 创建任务的对象名
*/ */
@ -35,38 +30,8 @@ class GroupStartCmd<T extends AbsTaskEntity> extends AbsGroupCmd<T> {
} }
@Override public void executeCmd() { @Override public void executeCmd() {
String mod; if (checkTask()) {
int maxTaskNum; tempTask.startSubTask(childUrl);
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);
}
} }
} }
} }

@ -15,13 +15,13 @@
*/ */
package com.arialyy.aria.core.command.group; package com.arialyy.aria.core.command.group;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.BaseGroupTaskEntity;
/** /**
* Created by AriaL on 2017/6/29. * Created by AriaL on 2017/6/29.
* 停止任务组的命令 * 停止任务组的命令
*/ */
class GroupStopCmd<T extends AbsTaskEntity> extends AbsGroupCmd<T>{ class GroupStopCmd<T extends BaseGroupTaskEntity> extends AbsGroupCmd<T> {
/** /**
* @param targetName 创建任务的对象名 * @param targetName 创建任务的对象名
*/ */
@ -30,6 +30,8 @@ class GroupStopCmd<T extends AbsTaskEntity> extends AbsGroupCmd<T>{
} }
@Override public void executeCmd() { @Override public void executeCmd() {
if (checkTask()) {
tempTask.stopSubTask(childUrl);
}
} }
} }

@ -24,7 +24,7 @@ import com.arialyy.aria.core.inf.AbsTaskEntity;
* Created by Lyy on 2016/9/23. * Created by Lyy on 2016/9/23.
* 命令工厂 * 命令工厂
*/ */
public class NormalCmdFactory extends AbsCmdFactory<AbsNormalCmd> { public class NormalCmdFactory extends AbsCmdFactory<AbsTaskEntity, AbsNormalCmd> {
/** /**
* 创建任务 * 创建任务
*/ */
@ -82,7 +82,7 @@ public class NormalCmdFactory extends AbsCmdFactory<AbsNormalCmd> {
* @param type 命令类型{@link #TASK_CREATE}{@link #TASK_START}{@link #TASK_CANCEL}{@link * @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} * #TASK_STOP}{@link #TASK_HIGHEST_PRIORITY}{@link #TASK_STOP_ALL}{@link #TASK_RESUME_ALL}
*/ */
public <T extends AbsTaskEntity> AbsNormalCmd<T> createCmd(String target, T entity, int type) { public AbsNormalCmd createCmd(String target, AbsTaskEntity entity, int type) {
switch (type) { switch (type) {
case TASK_CREATE: case TASK_CREATE:
return new AddCmd<>(target, entity); return new AddCmd<>(target, entity);
@ -105,4 +105,5 @@ public class NormalCmdFactory extends AbsCmdFactory<AbsNormalCmd> {
return null; return null;
} }
} }
} }

@ -16,9 +16,10 @@
package com.arialyy.aria.core.download; package com.arialyy.aria.core.download;
import android.text.TextUtils; import android.text.TextUtils;
import com.arialyy.aria.core.SubTaskManager;
import com.arialyy.aria.core.inf.AbsDownloadTarget; import com.arialyy.aria.core.inf.AbsDownloadTarget;
import com.arialyy.aria.core.inf.AbsTarget; import com.arialyy.aria.core.inf.AbsTarget;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.BaseGroupTaskEntity;
import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import java.io.File; import java.io.File;
@ -28,7 +29,7 @@ import java.util.List;
/** /**
* Created by Aria.Lao on 2017/7/26. * Created by Aria.Lao on 2017/7/26.
*/ */
abstract class BaseGroupTarget<TARGET extends AbsTarget, TASK_ENTITY extends AbsTaskEntity> abstract class BaseGroupTarget<TARGET extends AbsTarget, TASK_ENTITY extends BaseGroupTaskEntity>
extends AbsDownloadTarget<TARGET, DownloadGroupEntity, TASK_ENTITY> { extends AbsDownloadTarget<TARGET, DownloadGroupEntity, TASK_ENTITY> {
List<String> mUrls = new ArrayList<>(); List<String> mUrls = new ArrayList<>();
@ -42,6 +43,8 @@ abstract class BaseGroupTarget<TARGET extends AbsTarget, TASK_ENTITY extends Abs
*/ */
private boolean isSetDirPathed = false; private boolean isSetDirPathed = false;
private SubTaskManager mSubTaskManager;
/** /**
* 查询任务组实体如果数据库不存在该实体则新创建一个新的任务组实体 * 查询任务组实体如果数据库不存在该实体则新创建一个新的任务组实体
*/ */
@ -57,6 +60,18 @@ abstract class BaseGroupTarget<TARGET extends AbsTarget, TASK_ENTITY extends Abs
return entity; return entity;
} }
/**
* 获取子任务管理器
*
* @return 子任务管理器
*/
public SubTaskManager getSubTaskManager() {
if (mSubTaskManager == null) {
mSubTaskManager = new SubTaskManager(mTargetName, mTaskEntity);
}
return mSubTaskManager;
}
/** /**
* 设置任务组别名 * 设置任务组别名
*/ */

@ -31,11 +31,6 @@ public class DownloadGroupEntity extends AbsGroupEntity {
@OneToMany(table = DownloadEntity.class, key = "groupName") private List<DownloadEntity> subtask = @OneToMany(table = DownloadEntity.class, key = "groupName") private List<DownloadEntity> subtask =
new ArrayList<>(); new ArrayList<>();
/**
* 子任务链接组
*/
@NormalList(clazz = String.class) private List<String> urls = new ArrayList<>();
/** /**
* 任务组下载文件的文件夹地址 * 任务组下载文件的文件夹地址
* *
@ -59,14 +54,6 @@ public class DownloadGroupEntity extends AbsGroupEntity {
this.dirPath = dirPath; this.dirPath = dirPath;
} }
public List<String> getUrls() {
return urls;
}
public void setUrls(List<String> urls) {
this.urls = urls;
}
void setGroupName(String key) { void setGroupName(String key) {
this.groupName = key; this.groupName = key;
} }

@ -19,6 +19,7 @@ import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.IUtil; import com.arialyy.aria.core.common.IUtil;
import com.arialyy.aria.core.download.downloader.AbsGroupUtil;
import com.arialyy.aria.core.download.downloader.DownloadGroupUtil; import com.arialyy.aria.core.download.downloader.DownloadGroupUtil;
import com.arialyy.aria.core.download.downloader.FtpDirDownloadUtil; import com.arialyy.aria.core.download.downloader.FtpDirDownloadUtil;
import com.arialyy.aria.core.inf.AbsGroupTask; import com.arialyy.aria.core.inf.AbsGroupTask;
@ -33,7 +34,6 @@ import com.arialyy.aria.util.CheckUtil;
public class DownloadGroupTask extends AbsGroupTask<DownloadGroupTaskEntity, DownloadGroupEntity> { public class DownloadGroupTask extends AbsGroupTask<DownloadGroupTaskEntity, DownloadGroupEntity> {
private final String TAG = "DownloadGroupTask"; private final String TAG = "DownloadGroupTask";
private DownloadGroupListener mListener; private DownloadGroupListener mListener;
private IUtil mUtil;
private DownloadGroupTask(DownloadGroupTaskEntity taskEntity, Handler outHandler) { private DownloadGroupTask(DownloadGroupTaskEntity taskEntity, Handler outHandler) {
mTaskEntity = taskEntity; mTaskEntity = taskEntity;

@ -15,13 +15,13 @@
*/ */
package com.arialyy.aria.core.download; package com.arialyy.aria.core.download;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.BaseGroupTaskEntity;
import com.arialyy.aria.orm.OneToOne; import com.arialyy.aria.orm.OneToOne;
/** /**
* Created by AriaL on 2017/7/1. * Created by AriaL on 2017/7/1.
*/ */
public class DownloadGroupTaskEntity extends AbsTaskEntity<DownloadGroupEntity> { public class DownloadGroupTaskEntity extends BaseGroupTaskEntity<DownloadGroupEntity> {
@OneToOne(table = DownloadGroupEntity.class, key = "groupName") public DownloadGroupEntity entity; @OneToOne(table = DownloadGroupEntity.class, key = "groupName") public DownloadGroupEntity entity;

@ -300,7 +300,7 @@ public class DownloadReceiver extends AbsReceiver {
@Override public void removeAllTask(boolean removeFile) { @Override public void removeAllTask(boolean removeFile) {
final AriaManager ariaManager = AriaManager.getInstance(AriaManager.APP); final AriaManager ariaManager = AriaManager.getInstance(AriaManager.APP);
CancelAllCmd cancelCmd = CancelAllCmd cancelCmd =
(CancelAllCmd) CommonUtil.createCmd(targetName, new DownloadTaskEntity(), (CancelAllCmd) CommonUtil.createNormalCmd(targetName, new DownloadTaskEntity(),
NormalCmdFactory.TASK_CANCEL_ALL); NormalCmdFactory.TASK_CANCEL_ALL);
cancelCmd.removeFile = removeFile; cancelCmd.removeFile = removeFile;
ariaManager.setCmd(cancelCmd).exe(); ariaManager.setCmd(cancelCmd).exe();

@ -15,6 +15,7 @@
*/ */
package com.arialyy.aria.core.download.downloader; package com.arialyy.aria.core.download.downloader;
import android.util.Log;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.IUtil; import com.arialyy.aria.core.common.IUtil;
import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadEntity;
@ -38,7 +39,7 @@ import java.util.concurrent.Executors;
* Created by AriaL on 2017/6/30. * Created by AriaL on 2017/6/30.
* 任务组核心逻辑 * 任务组核心逻辑
*/ */
abstract class AbsGroupUtil implements IUtil { public abstract class AbsGroupUtil implements IUtil {
private final String TAG = "AbsGroupUtil"; private final String TAG = "AbsGroupUtil";
/** /**
* 任务组所有任务总大小 * 任务组所有任务总大小
@ -126,6 +127,55 @@ abstract class AbsGroupUtil implements IUtil {
mTaskEntity.getEntity().update(); mTaskEntity.getEntity().update();
} }
} }
/**
* 启动子任务下载
*
* @param url 子任务下载地址
*/
public void startSubTask(String url) {
Downloader d = getDownloader(url);
if (d != null && !d.isRunning()) {
d.start();
}
}
/**
* 停止子任务下载
*
* @param url 子任务下载地址
*/
public void stopSubTask(String url) {
Downloader d = getDownloader(url);
if (d != null && d.isRunning()) {
d.stop();
}
}
/**
* 删除子任务
*
* @param url 子任务下载地址
*/
public void cancelSunTask(String url) {
Downloader d = getDownloader(url);
if (d != null) {
d.cancel();
}
}
/**
* 通过地址获取下载器
*
* @param url 子任务下载地址
*/
private Downloader getDownloader(String url) {
Downloader d = mDownloaderMap.get(url);
if (d == null) {
Log.e(TAG, "链接【" + url + "】对应的下载器不存在");
return null;
}
return d;
}
@Override public long getFileSize() { @Override public long getFileSize() {
return mTotalSize; return mTotalSize;

@ -98,7 +98,7 @@ public abstract class AbsDownloadTarget<TARGET extends AbsTarget, ENTITY extends
protected void setHighestPriority() { protected void setHighestPriority() {
AriaManager.getInstance(AriaManager.APP) AriaManager.getInstance(AriaManager.APP)
.setCmd( .setCmd(
CommonUtil.createCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_HIGHEST_PRIORITY)) CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_HIGHEST_PRIORITY))
.exe(); .exe();
} }
@ -136,7 +136,7 @@ public abstract class AbsDownloadTarget<TARGET extends AbsTarget, ENTITY extends
*/ */
public void add() { public void add() {
AriaManager.getInstance(AriaManager.APP) AriaManager.getInstance(AriaManager.APP)
.setCmd(CommonUtil.createCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_CREATE)) .setCmd(CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_CREATE))
.exe(); .exe();
} }

@ -17,7 +17,10 @@ package com.arialyy.aria.core.inf;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import com.arialyy.aria.orm.NormalList;
import com.arialyy.aria.orm.Primary; import com.arialyy.aria.orm.Primary;
import java.util.ArrayList;
import java.util.List;
/** /**
* Created by AriaL on 2017/6/3. * Created by AriaL on 2017/6/3.
@ -33,6 +36,19 @@ public abstract class AbsGroupEntity extends AbsEntity implements Parcelable {
*/ */
private String alias = ""; private String alias = "";
/**
* 子任务链接组
*/
@NormalList(clazz = String.class) private List<String> urls = new ArrayList<>();
public List<String> getUrls() {
return urls;
}
public void setUrls(List<String> urls) {
this.urls = urls;
}
public String getGroupName() { public String getGroupName() {
return groupName; return groupName;
} }

@ -15,17 +15,53 @@
*/ */
package com.arialyy.aria.core.inf; package com.arialyy.aria.core.inf;
import com.arialyy.aria.core.download.downloader.AbsGroupUtil;
/** /**
* Created by AriaL on 2017/6/29. * Created by AriaL on 2017/6/29.
* 任务组任务抽象类
*/ */
public abstract class AbsGroupTask<TASK_ENTITY extends AbsTaskEntity, ENTITY extends AbsGroupEntity> public abstract class AbsGroupTask<TASK_ENTITY extends AbsTaskEntity, ENTITY extends AbsGroupEntity>
extends AbsTask<ENTITY> { extends AbsTask<ENTITY> {
protected TASK_ENTITY mTaskEntity; protected TASK_ENTITY mTaskEntity;
protected AbsGroupUtil mUtil;
@Override public String getKey() { @Override public String getKey() {
return mEntity.getGroupName(); return mEntity.getGroupName();
} }
/**
* 启动任务组中的子任务
*
* @param url 子任务下载地址
*/
public void startSubTask(String url) {
if (mUtil != null) {
mUtil.startSubTask(url);
}
}
/**
* 停止任务组中的子任务
*
* @param url 子任务下载地址
*/
public void stopSubTask(String url) {
if (mUtil != null) {
mUtil.stopSubTask(url);
}
}
/**
* 删除子任务组中的子任务
*
* @param url 子任务下载地址
*/
public void cancelSubTask(String url) {
if (mUtil != null) {
mUtil.cancelSunTask(url);
}
}
} }

@ -162,7 +162,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
*/ */
@Override public void start() { @Override public void start() {
AriaManager.getInstance(AriaManager.APP) AriaManager.getInstance(AriaManager.APP)
.setCmd(CommonUtil.createCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_START)) .setCmd(CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_START))
.exe(); .exe();
} }
@ -177,7 +177,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
@Override public void stop() { @Override public void stop() {
AriaManager.getInstance(AriaManager.APP) AriaManager.getInstance(AriaManager.APP)
.setCmd(CommonUtil.createCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_STOP)) .setCmd(CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_STOP))
.exe(); .exe();
} }
@ -186,7 +186,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
*/ */
@Override public void resume() { @Override public void resume() {
AriaManager.getInstance(AriaManager.APP) AriaManager.getInstance(AriaManager.APP)
.setCmd(CommonUtil.createCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_START)) .setCmd(CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_START))
.exe(); .exe();
} }
@ -195,7 +195,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
*/ */
@Override public void cancel() { @Override public void cancel() {
AriaManager.getInstance(AriaManager.APP) AriaManager.getInstance(AriaManager.APP)
.setCmd(CommonUtil.createCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_CANCEL)) .setCmd(CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_CANCEL))
.exe(); .exe();
} }
@ -207,7 +207,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
*/ */
public void cancel(boolean removeFile) { public void cancel(boolean removeFile) {
CancelCmd cancelCmd = CancelCmd cancelCmd =
(CancelCmd) CommonUtil.createCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_CANCEL); (CancelCmd) CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_CANCEL);
cancelCmd.removeFile = removeFile; cancelCmd.removeFile = removeFile;
AriaManager.getInstance(AriaManager.APP).setCmd(cancelCmd).exe(); AriaManager.getInstance(AriaManager.APP).setCmd(cancelCmd).exe();
} }

@ -0,0 +1,26 @@
/*
* 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;
/**
* Created by lyy on 2017/9/5.
*/
public abstract class BaseGroupTaskEntity<ENTITY extends AbsGroupEntity> extends AbsTaskEntity<ENTITY>{
@Override public ENTITY getEntity() {
return null;
}
}

@ -92,7 +92,7 @@ public class UploadReceiver extends AbsReceiver<UploadEntity> {
@Override public void removeAllTask(boolean removeFile) { @Override public void removeAllTask(boolean removeFile) {
final AriaManager am = AriaManager.getInstance(AriaManager.APP); final AriaManager am = AriaManager.getInstance(AriaManager.APP);
am.setCmd(CommonUtil.createCmd(targetName, new DownloadTaskEntity(), am.setCmd(CommonUtil.createNormalCmd(targetName, new DownloadTaskEntity(),
NormalCmdFactory.TASK_CANCEL_ALL)).exe(); NormalCmdFactory.TASK_CANCEL_ALL)).exe();
Set<String> keys = am.getReceiver().keySet(); Set<String> keys = am.getReceiver().keySet();

@ -24,16 +24,16 @@ import android.text.TextUtils;
import android.util.Base64; import android.util.Base64;
import android.util.Log; import android.util.Log;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.command.normal.NormalCmdFactory; import com.arialyy.aria.core.command.group.AbsGroupCmd;
import com.arialyy.aria.core.command.group.GroupCmdFactory;
import com.arialyy.aria.core.command.normal.AbsNormalCmd; import com.arialyy.aria.core.command.normal.AbsNormalCmd;
import com.arialyy.aria.core.command.normal.NormalCmdFactory;
import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.BaseGroupTaskEntity;
import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTaskEntity; import com.arialyy.aria.core.upload.UploadTaskEntity;
import com.arialyy.aria.orm.DbEntity;
import java.io.File; import java.io.File;
import java.io.FileFilter; import java.io.FileFilter;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -43,6 +43,11 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
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;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.net.URLEncoder; import java.net.URLEncoder;
@ -58,11 +63,6 @@ import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; 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. * Created by lyy on 2016/1/22.
@ -398,10 +398,24 @@ public class CommonUtil {
} }
} }
public static <T extends AbsTaskEntity> AbsNormalCmd createCmd(String target, T entity, int cmd) { /**
* 创建任务命令
*/
public static <T extends AbsTaskEntity> AbsNormalCmd createNormalCmd(String target, T entity,
int cmd) {
return NormalCmdFactory.getInstance().createCmd(target, entity, cmd); return NormalCmdFactory.getInstance().createCmd(target, entity, cmd);
} }
/**
* 创建任务组命令
*
* @param childUrl 子任务url
*/
public static <T extends BaseGroupTaskEntity> AbsGroupCmd createGroupCmd(String target, T entity,
int cmd, String childUrl) {
return GroupCmdFactory.getInstance().createCmd(target, entity, cmd, childUrl);
}
/** /**
* 创建隐性的Intent * 创建隐性的Intent
*/ */

@ -25,75 +25,134 @@ import java.lang.annotation.Target;
* Aria下载事件被注解的方法中参数仅能有一个参数类型为{@link com.arialyy.aria.core.download.DownloadGroupTask} * Aria下载事件被注解的方法中参数仅能有一个参数类型为{@link com.arialyy.aria.core.download.DownloadGroupTask}
* <pre> * <pre>
* <code> * <code>
* {@literal @}Download.onPre(groupName) * {@literal @}DownloadGroup.onPre(groupName)
* protected void onPre(DownloadGroupTask task) { * protected void onPre(DownloadGroupTask task) {
* } * }
* </code> * </code>
* </pre> * </pre>
* {@literal @}Download.onPre("myGroupName")如果你的注解中增加了url描述 * {@literal @}Download.onPre("myGroupName")如果你的注解中增加了url描述
* 则表示所有下载任务中只有下载地址为"myGroupName"的任务才能回调该注解的方法 * 则表示所有下载任务中只有下载地址为"myGroupName"的任务才能回调该注解的方法
*
*
* 如果希望获取子任务的状态可以使用onSub..类的注解
* <pre>
* <code>
* {@literal @}DownloadGroup.onSubPre(groupName)
* protected void onPre(DownloadGroupTask task, String url) {
* }
* </code>
* </pre>
*/ */
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface DownloadGroup { @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface DownloadGroup {
/** /**
* 如果你在方法中添加{@code @Download.onPre}注解在预处理完成时Aria会调用该方法 * 如果你在方法中添加{@code @DownloadGroup.onPre}注解在预处理完成时Aria会调用该方法
*/ */
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onPre { @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onPre {
String[] value() default { AriaConstance.NO_URL }; String[] value() default { AriaConstance.NO_URL };
} }
/** /**
* 如果你在方法中添加{@code @Download.onTaskPre}注解在任务预处理完成时Aria会调用该方法 * 如果你在方法中添加{@code @DownloadGroup.onTaskPre}注解在任务预处理完成时Aria会调用该方法
*/ */
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskPre { @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskPre {
String[] value() default { AriaConstance.NO_URL }; String[] value() default { AriaConstance.NO_URL };
} }
/** /**
* 如果你在方法中添加{@code @Download.onTaskResume}注解在任务恢复下载时Aria会调用该方法 * 如果你在方法中添加{@code @DownloadGroup.onTaskResume}注解在任务恢复下载时Aria会调用该方法
*/ */
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskResume { @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskResume {
String[] value() default { AriaConstance.NO_URL }; String[] value() default { AriaConstance.NO_URL };
} }
/** /**
* 如果你在方法中添加{@code @Download.onTaskStart}注解在任务开始下载时Aria会调用该方法 * 如果你在方法中添加{@code @DownloadGroup.onTaskStart}注解在任务开始下载时Aria会调用该方法
*/ */
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskStart { @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskStart {
String[] value() default { AriaConstance.NO_URL }; String[] value() default { AriaConstance.NO_URL };
} }
/** /**
* 如果你在方法中添加{@code @Download.onTaskStop}注解在任务停止时Aria会调用该方法 * 如果你在方法中添加{@code @DownloadGroup.onTaskStop}注解在任务停止时Aria会调用该方法
*/ */
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskStop { @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskStop {
String[] value() default { AriaConstance.NO_URL }; String[] value() default { AriaConstance.NO_URL };
} }
/** /**
* 如果你在方法中添加{@code @Download.onTaskCancel}l注解在任务取消时Aria会调用该方法 * 如果你在方法中添加{@code @DownloadGroup.onTaskCancel}l注解在任务取消时Aria会调用该方法
*/ */
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskCancel { @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskCancel {
String[] value() default { AriaConstance.NO_URL }; String[] value() default { AriaConstance.NO_URL };
} }
/** /**
* 如果你在方法中添加{@code @Download.onTaskFail)注解在任务预失败时Aria会调用该方法 * 如果你在方法中添加{@code @DownloadGroup.onTaskFail)注解在任务预失败时Aria会调用该方法
*/ */
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskFail { @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskFail {
String[] value() default { AriaConstance.NO_URL }; String[] value() default { AriaConstance.NO_URL };
} }
/** /**
* 如果你在方法中添加{@code @Download.onTaskComplete}注解在任务完成时Aria会调用该方法 * 如果你在方法中添加{@code @DownloadGroup.onTaskComplete}注解在任务完成时Aria会调用该方法
*/ */
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskComplete { @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskComplete {
String[] value() default { AriaConstance.NO_URL }; String[] value() default { AriaConstance.NO_URL };
} }
/** /**
* 如果你在方法中添加{@code @Download.onTaskRunning}注解在任务正在下载Aria会调用该方法 * 如果你在方法中添加{@code @DownloadGroup.onTaskRunning}注解在任务正在下载Aria会调用该方法
*/ */
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskRunning { @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskRunning {
String[] value() default { AriaConstance.NO_URL }; String[] value() default { AriaConstance.NO_URL };
} }
/**
* 任务组子任务预处理的注解
*/
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onSubTaskPre {
String value() default AriaConstance.NO_URL;
}
/**
* 任务组子任务开始的注解
*/
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onSubTaskStart {
String value() default AriaConstance.NO_URL;
}
/**
* 任务组子任务停止的注解
*/
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onSubTaskStop {
String value() default AriaConstance.NO_URL;
}
/**
* 任务组子任务删除的注解
*/
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onSubTaskCancel {
String value() default AriaConstance.NO_URL;
}
/**
* 任务组子任务失败的注解
*/
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onSubTaskFail {
String value() default AriaConstance.NO_URL;
}
/**
* 任务组子任务完成的注解
*/
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onSubTaskComplete {
String value() default AriaConstance.NO_URL;
}
/**
* 任务组子任务正在执行的注解
*/
@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onSubTaskRunning {
String value() default AriaConstance.NO_URL;
}
} }

@ -0,0 +1,123 @@
/*
* 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.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import butterknife.Bind;
import butterknife.OnClick;
import com.arialyy.annotations.DownloadGroup;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupTask;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseDialog;
import com.arialyy.simple.databinding.DialogSubTaskHandlerBinding;
import com.arialyy.simple.widget.HorizontalProgressBarWithNumber;
import java.util.List;
/**
* Created by Aria.Lao on 2017/9/5.
*/
@SuppressLint("ValidFragment") public class ChildHandleDialog
extends BaseDialog<DialogSubTaskHandlerBinding> {
@Bind(R.id.sub_task) TextView mSub;
@Bind(R.id.task_group) TextView mGroup;
@Bind(R.id.pb) HorizontalProgressBarWithNumber mPb;
private String mGroupName;
private String mChildName;
private DownloadEntity mChildEntity;
public ChildHandleDialog(Context context, String groupAliaName, DownloadEntity childEntity) {
super(context);
setStyle(STYLE_NO_TITLE, R.style.Theme_Light_Dialog);
mChildEntity = childEntity;
mGroupName = groupAliaName;
mChildName = childEntity.getFileName();
}
@Override protected void init(Bundle savedInstanceState) {
super.init(savedInstanceState);
Aria.download(this).register();
initWidget();
}
@Override public void onDestroy() {
super.onDestroy();
Aria.download(this).unRegister();
}
private void initWidget() {
mGroup.setText("任务组:" + mGroupName);
mSub.setText("子任务:" + mChildName);
mPb.setProgress((int) (mChildEntity.getCurrentProgress() * 100 / mChildEntity.getFileSize()));
Window window = getDialog().getWindow();
window.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
WindowManager.LayoutParams p = window.getAttributes();
p.width = ViewGroup.LayoutParams.MATCH_PARENT;
window.setAttributes(p);
window.setWindowAnimations(R.style.dialogStyle);
}
@DownloadGroup.onTaskResume void onTaskResume(DownloadGroupTask task) {
mSub.setText("子任务:" + mChildName + ",状态:下载中");
}
@DownloadGroup.onTaskCancel void onTaskCancel(DownloadGroupTask task) {
mSub.setText("子任务:" + mChildName + ",状态:取消下载");
}
@DownloadGroup.onTaskRunning void onTaskRunning(DownloadGroupTask task) {
mPb.setProgress((int) (mChildEntity.getCurrentProgress() * 100 / mChildEntity.getFileSize()));
}
@DownloadGroup.onTaskStop void onTaskStop(DownloadGroupTask task) {
mSub.setText("子任务:" + mChildName + ",状态:任务停止");
}
@DownloadGroup.onTaskComplete void onTaskComplete(DownloadGroupTask task) {
mSub.setText("子任务:" + mChildName + ",状态:任务完成");
mPb.setProgress(100);
}
@Override protected int setLayoutId() {
return R.layout.dialog_sub_task_handler;
}
@OnClick({ R.id.start, R.id.stop, R.id.cancel }) void onClick(View view) {
switch (view.getId()) {
case R.id.start:
break;
case R.id.stop:
break;
case R.id.cancel:
break;
}
}
@Override protected void dataCallback(int result, Object obj) {
}
}

@ -17,17 +17,15 @@ package com.arialyy.simple.download.group;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.Handler; import android.view.Gravity;
import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.Button;
import butterknife.Bind; import butterknife.Bind;
import com.arialyy.annotations.DownloadGroup; import com.arialyy.annotations.DownloadGroup;
import com.arialyy.aria.core.Aria; import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.download.DownloadGroupEntity; import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.download.DownloadGroupTask; import com.arialyy.aria.core.download.DownloadGroupTask;
import com.arialyy.aria.core.download.DownloadGroupTaskEntity; import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
import com.arialyy.frame.util.AndroidUtils;
import com.arialyy.frame.util.show.L; import com.arialyy.frame.util.show.L;
import com.arialyy.frame.util.show.T; import com.arialyy.frame.util.show.T;
import com.arialyy.simple.R; import com.arialyy.simple.R;
@ -62,6 +60,18 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
: (int) (groupEntity.getCurrentProgress() * 100 / groupEntity.getFileSize())); : (int) (groupEntity.getCurrentProgress() * 100 / groupEntity.getFileSize()));
} }
} }
mChildList.setOnItemClickListener(new SubStateLinearLayout.OnItemClickListener() {
@Override public void onItemClick(int position, View view) {
showPopupWindow(position);
}
});
}
private void showPopupWindow(int position) {
ChildHandleDialog dialog =
new ChildHandleDialog(this, "任务组测试", mChildList.getSubData().get(position));
dialog.show(getSupportFragmentManager(), "sub_dialog");
} }
@Override protected int setLayoutId() { @Override protected int setLayoutId() {
@ -77,7 +87,7 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
Environment.getExternalStorageDirectory().getPath() + "/Download/group_test_3") Environment.getExternalStorageDirectory().getPath() + "/Download/group_test_3")
.setGroupAlias("任务组测试") .setGroupAlias("任务组测试")
.setSubFileName(getModule(GroupModule.class).getSubName()) .setSubFileName(getModule(GroupModule.class).getSubName())
.setFileSize(32895492) //.setFileSize(32895492)
.start(); .start();
break; break;
case R.id.stop: case R.id.stop:
@ -99,7 +109,7 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
} }
L.d(TAG, "group task pre"); L.d(TAG, "group task pre");
getBinding().setFileSize(task.getConvertFileSize()); getBinding().setFileSize(task.getConvertFileSize());
if (mChildList.getSubData().size() <= 0){ if (mChildList.getSubData().size() <= 0) {
mChildList.addData(task.getEntity().getSubTask()); mChildList.addData(task.getEntity().getSubTask());
} }
} }
@ -109,7 +119,6 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
} }
@DownloadGroup.onTaskRunning() protected void running(DownloadGroupTask task) { @DownloadGroup.onTaskRunning() protected void running(DownloadGroupTask task) {
L.d(TAG, "P ==> " + task.getPercent());
getBinding().setProgress(task.getPercent()); getBinding().setProgress(task.getPercent());
getBinding().setSpeed(task.getConvertSpeed()); getBinding().setSpeed(task.getConvertSpeed());
mChildList.updateChildProgress(task.getEntity().getSubTask()); mChildList.updateChildProgress(task.getEntity().getSubTask());

@ -1,8 +1,24 @@
/*
* 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.widget; package com.arialyy.simple.widget;
import android.content.Context; import android.content.Context;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.LinearLayout; import android.widget.LinearLayout;
@ -17,16 +33,22 @@ import java.util.WeakHashMap;
/** /**
* Created by Aria.Lao on 2017/7/17. * Created by Aria.Lao on 2017/7/17.
*/ */
public class SubStateLinearLayout extends LinearLayout { public class SubStateLinearLayout extends LinearLayout implements View.OnClickListener {
interface OnShowCallback { interface OnShowCallback {
void onShow(boolean visibility); void onShow(boolean visibility);
} }
OnShowCallback callback; public interface OnItemClickListener {
void onItemClick(int position, View view);
}
OnShowCallback mShowCallback;
OnItemClickListener mItemClickListener;
List<DownloadEntity> mSubData = new LinkedList<>(); List<DownloadEntity> mSubData = new LinkedList<>();
Map<String, Integer> mPosition = new WeakHashMap<>(); Map<String, Integer> mPosition = new WeakHashMap<>();
SparseArray<View> mViews = new SparseArray<>();
public SubStateLinearLayout(Context context) { public SubStateLinearLayout(Context context) {
super(context); super(context);
@ -50,15 +72,25 @@ public class SubStateLinearLayout extends LinearLayout {
createShowView(); createShowView();
int i = 1; int i = 1;
for (DownloadEntity entity : datas) { for (DownloadEntity entity : datas) {
TextView view = createView(entity); TextView view = createView(i - 1, entity);
mPosition.put(entity.getDownloadPath(), i); mPosition.put(entity.getDownloadPath(), i);
addView(view, i); addView(view, i);
i++; i++;
} }
} }
@Override public void onClick(View v) {
if (mItemClickListener != null) {
mItemClickListener.onItemClick(mViews.indexOfValue(v), v);
}
}
public void setOnShowCallback(OnShowCallback callback) { public void setOnShowCallback(OnShowCallback callback) {
this.callback = callback; this.mShowCallback = callback;
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.mItemClickListener = listener;
} }
public List<DownloadEntity> getSubData() { public List<DownloadEntity> getSubData() {
@ -79,10 +111,12 @@ public class SubStateLinearLayout extends LinearLayout {
} }
} }
private TextView createView(DownloadEntity entity) { private TextView createView(int position, DownloadEntity entity) {
TextView view = TextView view =
(TextView) LayoutInflater.from(getContext()).inflate(R.layout.layout_child_state, null); (TextView) LayoutInflater.from(getContext()).inflate(R.layout.layout_child_state, null);
view.setText(entity.getFileName() + ": " + getPercent(entity) + "%"); view.setText(entity.getFileName() + ": " + getPercent(entity) + "%");
view.setOnClickListener(this);
mViews.append(position, view);
return view; return view;
} }

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromYDelta="100%"
android:duration="100"/>
</set>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="100"
android:toYDelta="100%"/>
</set>

@ -17,7 +17,7 @@
/> />
</data> </data>
<LinearLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
@ -27,18 +27,24 @@
<include <include
layout="@layout/content_single" layout="@layout/content_single"
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/toolbar"
bind:fileSize="@{fileSize}" bind:fileSize="@{fileSize}"
bind:progress="@{progress}" bind:progress="@{progress}"
bind:speed="@{speed}" bind:speed="@{speed}"
/> />
<com.arialyy.simple.widget.SubStateLinearLayout <com.arialyy.simple.widget.SubStateLinearLayout
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:id="@+id/child_list" android:id="@+id/child_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_above="@+id/temp"
android:layout_below="@+id/content"
android:paddingLeft="16dp"
android:paddingRight="16dp"
/> />
</LinearLayout> </RelativeLayout>
</layout> </layout>

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:padding="16dp"
>
<TextView
android:id="@+id/task_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="任务组:"
/>
<TextView
android:id="@+id/sub_task"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/task_group"
android:layout_marginTop="5dp"
android:text="子任务:"
/>
<com.arialyy.simple.widget.HorizontalProgressBarWithNumber
android:id="@+id/pb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/sub_task"
android:layout_marginTop="10dp"
android:max="100"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/pb"
android:orientation="horizontal"
>
<Button
android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="开始"
style="?buttonBarButtonStyle"
/>
<Button
android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="停止"
style="?buttonBarButtonStyle"
/>
<Button
android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="删除"
style="?buttonBarButtonStyle"
/>
</LinearLayout>
</RelativeLayout>
</layout>

@ -10,13 +10,13 @@
<include layout="@layout/layout_bar"/> <include layout="@layout/layout_bar"/>
<Button <Button
android:onClick="onClick" android:onClick="onClick"
android:id="@+id/download" android:id="@+id/download"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="多任务同时下载" android:text="多任务同时下载"
style="?buttonBarButtonStyle" style="?buttonBarButtonStyle"
/> />
</LinearLayout> </LinearLayout>
</layout> </layout>

@ -49,7 +49,7 @@
<string-array name="group_urls"> <string-array name="group_urls">
<!--<item>https://res5.d.cn/5a6a3384c1b2be1a65d84b914e6a6fef697637578b6db2eb1056d50b09cf1dcf289d4045df7ef95746e498e3d6a848ab84c89b77aa60194e2c48e5a7cb748265.apk</item>--> <!--<item>https://res5.d.cn/5a6a3384c1b2be1a65d84b914e6a6fef697637578b6db2eb1056d50b09cf1dcf289d4045df7ef95746e498e3d6a848ab84c89b77aa60194e2c48e5a7cb748265.apk</item>-->
<!--<item>https://res5.d.cn/5a6a3384c1b2be1a52034c72752e8475414630ebc69318b84ef584115ebf5eaaab945ae07b7fe3596afc72a7940ff328d4a9553f6ae92d6c09ba4bfb533137f6.apk</item>--> <!--<item>https://res5.d.cn/5a6a3384c1b2be1a52034c72752e8475414630ebc69318b84ef584115ebf5eaaab945ae07b7fe3596afc72a7940ff328d4a9553f6ae92d6c09ba4bfb533137f6.apk</item>-->
<!--<item>https://res5.d.cn/5a6a3384c1b2be1a426f06bfc69034d69c44ae1a01da180cab8e59bd1a5e1a784bac46ba0c64579d14f0e80a4ce4f068af89b0369a393456f4f449a8829cad5c.apk</item>--> <item>https://res5.d.cn/5a6a3384c1b2be1a426f06bfc69034d69c44ae1a01da180cab8e59bd1a5e1a784bac46ba0c64579d14f0e80a4ce4f068af89b0369a393456f4f449a8829cad5c.apk</item>
<item>http://static.gaoshouyou.com/d/12/0d/7f120f50c80d2e7b8c4ba24ece4f9cdd.apk</item> <item>http://static.gaoshouyou.com/d/12/0d/7f120f50c80d2e7b8c4ba24ece4f9cdd.apk</item>
<item>http://static.ilongyuan.cn/rayark/RayarkFZ_2.0.7.apk</item> <item>http://static.ilongyuan.cn/rayark/RayarkFZ_2.0.7.apk</item>
</string-array> </string-array>
@ -72,7 +72,7 @@
<string-array name="group_names"> <string-array name="group_names">
<item>王者荣耀.apk</item> <item>王者荣耀.apk</item>
<item>战斗吧剑灵.apk</item> <item>战斗吧剑灵.apk</item>
<!--<item>天魔幻想.apk</item>--> <item>天魔幻想.apk</item>
</string-array> </string-array>
<string-array name="group_names_1"> <string-array name="group_names_1">

@ -22,4 +22,21 @@
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/> <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>
<style name="dialogStyle" parent="@android:style/Animation.Dialog">
<item name="@android:windowEnterAnimation">@anim/dialog_enter</item>
<!-- 进入时的动画 -->
<item name="@android:windowExitAnimation">@anim/dialog_exit</item>
<!-- 退出时的动画 -->
</style>
<!-- 对话框样式 -->
<style name="Theme.Light.Dialog" parent="android:style/Theme.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:scrollHorizontally">true</item>
</style>
</resources> </resources>

Loading…
Cancel
Save