Merge branch 'v_3.0' of https://github.com/AriaLyy/Aria into v_3.0
This commit is contained in:
@ -86,6 +86,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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果需要在代码中修改下载配置,请使用以下方法
|
||||
* <pre>
|
||||
|
@ -86,10 +86,27 @@ 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)) {
|
||||
|
29
Aria/src/main/java/com/arialyy/aria/core/QueueMod.java
Normal file
29
Aria/src/main/java/com/arialyy/aria/core/QueueMod.java
Normal file
@ -0,0 +1,29 @@
|
||||
package com.arialyy.aria.core;
|
||||
|
||||
/**
|
||||
* Created by Aria.Lao on 2017/6/21.
|
||||
* 执行队列类型
|
||||
*/
|
||||
public enum QueueMod {
|
||||
/**
|
||||
* 等待模式,如果执行队列已经满了,再次使用start命令执行任务时,该任务会被添加到缓存队列中
|
||||
* 当执行队列的任务完成时,将自动执行缓存队列中的任务
|
||||
*/
|
||||
WAIT("wait"),
|
||||
|
||||
/**
|
||||
* 立刻执行模式
|
||||
* 如果执行队列已经满了,再次使用start命令执行任务时,该任务会添加到执行队列队尾,而原来执行队列的队首任务会停止
|
||||
*/
|
||||
NOW("now");
|
||||
|
||||
String tag;
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
QueueMod(String tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
}
|
@ -32,13 +32,18 @@ import com.arialyy.aria.util.CommonUtil;
|
||||
*/
|
||||
public abstract class AbsCmd<T extends AbsTaskEntity> implements ICmd {
|
||||
ITaskQueue mQueue;
|
||||
T mEntity;
|
||||
T mTaskEntity;
|
||||
String TAG;
|
||||
String mTargetName;
|
||||
/**
|
||||
* 能否执行命令
|
||||
*/
|
||||
boolean canExeCmd = true;
|
||||
/**
|
||||
* 是否是下载任务的命令
|
||||
* {@code true} 下载任务的命令,{@code false} 上传任务的命令
|
||||
*/
|
||||
boolean isDownloadCmd = true;
|
||||
|
||||
/**
|
||||
* @param targetName 产生任务的对象名
|
||||
@ -47,12 +52,14 @@ public abstract class AbsCmd<T extends AbsTaskEntity> implements ICmd {
|
||||
canExeCmd = CheckUtil.checkCmdEntity(entity,
|
||||
!(this instanceof CancelCmd) || !(this instanceof StopCmd));
|
||||
mTargetName = targetName;
|
||||
mEntity = entity;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -33,10 +33,10 @@ class AddCmd<T extends AbsTaskEntity> extends AbsCmd<T> {
|
||||
|
||||
@Override public void executeCmd() {
|
||||
if (!canExeCmd) return;
|
||||
ITask task = mQueue.getTask(mEntity.getEntity());
|
||||
ITask 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, "添加命令执行失败,【该任务已经存在】");
|
||||
}
|
||||
|
@ -31,15 +31,15 @@ class CancelCmd<T extends AbsTaskEntity> extends AbsCmd<T> {
|
||||
|
||||
@Override public void executeCmd() {
|
||||
if (!canExeCmd) return;
|
||||
ITask task = mQueue.getTask(mEntity.getEntity());
|
||||
ITask 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -39,9 +39,9 @@ final class HighestPriorityCmd<T extends AbsTaskEntity> extends AbsCmd<T> {
|
||||
|
||||
@Override public void executeCmd() {
|
||||
if (!canExeCmd) return;
|
||||
ITask task = mQueue.getTask(mEntity.getEntity());
|
||||
ITask 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)) {
|
||||
|
@ -27,7 +27,7 @@ final class ResumeAllCmd<T extends AbsTaskEntity> extends AbsCmd<T> {
|
||||
List<DownloadEntity> allEntity =
|
||||
DbEntity.findDatas(DownloadEntity.class, "state=?", IEntity.STATE_STOP + "");
|
||||
for (DownloadEntity entity : allEntity) {
|
||||
int exeNum = mQueue.getExeTaskNum();
|
||||
int exeNum = mQueue.getExePoolSize();
|
||||
if (exeNum == 0 || exeNum < mQueue.getMaxTaskNum()) {
|
||||
ITask task = createTask(entity);
|
||||
mQueue.startTask(task);
|
||||
|
@ -17,6 +17,8 @@
|
||||
package com.arialyy.aria.core.command;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import com.arialyy.aria.core.QueueMod;
|
||||
import com.arialyy.aria.core.inf.ITask;
|
||||
import com.arialyy.aria.core.inf.AbsTaskEntity;
|
||||
|
||||
@ -32,15 +34,31 @@ class StartCmd<T extends AbsTaskEntity> extends AbsCmd<T> {
|
||||
|
||||
@Override public void executeCmd() {
|
||||
if (!canExeCmd) return;
|
||||
ITask task = mQueue.getTask(mEntity.getEntity());
|
||||
ITask 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);
|
||||
}
|
||||
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();
|
||||
}
|
||||
if (mod.equals(QueueMod.NOW.getTag())) {
|
||||
mQueue.startTask(task);
|
||||
}else if (mod.equals(QueueMod.WAIT.getTag())){
|
||||
if (mQueue.getExePoolSize() < maxTaskNum){
|
||||
mQueue.startTask(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -34,10 +34,10 @@ class StopCmd<T extends AbsTaskEntity> extends AbsCmd<T> {
|
||||
|
||||
@Override public void executeCmd() {
|
||||
if (!canExeCmd) return;
|
||||
ITask task = mQueue.getTask(mEntity.getEntity());
|
||||
ITask 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, "停止命令执行失败,【调度器中没有该任务】");
|
||||
|
@ -18,6 +18,7 @@ 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.IEntity;
|
||||
import com.arialyy.aria.core.inf.IReceiver;
|
||||
import com.arialyy.aria.core.command.CmdFactory;
|
||||
import com.arialyy.aria.core.command.AbsCmd;
|
||||
@ -26,6 +27,7 @@ import com.arialyy.aria.core.scheduler.ISchedulerListener;
|
||||
import com.arialyy.aria.orm.DbEntity;
|
||||
import com.arialyy.aria.util.CheckUtil;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -58,7 +60,7 @@ public class DownloadReceiver implements IReceiver<DownloadEntity> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取下载链接
|
||||
* 加载下载地址
|
||||
*/
|
||||
public DownloadTarget load(@NonNull String downloadUrl) {
|
||||
CheckUtil.checkDownloadUrl(downloadUrl);
|
||||
@ -67,6 +69,10 @@ public class DownloadReceiver implements IReceiver<DownloadEntity> {
|
||||
if (entity == null) {
|
||||
entity = new DownloadEntity();
|
||||
}
|
||||
File file = new File(entity.getDownloadPath());
|
||||
if (!file.exists()) {
|
||||
entity.setState(IEntity.STATE_WAIT);
|
||||
}
|
||||
entity.setDownloadUrl(downloadUrl);
|
||||
return new DownloadTarget(entity, targetName);
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ 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;
|
||||
@ -192,7 +191,6 @@ class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
private void failDownload(String msg) {
|
||||
Log.e(TAG, msg);
|
||||
CONSTANCE.isDownloading = false;
|
||||
stopDownload();
|
||||
mListener.onFail();
|
||||
}
|
||||
|
||||
@ -210,7 +208,7 @@ class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
+ mDownloadEntity.getDownloadUrl()
|
||||
+ "】\n【filePath:"
|
||||
+ mDownloadFile.getPath()
|
||||
+ "】"
|
||||
+ "】\n"
|
||||
+ CommonUtil.getPrintException(e));
|
||||
}
|
||||
}
|
||||
@ -340,7 +338,7 @@ class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
* 处理不支持断点的下载
|
||||
*/
|
||||
private void handleNoSupportBreakpointDownload(HttpURLConnection conn) {
|
||||
ConfigEntity entity = new ConfigEntity();
|
||||
ChildThreadConfigEntity entity = new ChildThreadConfigEntity();
|
||||
long len = conn.getContentLength();
|
||||
entity.FILE_SIZE = len;
|
||||
entity.DOWNLOAD_URL = mDownloadEntity.isRedirect() ? mDownloadEntity.getRedirectUrl()
|
||||
@ -350,7 +348,7 @@ class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
entity.START_LOCATION = 0;
|
||||
entity.END_LOCATION = entity.FILE_SIZE;
|
||||
entity.CONFIG_FILE_PATH = mConfigFile.getPath();
|
||||
entity.isSupportBreakpoint = isSupportBreakpoint;
|
||||
entity.IS_SUPPORT_BREAK_POINT = isSupportBreakpoint;
|
||||
entity.DOWNLOAD_TASK_ENTITY = mDownloadTaskEntity;
|
||||
THREAD_NUM = 1;
|
||||
CONSTANCE.THREAD_NUM = THREAD_NUM;
|
||||
@ -372,6 +370,7 @@ class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
new BufferedRandomAccessFile(new File(mDownloadFile.getPath()), "rwd", 8192);
|
||||
//设置文件长度
|
||||
file.setLength(fileLength);
|
||||
file.close();
|
||||
mListener.onPostPre(fileLength);
|
||||
//分配每条线程的下载区间
|
||||
pro = CommonUtil.loadConfig(mConfigFile);
|
||||
@ -440,7 +439,7 @@ class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
* 创建单线程任务
|
||||
*/
|
||||
private void addSingleTask(int i, long startL, long endL, long fileLength) {
|
||||
ConfigEntity entity = new ConfigEntity();
|
||||
ChildThreadConfigEntity entity = new ChildThreadConfigEntity();
|
||||
entity.FILE_SIZE = fileLength;
|
||||
entity.DOWNLOAD_URL = mDownloadEntity.isRedirect() ? mDownloadEntity.getRedirectUrl()
|
||||
: mDownloadEntity.getDownloadUrl();
|
||||
@ -449,7 +448,7 @@ class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
entity.START_LOCATION = startL;
|
||||
entity.END_LOCATION = endL;
|
||||
entity.CONFIG_FILE_PATH = mConfigFile.getPath();
|
||||
entity.isSupportBreakpoint = isSupportBreakpoint;
|
||||
entity.IS_SUPPORT_BREAK_POINT = isSupportBreakpoint;
|
||||
entity.DOWNLOAD_TASK_ENTITY = mDownloadTaskEntity;
|
||||
CONSTANCE.THREAD_NUM = THREAD_NUM;
|
||||
SingleThreadTask task = new SingleThreadTask(CONSTANCE, mListener, entity);
|
||||
@ -478,16 +477,20 @@ class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
/**
|
||||
* 子线程下载信息类
|
||||
*/
|
||||
final static class ConfigEntity {
|
||||
//文件大小
|
||||
final static class ChildThreadConfigEntity {
|
||||
//线程Id
|
||||
int THREAD_ID;
|
||||
//下载文件大小
|
||||
long FILE_SIZE;
|
||||
//子线程启动下载位置
|
||||
long START_LOCATION;
|
||||
//子线程结束下载位置
|
||||
long END_LOCATION;
|
||||
//下载路径
|
||||
File TEMP_FILE;
|
||||
String DOWNLOAD_URL;
|
||||
String CONFIG_FILE_PATH;
|
||||
DownloadTaskEntity DOWNLOAD_TASK_ENTITY;
|
||||
boolean isSupportBreakpoint = true;
|
||||
boolean IS_SUPPORT_BREAK_POINT = true;
|
||||
}
|
||||
}
|
@ -28,9 +28,7 @@ import java.math.BigDecimal;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.HashSet;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2017/1/18.
|
||||
@ -38,7 +36,7 @@ import java.util.Set;
|
||||
*/
|
||||
final class SingleThreadTask implements Runnable {
|
||||
private static final String TAG = "SingleThreadTask";
|
||||
private DownloadUtil.ConfigEntity mConfigEntity;
|
||||
private DownloadUtil.ChildThreadConfigEntity mConfigEntity;
|
||||
private String mConfigFPath;
|
||||
private long mChildCurrentLocation = 0;
|
||||
private int mBufSize;
|
||||
@ -47,14 +45,14 @@ final class SingleThreadTask implements Runnable {
|
||||
private long mSleepTime = 0;
|
||||
|
||||
SingleThreadTask(DownloadStateConstance constance, IDownloadListener listener,
|
||||
DownloadUtil.ConfigEntity downloadInfo) {
|
||||
DownloadUtil.ChildThreadConfigEntity downloadInfo) {
|
||||
AriaManager manager = AriaManager.getInstance(AriaManager.APP);
|
||||
CONSTANCE = constance;
|
||||
CONSTANCE.CONNECT_TIME_OUT = manager.getDownloadConfig().getConnectTimeOut();
|
||||
CONSTANCE.READ_TIME_OUT = manager.getDownloadConfig().getIOTimeOut();
|
||||
mListener = listener;
|
||||
this.mConfigEntity = downloadInfo;
|
||||
if (mConfigEntity.isSupportBreakpoint) {
|
||||
if (mConfigEntity.IS_SUPPORT_BREAK_POINT) {
|
||||
mConfigFPath = downloadInfo.CONFIG_FILE_PATH;
|
||||
}
|
||||
mBufSize = manager.getDownloadConfig().getBuffSize();
|
||||
@ -76,12 +74,13 @@ final class SingleThreadTask implements Runnable {
|
||||
}
|
||||
|
||||
@Override public void run() {
|
||||
HttpURLConnection conn;
|
||||
InputStream is;
|
||||
HttpURLConnection conn = null;
|
||||
InputStream is = null;
|
||||
BufferedRandomAccessFile file = null;
|
||||
try {
|
||||
URL url = new URL(mConfigEntity.DOWNLOAD_URL);
|
||||
conn = ConnectionHelp.handleConnection(url);
|
||||
if (mConfigEntity.isSupportBreakpoint) {
|
||||
if (mConfigEntity.IS_SUPPORT_BREAK_POINT) {
|
||||
Log.d(TAG, "任务【"
|
||||
+ mConfigEntity.TEMP_FILE.getName()
|
||||
+ "】线程__"
|
||||
@ -102,8 +101,7 @@ final class SingleThreadTask implements Runnable {
|
||||
conn.setReadTimeout(CONSTANCE.READ_TIME_OUT); //设置读取流的等待时间,必须设置该参数
|
||||
is = conn.getInputStream();
|
||||
//创建可设置位置的文件
|
||||
BufferedRandomAccessFile file =
|
||||
new BufferedRandomAccessFile(mConfigEntity.TEMP_FILE, "rwd", mBufSize);
|
||||
file = new BufferedRandomAccessFile(mConfigEntity.TEMP_FILE, "rwd", mBufSize);
|
||||
//设置每条线程写入文件的位置
|
||||
file.seek(mConfigEntity.START_LOCATION);
|
||||
byte[] buffer = new byte[mBufSize];
|
||||
@ -121,10 +119,6 @@ final class SingleThreadTask implements Runnable {
|
||||
file.write(buffer, 0, len);
|
||||
progress(len);
|
||||
}
|
||||
file.close();
|
||||
//close 为阻塞的,需要使用线程池来处理
|
||||
is.close();
|
||||
conn.disconnect();
|
||||
if (CONSTANCE.isCancel) {
|
||||
return;
|
||||
}
|
||||
@ -133,7 +127,7 @@ final class SingleThreadTask implements Runnable {
|
||||
return;
|
||||
}
|
||||
//支持断点的处理
|
||||
if (mConfigEntity.isSupportBreakpoint) {
|
||||
if (mConfigEntity.IS_SUPPORT_BREAK_POINT) {
|
||||
Log.i(TAG, "任务【"
|
||||
+ mConfigEntity.TEMP_FILE.getName()
|
||||
+ "】线程__"
|
||||
@ -161,6 +155,20 @@ final class SingleThreadTask implements Runnable {
|
||||
failDownload(mChildCurrentLocation, "下载失败【" + mConfigEntity.DOWNLOAD_URL + "】", e);
|
||||
} catch (Exception e) {
|
||||
failDownload(mChildCurrentLocation, "获取流失败", e);
|
||||
} finally {
|
||||
try {
|
||||
if (file != null) {
|
||||
file.close();
|
||||
}
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
if (conn != null) {
|
||||
conn.disconnect();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,7 +178,7 @@ final class SingleThreadTask implements Runnable {
|
||||
protected void stop() {
|
||||
synchronized (AriaManager.LOCK) {
|
||||
try {
|
||||
if (mConfigEntity.isSupportBreakpoint) {
|
||||
if (mConfigEntity.IS_SUPPORT_BREAK_POINT) {
|
||||
CONSTANCE.STOP_NUM++;
|
||||
Log.d(TAG, "任务【"
|
||||
+ mConfigEntity.TEMP_FILE.getName()
|
||||
@ -211,7 +219,7 @@ final class SingleThreadTask implements Runnable {
|
||||
*/
|
||||
protected void cancel() {
|
||||
synchronized (AriaManager.LOCK) {
|
||||
if (mConfigEntity.isSupportBreakpoint) {
|
||||
if (mConfigEntity.IS_SUPPORT_BREAK_POINT) {
|
||||
CONSTANCE.CANCEL_NUM++;
|
||||
Log.d(TAG, "任务【"
|
||||
+ mConfigEntity.TEMP_FILE.getName()
|
||||
@ -250,7 +258,7 @@ final class SingleThreadTask implements Runnable {
|
||||
if (ex != null) {
|
||||
Log.e(TAG, msg + "\n" + CommonUtil.getPrintException(ex));
|
||||
}
|
||||
if (mConfigEntity.isSupportBreakpoint) {
|
||||
if (mConfigEntity.IS_SUPPORT_BREAK_POINT) {
|
||||
writeConfig(false, currentLocation);
|
||||
if (CONSTANCE.isFail()) {
|
||||
Log.e(TAG, "任务【" + mConfigEntity.TEMP_FILE.getName() + "】下载失败");
|
||||
|
@ -35,7 +35,7 @@ public abstract class AbsTaskEntity {
|
||||
public RequestEnum requestEnum = RequestEnum.GET;
|
||||
|
||||
/**
|
||||
* 重定向后,新url的key
|
||||
* 重定向后,从链接中获取新url所需要的key
|
||||
*/
|
||||
public String redirectUrlKey = "location";
|
||||
|
||||
|
@ -39,7 +39,7 @@ public interface IEntity {
|
||||
*/
|
||||
@Ignore public static final int STATE_STOP = 2;
|
||||
/**
|
||||
* 未开始状态
|
||||
* 等待状态
|
||||
*/
|
||||
@Ignore public static final int STATE_WAIT = 3;
|
||||
/**
|
||||
|
@ -44,14 +44,14 @@ public interface ITask<ENTITY extends AbsEntity> {
|
||||
public String getKey();
|
||||
|
||||
/**
|
||||
* 是否真正执行
|
||||
* 任务是否正在执行
|
||||
*
|
||||
* @return true,正在执行;
|
||||
*/
|
||||
public boolean isRunning();
|
||||
|
||||
/**
|
||||
* 获取工具实体
|
||||
* 获取信息实体
|
||||
*/
|
||||
public ENTITY getEntity();
|
||||
|
||||
|
@ -36,6 +36,10 @@ abstract class AbsTaskQueue<TASK extends ITask, TASK_ENTITY extends AbsTaskEntit
|
||||
CachePool<TASK> mCachePool = new CachePool<>();
|
||||
ExecutePool<TASK> mExecutePool;
|
||||
|
||||
@Override public boolean taskIsRunning(String key) {
|
||||
return mExecutePool.getTask(key) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止所有任务
|
||||
*/
|
||||
@ -74,16 +78,16 @@ abstract class AbsTaskQueue<TASK extends ITask, TASK_ENTITY extends AbsTaskEntit
|
||||
*
|
||||
* @return 获取缓存的任务数
|
||||
*/
|
||||
@Override public int cachePoolSize() {
|
||||
@Override public int getCachePoolSize() {
|
||||
return mCachePool.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前运行的任务数
|
||||
* 获取执行池中的任务数量
|
||||
*
|
||||
* @return 当前正在执行的任务数
|
||||
*/
|
||||
@Override public int getExeTaskNum() {
|
||||
@Override public int getExePoolSize() {
|
||||
return mExecutePool.size();
|
||||
}
|
||||
|
||||
@ -130,7 +134,7 @@ abstract class AbsTaskQueue<TASK extends ITask, TASK_ENTITY extends AbsTaskEntit
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void cancelTask(TASK task) {
|
||||
@Override public void removeTask(TASK task) {
|
||||
task.cancel();
|
||||
}
|
||||
|
||||
|
@ -91,6 +91,9 @@ public class DownloadTaskQueue
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 最大下载速度
|
||||
*/
|
||||
public void setMaxSpeed(double maxSpeed) {
|
||||
Map<String, DownloadTask> tasks = mExecutePool.getAllTask();
|
||||
Set<String> keys = tasks.keySet();
|
||||
@ -116,7 +119,7 @@ public class DownloadTaskQueue
|
||||
}
|
||||
}
|
||||
}
|
||||
mExecutePool.setDownloadNum(downloadNum);
|
||||
mExecutePool.setMaxNum(downloadNum);
|
||||
if (diff >= 1) {
|
||||
for (int i = 0; i < diff; i++) {
|
||||
DownloadTask nextTask = getNextTask();
|
||||
|
@ -32,6 +32,14 @@ import com.arialyy.aria.core.upload.UploadTaskEntity;
|
||||
*/
|
||||
public interface ITaskQueue<TASK extends ITask, TASK_ENTITY extends AbsTaskEntity, ENTITY extends IEntity> {
|
||||
|
||||
/**
|
||||
* 通过key判断任务是否正在执行
|
||||
*
|
||||
* @param key 下载链接,或上传文件的路径
|
||||
* @return {@code true} 任务正在运行
|
||||
*/
|
||||
boolean taskIsRunning(String key);
|
||||
|
||||
/**
|
||||
* 停止所有任务
|
||||
*/
|
||||
@ -59,11 +67,18 @@ public interface ITaskQueue<TASK extends ITask, TASK_ENTITY extends AbsTaskEntit
|
||||
void stopTask(TASK task);
|
||||
|
||||
/**
|
||||
* 取消任务
|
||||
* 通过任务任务实体删除任务
|
||||
*
|
||||
* @param task {@link DownloadTask}、{@link UploadTask}
|
||||
*/
|
||||
void cancelTask(TASK task);
|
||||
void removeTask(TASK task);
|
||||
|
||||
/**
|
||||
* 通过工作实体删除任务
|
||||
*
|
||||
* @param entity 工作实体{@link DownloadEntity}、{@link UploadEntity}
|
||||
*/
|
||||
void removeTask(ENTITY entity);
|
||||
|
||||
/**
|
||||
* 重试下载
|
||||
@ -73,24 +88,24 @@ public interface ITaskQueue<TASK extends ITask, TASK_ENTITY extends AbsTaskEntit
|
||||
void reTryStart(TASK task);
|
||||
|
||||
/**
|
||||
* 获取正在执行的任务数量
|
||||
* 获取执行池中的任务数量
|
||||
*/
|
||||
int getExeTaskNum();
|
||||
int getExePoolSize();
|
||||
|
||||
/**
|
||||
* 任务缓存池大小
|
||||
* 获取任务缓存池中的任务数量
|
||||
*/
|
||||
int cachePoolSize();
|
||||
int getCachePoolSize();
|
||||
|
||||
/**
|
||||
* 设置最大任务数
|
||||
* 设置执行池可执行的最大任务数
|
||||
*
|
||||
* @param newMaxNum 最大任务数
|
||||
*/
|
||||
void setMaxTaskNum(int newMaxNum);
|
||||
|
||||
/**
|
||||
* 获取可执行队列的大小
|
||||
* 获取执行池可执行的最大任务数
|
||||
*/
|
||||
int getMaxTaskNum();
|
||||
|
||||
@ -119,13 +134,6 @@ public interface ITaskQueue<TASK extends ITask, TASK_ENTITY extends AbsTaskEntit
|
||||
*/
|
||||
TASK getTask(String url);
|
||||
|
||||
/**
|
||||
* 通过工作实体删除任务
|
||||
*
|
||||
* @param entity 工作实体{@link DownloadEntity}、{@link UploadEntity}
|
||||
*/
|
||||
void removeTask(ENTITY entity);
|
||||
|
||||
/**
|
||||
* 获取缓存池的下一个任务
|
||||
*
|
||||
|
@ -45,7 +45,7 @@ public class CachePool<TASK extends ITask> implements IPool<TASK> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有正在执行的任务
|
||||
* 获取被缓存的任务
|
||||
*/
|
||||
public Map<String, TASK> getAllTask() {
|
||||
return mCacheMap;
|
||||
|
@ -83,19 +83,19 @@ public class ExecutePool<TASK extends ITask> implements IPool<TASK> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置执行任务数
|
||||
* 设置执行队列最大任务数
|
||||
*
|
||||
* @param downloadNum 下载数
|
||||
* @param maxNum 下载数
|
||||
*/
|
||||
public void setDownloadNum(int downloadNum) {
|
||||
public void setMaxNum(int maxNum) {
|
||||
try {
|
||||
ArrayBlockingQueue<TASK> temp = new ArrayBlockingQueue<>(downloadNum);
|
||||
ArrayBlockingQueue<TASK> 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,7 +104,7 @@ public class ExecutePool<TASK extends ITask> implements IPool<TASK> {
|
||||
/**
|
||||
* 添加新任务
|
||||
*
|
||||
* @param newTask 新下载任务
|
||||
* @param newTask 新任务
|
||||
*/
|
||||
private boolean putNewTask(TASK newTask) {
|
||||
String url = newTask.getKey();
|
||||
|
@ -52,17 +52,17 @@ public interface IPool<T extends ITask> {
|
||||
public boolean removeTask(T task);
|
||||
|
||||
/**
|
||||
* 通过下载链接移除下载任务
|
||||
* 通过key除下载任务
|
||||
*
|
||||
* @param downloadUrl 下载链接
|
||||
* @param key 下载链接
|
||||
* @return true:移除成功
|
||||
*/
|
||||
public boolean removeTask(String downloadUrl);
|
||||
public boolean removeTask(String key);
|
||||
|
||||
/**
|
||||
* 池子大小
|
||||
*
|
||||
* @return 返回缓存池或者当前任务池大小
|
||||
* @return 返回缓存池或者执行池大小
|
||||
*/
|
||||
public int size();
|
||||
}
|
@ -140,7 +140,7 @@ public abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskEntity, ENTITY ex
|
||||
}
|
||||
case CANCEL:
|
||||
mQueue.removeTask(entity);
|
||||
if (mQueue.getExeTaskNum() < AriaManager.getInstance(AriaManager.APP)
|
||||
if (mQueue.getExePoolSize() < AriaManager.getInstance(AriaManager.APP)
|
||||
.getUploadConfig()
|
||||
.getMaxTaskNum()) {
|
||||
startNextTask();
|
||||
|
@ -187,6 +187,7 @@ final class SqlHelper extends SQLiteOpenHelper {
|
||||
print(FIND_DATA, sql);
|
||||
Cursor cursor = db.rawQuery(sql, null);
|
||||
List<T> data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null;
|
||||
cursor.close();
|
||||
close(db);
|
||||
return data;
|
||||
}
|
||||
@ -215,6 +216,7 @@ final class SqlHelper extends SQLiteOpenHelper {
|
||||
print(FIND_DATA, sb.toString());
|
||||
Cursor cursor = db.rawQuery(sb.toString(), null);
|
||||
List<T> data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null;
|
||||
cursor.close();
|
||||
close(db);
|
||||
return data;
|
||||
}
|
||||
@ -229,6 +231,7 @@ final class SqlHelper extends SQLiteOpenHelper {
|
||||
print(FIND_ALL_DATA, sb.toString());
|
||||
Cursor cursor = db.rawQuery(sb.toString(), null);
|
||||
List<T> data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null;
|
||||
cursor.close();
|
||||
close(db);
|
||||
return data;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ Aria怎样使用?
|
||||
[](https://bintray.com/arialyy/maven/AriaApi/_latestVersion)
|
||||
[](https://bintray.com/arialyy/maven/AriaCompiler/_latestVersion)
|
||||
```java
|
||||
compile 'com.arialyy.aria:Aria:3.1.9'
|
||||
compile 'com.arialyy.aria:aria-core:3.1.9'
|
||||
annotationProcessor 'com.arialyy.aria:aria-compiler:3.1.9'
|
||||
```
|
||||
|
||||
|
@ -42,7 +42,7 @@ 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 'com.arialyy.aria:aria-core:3.1.9'
|
||||
// annotationProcessor 'com.arialyy.aria:aria-compiler:3.1.9'
|
||||
|
||||
}
|
||||
|
@ -34,6 +34,9 @@
|
||||
<!--是否需要转换速度单位,转换完成后为:1b/s、1kb/s、1mb/s、1gb/s、1tb/s,如果不需要将返回byte长度-->
|
||||
<convertSpeed value="true"/>
|
||||
|
||||
<!--执行队列类型,见com.arialyy.aria.core.QueueMod,默认类型为now-->
|
||||
<queueMod value="wait"/>
|
||||
|
||||
</download>
|
||||
|
||||
<upload>
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
@ -62,9 +62,10 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
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://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://static.gaoshouyou.com/d/36/69/2d3699acfa69e9632262442c46516ad8.apk";
|
||||
//"http://oqcpqqvuf.bkt.clouddn.com/ceshi.txt";
|
||||
//"http://down8.androidgame-store.com/201706122321/97967927DD4E53D9905ECAA7874C8128/new/game1/19/45319/com.neuralprisma-2.5.2.174-2000174_1494784835.apk?f=web_1";
|
||||
//不支持断点的链接
|
||||
@ -153,7 +154,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
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);
|
||||
|
@ -3,6 +3,7 @@ package com.arialyy.simple.test;
|
||||
import android.os.Environment;
|
||||
import android.view.View;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.QueueMod;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.databinding.TestActivityMultiBinding;
|
||||
@ -54,21 +55,26 @@ public class TestMutilTaskSysDownload extends BaseActivity<TestActivityMultiBind
|
||||
"M02/3B/A5/oYYBAFaOeaSAdFyoAACaxVxgUJA092.jpg"
|
||||
};
|
||||
int maxNum = Aria.get(this).getDownloadConfig().getMaxTaskNum();
|
||||
Aria.get(this).setDownloadQueueMod(QueueMod.NOW);
|
||||
for (int i = 0; i < urlArray.length; i++) {
|
||||
if (i < maxNum) {
|
||||
|
||||
Aria.download(this)
|
||||
.load(baseUrl + urlArray[i])
|
||||
.setDownloadPath(Environment.getExternalStorageDirectory() + "/test/" + i + ".jpg")
|
||||
//.addHeader("Accept-Encoding", "gzip,deflate,sdcn")
|
||||
.start();
|
||||
} else {
|
||||
Aria.download(this)
|
||||
.load(baseUrl + urlArray[i])
|
||||
.setDownloadPath(Environment.getExternalStorageDirectory() + "/test/" + i + ".jpg")
|
||||
//.addHeader("Accept-Encoding", "gzip,deflate,sdcn")
|
||||
.add();
|
||||
}
|
||||
//if (i < maxNum) {
|
||||
// Aria.download(this)
|
||||
// .load(baseUrl + urlArray[i])
|
||||
// .setDownloadPath(Environment.getExternalStorageDirectory() + "/test/" + i + ".jpg")
|
||||
// //.addHeader("Accept-Encoding", "gzip,deflate,sdcn")
|
||||
// .start();
|
||||
//} else {
|
||||
// Aria.download(this)
|
||||
// .load(baseUrl + urlArray[i])
|
||||
// .setDownloadPath(Environment.getExternalStorageDirectory() + "/test/" + i + ".jpg")
|
||||
// //.addHeader("Accept-Encoding", "gzip,deflate,sdcn")
|
||||
// .add();
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +68,23 @@ class Configuration {
|
||||
*/
|
||||
boolean isConvertSpeed = false;
|
||||
|
||||
/**
|
||||
* 执行队列类型
|
||||
*
|
||||
* @see QueueMod
|
||||
*/
|
||||
String queueMod = "now";
|
||||
|
||||
public String getQueueMod() {
|
||||
return queueMod;
|
||||
}
|
||||
|
||||
public BaseConfig setQueueMod(String queueMod) {
|
||||
this.queueMod = queueMod;
|
||||
saveKey("queueMod", queueMod);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isOpenBreadCast() {
|
||||
return isOpenBreadCast;
|
||||
}
|
||||
|
Reference in New Issue
Block a user