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..5bcad9cb 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java +++ b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java @@ -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; + } + /** * 如果需要在代码中修改下载配置,请使用以下方法 *
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..260d1d29 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/ConfigHelper.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/ConfigHelper.java
@@ -86,16 +86,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;
     }
   }
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..70d02300
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/QueueMod.java
@@ -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;
+  }
+}
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..8dc620c8 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
@@ -32,13 +32,18 @@ import com.arialyy.aria.util.CommonUtil;
  */
 public abstract class AbsCmd 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 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;
     }
   }
 }
\ 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/AddCmd.java
index fe6d481b..4177dc1d 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/AddCmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/AddCmd.java
@@ -33,10 +33,10 @@ class AddCmd extends AbsCmd {
 
   @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, "添加命令执行失败,【该任务已经存在】");
     }
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/CancelCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/CancelCmd.java
index ad2aecd8..fd51ad14 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/CancelCmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/CancelCmd.java
@@ -31,15 +31,15 @@ class CancelCmd extends AbsCmd {
 
   @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);
     }
   }
 }
\ 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/HighestPriorityCmd.java
index 74999611..57dc35bb 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/HighestPriorityCmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/HighestPriorityCmd.java
@@ -39,9 +39,9 @@ final class HighestPriorityCmd extends AbsCmd {
 
   @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)) {
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/ResumeAllCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/ResumeAllCmd.java
index c7110077..cb87dee7 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/ResumeAllCmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/ResumeAllCmd.java
@@ -27,7 +27,7 @@ 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.getExePoolSize();
       if (exeNum == 0 || exeNum < mQueue.getMaxTaskNum()) {
         ITask task = createTask(entity);
         mQueue.startTask(task);
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java
index 82821ea8..a9a3d180 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java
@@ -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 extends AbsCmd {
 
   @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.startTask(task);
+      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);
+        }
+      }
     }
   }
 }
\ No newline at end of file
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/StopCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/StopCmd.java
index 1e1fb295..8712d6cc 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/StopCmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/StopCmd.java
@@ -34,10 +34,10 @@ class StopCmd extends AbsCmd {
 
   @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, "停止命令执行失败,【调度器中没有该任务】");
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..6aa171ca 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
@@ -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 {
   }
 
   /**
-   * 读取下载链接
+   * 加载下载地址
    */
   public DownloadTarget load(@NonNull String downloadUrl) {
     CheckUtil.checkDownloadUrl(downloadUrl);
@@ -67,6 +69,10 @@ public class DownloadReceiver implements IReceiver {
     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);
   }
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
index 2f08ba86..d91271e4 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadUtil.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadUtil.java
@@ -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;
   }
 }
\ No newline at end of file
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/SingleThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/SingleThreadTask.java
index b6233744..b46b8750 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/SingleThreadTask.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/SingleThreadTask.java
@@ -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() + "】下载失败");
diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java
index eefa1f3a..4f82ad27 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java
@@ -35,7 +35,7 @@ public abstract class AbsTaskEntity {
   public RequestEnum requestEnum = RequestEnum.GET;
 
   /**
-   * 重定向后,新url的key
+   * 重定向后,从链接中获取新url所需要的key
    */
   public String redirectUrlKey = "location";
 
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..fe529b49 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
@@ -39,7 +39,7 @@ public interface IEntity {
    */
   @Ignore public static final int STATE_STOP = 2;
   /**
-   * 未开始状态
+   * 等待状态
    */
   @Ignore public static final int STATE_WAIT = 3;
   /**
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..27b4af9b 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
@@ -44,14 +44,14 @@ public interface ITask {
   public String getKey();
 
   /**
-   * 是否真正执行
+   * 任务是否正在执行
    *
    * @return true,正在执行;
    */
   public boolean isRunning();
 
   /**
-   * 获取工具实体
+   * 获取信息实体
    */
   public ENTITY getEntity();
 
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..67f55038 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
@@ -36,6 +36,10 @@ abstract class AbsTaskQueue mCachePool = new CachePool<>();
   ExecutePool mExecutePool;
 
+  @Override public boolean taskIsRunning(String key) {
+    return mExecutePool.getTask(key) != null;
+  }
+
   /**
    * 停止所有任务
    */
@@ -74,16 +78,16 @@ abstract class AbsTaskQueue tasks = mExecutePool.getAllTask();
     Set keys = tasks.keySet();
-    for (String key : keys){
+    for (String key : keys) {
       DownloadTask task = tasks.get(key);
       task.setMaxSpeed(maxSpeed);
     }
@@ -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();
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..f6fd93d5 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
@@ -32,6 +32,14 @@ import com.arialyy.aria.core.upload.UploadTaskEntity;
  */
 public interface ITaskQueue {
 
+  /**
+   * 通过key判断任务是否正在执行
+   *
+   * @param key 下载链接,或上传文件的路径
+   * @return {@code true} 任务正在运行
+   */
+  boolean taskIsRunning(String key);
+
   /**
    * 停止所有任务
    */
@@ -59,11 +67,18 @@ public interface ITaskQueue implements IPool {
   }
 
   /**
-   * 获取所有正在执行的任务
+   * 获取被缓存的任务
    */
   public Map getAllTask() {
     return mCacheMap;
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/ExecutePool.java
index 4f9691af..6892d208 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/ExecutePool.java
@@ -83,19 +83,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,7 +104,7 @@ public class ExecutePool implements IPool {
   /**
    * 添加新任务
    *
-   * @param newTask 新下载任务
+   * @param newTask 新任务
    */
   private boolean putNewTask(TASK newTask) {
     String url = newTask.getKey();
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..970c22b9 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
@@ -52,17 +52,17 @@ public interface IPool {
   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();
 }
\ No newline at end of file
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..4aa14f66 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
@@ -140,7 +140,7 @@ public abstract class AbsSchedulers 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 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 data = cursor.getCount() > 0 ? newInstanceEntity(clazz, cursor) : null;
+    cursor.close();
     close(db);
     return data;
   }
diff --git a/README.md b/README.md
index f1e78ebd..8e71303a 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,7 @@ 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:3.1.9'
+compile 'com.arialyy.aria:aria-core:3.1.9'
 annotationProcessor 'com.arialyy.aria:aria-compiler:3.1.9'
 ```
 
diff --git a/app/build.gradle b/app/build.gradle
index e4a53267..58c03308 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -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'
 
 }
diff --git a/app/src/main/assets/aria_config.xml b/app/src/main/assets/aria_config.xml
index f9ed36f3..9972caa4 100644
--- a/app/src/main/assets/aria_config.xml
+++ b/app/src/main/assets/aria_config.xml
@@ -34,6 +34,9 @@
     
     
 
+    
+    
+
   
 
   
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/download/SingleTaskActivity.java b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java
index 6e3b468e..76585966 100644
--- a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java
+++ b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java
@@ -62,9 +62,10 @@ public class SingleTaskActivity extends BaseActivity {
   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://tinghuaapp.oss-cn-shanghai.aliyuncs.com/20170612201739607815";
-  //"http://static.gaoshouyou.com/d/36/69/2d3699acfa69e9632262442c46516ad8.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://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 {
     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);
diff --git a/app/src/main/java/com/arialyy/simple/test/TestMutilTaskSysDownload.java b/app/src/main/java/com/arialyy/simple/test/TestMutilTaskSysDownload.java
index 71b235e5..45e659aa 100644
--- a/app/src/main/java/com/arialyy/simple/test/TestMutilTaskSysDownload.java
+++ b/app/src/main/java/com/arialyy/simple/test/TestMutilTaskSysDownload.java
@@ -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