pull/330/head
AriaLyy 8 years ago
parent bae48a4126
commit 0d59c7b421
  1. 41
      Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
  2. 4
      Aria/src/main/java/com/arialyy/aria/core/command/CmdFactory.java
  3. 2
      Aria/src/main/java/com/arialyy/aria/core/command/HighestPriorityCmd.java
  4. 2
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java
  5. 35
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java
  6. 20
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadUtil.java
  7. 70
      Aria/src/main/java/com/arialyy/aria/core/download/SingleThreadTask.java
  8. 2
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java
  9. 4
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsTask.java
  10. 6
      Aria/src/main/java/com/arialyy/aria/core/inf/ITask.java
  11. 6
      Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java
  12. 4
      Aria/src/main/java/com/arialyy/aria/core/queue/TaskFactory.java
  13. 4
      Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java
  14. 34
      Aria/src/main/java/com/arialyy/aria/core/queue/pool/CachePool.java
  15. 11
      Aria/src/main/java/com/arialyy/aria/core/queue/pool/ExecutePool.java
  16. 23
      Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java
  17. 4
      Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadSchedulers.java
  18. 4
      Aria/src/main/java/com/arialyy/aria/core/scheduler/UploadSchedulers.java
  19. 4
      Aria/src/main/java/com/arialyy/aria/orm/DbUtil.java
  20. 4
      Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java
  21. 9
      README.md
  22. 2
      app/src/main/assets/aria_config.xml
  23. 2
      app/src/main/java/com/arialyy/simple/download/HighestPriorityActivity.java
  24. 10
      app/src/main/java/com/arialyy/simple/download/multi_download/MultiDownloadActivity.java

@ -36,6 +36,7 @@ import com.arialyy.aria.orm.DbUtil;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
@ -55,7 +56,7 @@ import org.xml.sax.SAXException;
private static final String TAG = "AriaManager"; private static final String TAG = "AriaManager";
private static final String DOWNLOAD = "_download"; private static final String DOWNLOAD = "_download";
private static final String UPLOAD = "_upload"; private static final String UPLOAD = "_upload";
private static final Object LOCK = new Object(); public static final Object LOCK = new Object();
public static final String DOWNLOAD_TEMP_DIR = "/Aria/temp/download/"; public static final String DOWNLOAD_TEMP_DIR = "/Aria/temp/download/";
public static final String UPLOAD_TEMP_DIR = "/Aria/temp/upload/"; public static final String UPLOAD_TEMP_DIR = "/Aria/temp/upload/";
@SuppressLint("StaticFieldLeak") private static volatile AriaManager INSTANCE = null; @SuppressLint("StaticFieldLeak") private static volatile AriaManager INSTANCE = null;
@ -85,20 +86,6 @@ import org.xml.sax.SAXException;
return mReceivers; return mReceivers;
} }
/**
* 加载配置文件
*/
private void loadConfig() {
try {
ConfigHelper helper = new ConfigHelper();
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse(APP.getAssets().open("aria_config.xml"), helper);
} catch (ParserConfigurationException | IOException | SAXException e) {
Log.e(TAG, e.toString());
}
}
/** /**
* 如果需要在代码中修改下载配置请使用以下方法 * 如果需要在代码中修改下载配置请使用以下方法
* <pre> * <pre>
@ -255,7 +242,13 @@ import org.xml.sax.SAXException;
} else { } else {
try { try {
String md5Code = CommonUtil.getFileMD5(xmlFile); String md5Code = CommonUtil.getFileMD5(xmlFile);
if (!CommonUtil.checkMD5(md5Code, APP.getAssets().open("aria_config.xml"))) { File file = new File(APP.getFilesDir().getPath() + "temp.xml");
if (file.exists()) {
file.delete();
}
CommonUtil.createFileFormInputStream(APP.getAssets().open("aria_config.xml"),
file.getPath());
if (!CommonUtil.checkMD5(md5Code, file)) {
loadConfig(); loadConfig();
} }
} catch (IOException e) { } catch (IOException e) {
@ -271,6 +264,22 @@ import org.xml.sax.SAXException;
} }
} }
/**
* 加载配置文件
*/
private void loadConfig() {
try {
ConfigHelper helper = new ConfigHelper();
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse(APP.getAssets().open("aria_config.xml"), helper);
CommonUtil.createFileFormInputStream(APP.getAssets().open("aria_config.xml"),
APP.getFilesDir().getPath() + Configuration.XML_FILE);
} catch (ParserConfigurationException | IOException | SAXException e) {
Log.e(TAG, e.toString());
}
}
/** /**
* 注册APP生命周期回调 * 注册APP生命周期回调
*/ */

@ -16,6 +16,7 @@
package com.arialyy.aria.core.command; package com.arialyy.aria.core.command;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.AbsTaskEntity;
/** /**
@ -50,7 +51,6 @@ public class CmdFactory {
public static final int TASK_SINGLE = 0x126; public static final int TASK_SINGLE = 0x126;
private static final Object LOCK = new Object();
private static volatile CmdFactory INSTANCE = null; private static volatile CmdFactory INSTANCE = null;
private CmdFactory() { private CmdFactory() {
@ -59,7 +59,7 @@ public class CmdFactory {
public static CmdFactory getInstance() { public static CmdFactory getInstance() {
if (INSTANCE == null) { if (INSTANCE == null) {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
INSTANCE = new CmdFactory(); INSTANCE = new CmdFactory();
} }
} }

@ -26,7 +26,7 @@ import com.arialyy.aria.core.inf.AbsTaskEntity;
* 2最高优先级任务会一直存在直到用户手动暂停或任务完成 * 2最高优先级任务会一直存在直到用户手动暂停或任务完成
* 3任务调度器不会暂停最高优先级任务 * 3任务调度器不会暂停最高优先级任务
* 4用户手动暂停或任务完成后第二次重新执行该任务该命令将失效 * 4用户手动暂停或任务完成后第二次重新执行该任务该命令将失效
* 5如果下载队列中已经满了则会停止队尾的任务 * 5如果下载队列中已经满了则会停止队尾的任务当高优先级任务完成后该队尾任务将自动执行
* 6把任务设置为最高优先级任务后将自动执行任务不需要重新调用start()启动任务 * 6把任务设置为最高优先级任务后将自动执行任务不需要重新调用start()启动任务
*/ */
final class HighestPriorityCmd<T extends AbsTaskEntity> extends AbsCmd<T> { final class HighestPriorityCmd<T extends AbsTaskEntity> extends AbsCmd<T> {

@ -50,7 +50,7 @@ public class DownloadTarget extends AbsTarget<DownloadEntity, DownloadTaskEntity
* 2最高优先级任务会一直存在直到用户手动暂停或任务完成 * 2最高优先级任务会一直存在直到用户手动暂停或任务完成
* 3任务调度器不会暂停最高优先级任务 * 3任务调度器不会暂停最高优先级任务
* 4用户手动暂停或任务完成后第二次重新执行该任务该命令将失效 * 4用户手动暂停或任务完成后第二次重新执行该任务该命令将失效
* 5如果下载队列中已经满了则会停止队尾的任务 * 5如果下载队列中已经满了则会停止队尾的任务当高优先级任务完成后该队尾任务将自动执行
* 6把任务设置为最高优先级任务后将自动执行任务不需要重新调用start()启动任务 * 6把任务设置为最高优先级任务后将自动执行任务不需要重新调用start()启动任务
*/ */
@Override public void setHighestPriority() { @Override public void setHighestPriority() {

@ -23,6 +23,7 @@ import android.util.Log;
import com.arialyy.aria.core.Aria; import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.AbsTask;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.scheduler.DownloadSchedulers; import com.arialyy.aria.core.scheduler.DownloadSchedulers;
import com.arialyy.aria.core.scheduler.ISchedulers; import com.arialyy.aria.core.scheduler.ISchedulers;
import com.arialyy.aria.util.CheckUtil; import com.arialyy.aria.util.CheckUtil;
@ -39,6 +40,7 @@ public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> {
private IDownloadListener mListener; private IDownloadListener mListener;
private Handler mOutHandler; private Handler mOutHandler;
private IDownloadUtil mUtil; private IDownloadUtil mUtil;
private boolean isWait = false;
private DownloadTask(DownloadTaskEntity taskEntity, Handler outHandler) { private DownloadTask(DownloadTaskEntity taskEntity, Handler outHandler) {
mEntity = taskEntity.downloadEntity; mEntity = taskEntity.downloadEntity;
@ -78,15 +80,23 @@ public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> {
return mEntity; return mEntity;
} }
/**
* 暂停任务并让任务处于等待状态
*/
@Override public void stopAndWait() {
super.stopAndWait();
stop(true);
}
/** /**
* 开始下载 * 开始下载
*/ */
@Override public void start() { @Override public void start() {
isWait = false;
if (mUtil.isDownloading()) { if (mUtil.isDownloading()) {
Log.d(TAG, "任务正在下载"); Log.d(TAG, "任务正在下载");
} else { } else {
if (mListener == null) { if (mListener == null || isWait) {
mListener = new DListener(mContext, this, mOutHandler); mListener = new DListener(mContext, this, mOutHandler);
} }
mUtil.startDownload(); mUtil.startDownload();
@ -97,10 +107,15 @@ public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> {
* 停止下载 * 停止下载
*/ */
@Override public void stop() { @Override public void stop() {
stop(false);
}
private void stop(boolean isWait) {
this.isWait = isWait;
if (mUtil.isDownloading()) { if (mUtil.isDownloading()) {
mUtil.stopDownload(); mUtil.stopDownload();
} else { } else {
mEntity.setState(DownloadEntity.STATE_STOP); mEntity.setState(isWait ? IEntity.STATE_WAIT : IEntity.STATE_STOP);
mEntity.save(); mEntity.save();
if (mOutHandler != null) { if (mOutHandler != null) {
mOutHandler.obtainMessage(DownloadSchedulers.STOP, this).sendToTarget(); mOutHandler.obtainMessage(DownloadSchedulers.STOP, this).sendToTarget();
@ -201,7 +216,7 @@ public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> {
@Override public void onPre() { @Override public void onPre() {
super.onPre(); super.onPre();
downloadEntity.setState(DownloadEntity.STATE_PRE); downloadEntity.setState(IEntity.STATE_PRE);
sendInState2Target(ISchedulers.PRE); sendInState2Target(ISchedulers.PRE);
sendIntent(Aria.ACTION_PRE, -1); sendIntent(Aria.ACTION_PRE, -1);
} }
@ -209,21 +224,21 @@ public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> {
@Override public void onPostPre(long fileSize) { @Override public void onPostPre(long fileSize) {
super.onPostPre(fileSize); super.onPostPre(fileSize);
downloadEntity.setFileSize(fileSize); downloadEntity.setFileSize(fileSize);
downloadEntity.setState(DownloadEntity.STATE_POST_PRE); downloadEntity.setState(IEntity.STATE_POST_PRE);
sendInState2Target(ISchedulers.POST_PRE); sendInState2Target(ISchedulers.POST_PRE);
sendIntent(Aria.ACTION_POST_PRE, -1); sendIntent(Aria.ACTION_POST_PRE, -1);
} }
@Override public void onResume(long resumeLocation) { @Override public void onResume(long resumeLocation) {
super.onResume(resumeLocation); super.onResume(resumeLocation);
downloadEntity.setState(DownloadEntity.STATE_RUNNING); downloadEntity.setState(IEntity.STATE_RUNNING);
sendInState2Target(ISchedulers.RESUME); sendInState2Target(ISchedulers.RESUME);
sendIntent(Aria.ACTION_RESUME, resumeLocation); sendIntent(Aria.ACTION_RESUME, resumeLocation);
} }
@Override public void onStart(long startLocation) { @Override public void onStart(long startLocation) {
super.onStart(startLocation); super.onStart(startLocation);
downloadEntity.setState(DownloadEntity.STATE_RUNNING); downloadEntity.setState(IEntity.STATE_RUNNING);
sendInState2Target(ISchedulers.START); sendInState2Target(ISchedulers.START);
sendIntent(Aria.ACTION_START, startLocation); sendIntent(Aria.ACTION_START, startLocation);
} }
@ -249,7 +264,7 @@ public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> {
@Override public void onStop(long stopLocation) { @Override public void onStop(long stopLocation) {
super.onStop(stopLocation); super.onStop(stopLocation);
downloadEntity.setState(DownloadEntity.STATE_STOP); downloadEntity.setState(task.isWait ? IEntity.STATE_WAIT : IEntity.STATE_STOP);
handleSpeed(0); handleSpeed(0);
sendInState2Target(ISchedulers.STOP); sendInState2Target(ISchedulers.STOP);
sendIntent(Aria.ACTION_STOP, stopLocation); sendIntent(Aria.ACTION_STOP, stopLocation);
@ -257,7 +272,7 @@ public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> {
@Override public void onCancel() { @Override public void onCancel() {
super.onCancel(); super.onCancel();
downloadEntity.setState(DownloadEntity.STATE_CANCEL); downloadEntity.setState(IEntity.STATE_CANCEL);
handleSpeed(0); handleSpeed(0);
sendInState2Target(ISchedulers.CANCEL); sendInState2Target(ISchedulers.CANCEL);
sendIntent(Aria.ACTION_CANCEL, -1); sendIntent(Aria.ACTION_CANCEL, -1);
@ -266,7 +281,7 @@ public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> {
@Override public void onComplete() { @Override public void onComplete() {
super.onComplete(); super.onComplete();
downloadEntity.setState(DownloadEntity.STATE_COMPLETE); downloadEntity.setState(IEntity.STATE_COMPLETE);
downloadEntity.setDownloadComplete(true); downloadEntity.setDownloadComplete(true);
handleSpeed(0); handleSpeed(0);
sendInState2Target(ISchedulers.COMPLETE); sendInState2Target(ISchedulers.COMPLETE);
@ -276,7 +291,7 @@ public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> {
@Override public void onFail() { @Override public void onFail() {
super.onFail(); super.onFail();
downloadEntity.setFailNum(downloadEntity.getFailNum() + 1); downloadEntity.setFailNum(downloadEntity.getFailNum() + 1);
downloadEntity.setState(DownloadEntity.STATE_FAIL); downloadEntity.setState(IEntity.STATE_FAIL);
handleSpeed(0); handleSpeed(0);
sendInState2Target(ISchedulers.FAIL); sendInState2Target(ISchedulers.FAIL);
sendIntent(Aria.ACTION_FAIL, -1); sendIntent(Aria.ACTION_FAIL, -1);

@ -66,7 +66,7 @@ class DownloadUtil implements IDownloadUtil, Runnable {
mDownloadTaskEntity = entity; mDownloadTaskEntity = entity;
mListener = downloadListener; mListener = downloadListener;
// 线程下载数改变后,新的下载才会生效 // 线程下载数改变后,新的下载才会生效
mFixedThreadPool = Executors.newFixedThreadPool(Integer.MAX_VALUE); //mFixedThreadPool = Executors.newFixedThreadPool(Integer.MAX_VALUE);
CONSTANCE = new DownloadStateConstance(); CONSTANCE = new DownloadStateConstance();
init(); init();
} }
@ -75,8 +75,10 @@ class DownloadUtil implements IDownloadUtil, Runnable {
mConnectTimeOut = AriaManager.getInstance(mContext).getDownloadConfig().getConnectTimeOut(); mConnectTimeOut = AriaManager.getInstance(mContext).getDownloadConfig().getConnectTimeOut();
mDownloadFile = new File(mDownloadTaskEntity.downloadEntity.getDownloadPath()); mDownloadFile = new File(mDownloadTaskEntity.downloadEntity.getDownloadPath());
//读取已完成的线程数 //读取已完成的线程数
mConfigFile = new File( mConfigFile = new File(mContext.getFilesDir().getPath()
mContext.getFilesDir().getPath() + AriaManager.DOWNLOAD_TEMP_DIR + mDownloadFile.getName() + ".properties"); + AriaManager.DOWNLOAD_TEMP_DIR
+ mDownloadFile.getName()
+ ".properties");
try { try {
if (!mConfigFile.exists()) { //记录文件被删除,则重新下载 if (!mConfigFile.exists()) { //记录文件被删除,则重新下载
handleNewTask(); handleNewTask();
@ -111,7 +113,9 @@ class DownloadUtil implements IDownloadUtil, Runnable {
@Override public void cancelDownload() { @Override public void cancelDownload() {
CONSTANCE.isCancel = true; CONSTANCE.isCancel = true;
CONSTANCE.isDownloading = false; CONSTANCE.isDownloading = false;
if (mFixedThreadPool != null) {
mFixedThreadPool.shutdown(); mFixedThreadPool.shutdown();
}
for (int i = 0; i < THREAD_NUM; i++) { for (int i = 0; i < THREAD_NUM; i++) {
SingleThreadTask task = (SingleThreadTask) mTask.get(i); SingleThreadTask task = (SingleThreadTask) mTask.get(i);
if (task != null) { if (task != null) {
@ -126,7 +130,9 @@ class DownloadUtil implements IDownloadUtil, Runnable {
@Override public void stopDownload() { @Override public void stopDownload() {
CONSTANCE.isStop = true; CONSTANCE.isStop = true;
CONSTANCE.isDownloading = false; CONSTANCE.isDownloading = false;
if (mFixedThreadPool != null) {
mFixedThreadPool.shutdown(); mFixedThreadPool.shutdown();
}
for (int i = 0; i < THREAD_NUM; i++) { for (int i = 0; i < THREAD_NUM; i++) {
SingleThreadTask task = (SingleThreadTask) mTask.get(i); SingleThreadTask task = (SingleThreadTask) mTask.get(i);
if (task != null) { if (task != null) {
@ -304,7 +310,7 @@ class DownloadUtil implements IDownloadUtil, Runnable {
if (!isNewTask && record != null && Long.parseLong(record + "") > 0) { if (!isNewTask && record != null && Long.parseLong(record + "") > 0) {
Long r = Long.parseLong(record + ""); Long r = Long.parseLong(record + "");
CONSTANCE.CURRENT_LOCATION += r - startL; CONSTANCE.CURRENT_LOCATION += r - startL;
Log.d(TAG, "++++++++++ 线程_" + i + "_恢复下载 ++++++++++"); Log.d(TAG, "任务【" + mDownloadEntity.getFileName() + "】线程__" + i + "__恢复下载");
mListener.onChildResume(r); mListener.onChildResume(r);
startL = r; startL = r;
recordL[rl] = i; recordL[rl] = i;
@ -386,9 +392,10 @@ class DownloadUtil implements IDownloadUtil, Runnable {
continue; continue;
} }
handleNewTask(); handleNewTask();
break; return pro;
} }
} }
isNewTask = false;
} }
return pro; return pro;
} }
@ -452,10 +459,11 @@ class DownloadUtil implements IDownloadUtil, Runnable {
} else { } else {
mListener.onStart(CONSTANCE.CURRENT_LOCATION); mListener.onStart(CONSTANCE.CURRENT_LOCATION);
} }
mFixedThreadPool = Executors.newFixedThreadPool(recordL.length);
for (int l : recordL) { for (int l : recordL) {
if (l == -1) continue; if (l == -1) continue;
Runnable task = mTask.get(l); Runnable task = mTask.get(l);
if (task != null && !mFixedThreadPool.isShutdown()) { if (task != null) {
mFixedThreadPool.execute(task); mFixedThreadPool.execute(task);
} }
} }

@ -15,6 +15,7 @@
*/ */
package com.arialyy.aria.core.download; package com.arialyy.aria.core.download;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.util.BufferedRandomAccessFile; import com.arialyy.aria.util.BufferedRandomAccessFile;
@ -36,7 +37,6 @@ final class SingleThreadTask implements Runnable {
private DownloadUtil.ConfigEntity mConfigEntity; private DownloadUtil.ConfigEntity mConfigEntity;
private String mConfigFPath; private String mConfigFPath;
private long mChildCurrentLocation = 0; private long mChildCurrentLocation = 0;
private static final Object LOCK = new Object();
private int mBufSize; private int mBufSize;
private IDownloadListener mListener; private IDownloadListener mListener;
private DownloadStateConstance CONSTANCE; private DownloadStateConstance CONSTANCE;
@ -62,9 +62,11 @@ final class SingleThreadTask implements Runnable {
URL url = new URL(mConfigEntity.DOWNLOAD_URL); URL url = new URL(mConfigEntity.DOWNLOAD_URL);
conn = ConnectionHelp.handleConnection(url); conn = ConnectionHelp.handleConnection(url);
if (mConfigEntity.isSupportBreakpoint) { if (mConfigEntity.isSupportBreakpoint) {
Log.d(TAG, "线程_" Log.d(TAG, "任务【"
+ mConfigEntity.TEMP_FILE.getName()
+ "】线程__"
+ mConfigEntity.THREAD_ID + mConfigEntity.THREAD_ID
+ "_正在下载【开始位置 : " + "__开始下载【开始位置 : "
+ mConfigEntity.START_LOCATION + mConfigEntity.START_LOCATION
+ ",结束位置:" + ",结束位置:"
+ mConfigEntity.END_LOCATION + mConfigEntity.END_LOCATION
@ -112,9 +114,12 @@ final class SingleThreadTask implements Runnable {
} }
//支持断点的处理 //支持断点的处理
if (mConfigEntity.isSupportBreakpoint) { if (mConfigEntity.isSupportBreakpoint) {
Log.i(TAG, Log.i(TAG, "任务【"
"任务【" + mConfigEntity.TEMP_FILE.getName() + "】线程【" + mConfigEntity.THREAD_ID + "】下载完毕"); + mConfigEntity.TEMP_FILE.getName()
writeConfig(1); + "】线程__"
+ mConfigEntity.THREAD_ID
+ "__下载完毕");
writeConfig(true, 1);
mListener.onChildComplete(mConfigEntity.END_LOCATION); mListener.onChildComplete(mConfigEntity.END_LOCATION);
CONSTANCE.COMPLETE_THREAD_NUM++; CONSTANCE.COMPLETE_THREAD_NUM++;
if (CONSTANCE.isComplete()) { if (CONSTANCE.isComplete()) {
@ -143,22 +148,24 @@ final class SingleThreadTask implements Runnable {
* 停止下载 * 停止下载
*/ */
protected void stop() { protected void stop() {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
try { try {
if (mConfigEntity.isSupportBreakpoint) { if (mConfigEntity.isSupportBreakpoint) {
CONSTANCE.STOP_NUM++; CONSTANCE.STOP_NUM++;
Log.d(TAG, "thread_" Log.d(TAG, "任务【"
+ mConfigEntity.TEMP_FILE.getName()
+ "】thread__"
+ mConfigEntity.THREAD_ID + mConfigEntity.THREAD_ID
+ "_stop, stop location ==> " + "__停止, stop location ==> "
+ mChildCurrentLocation); + mChildCurrentLocation);
writeConfig(mChildCurrentLocation); writeConfig(false, mChildCurrentLocation);
if (CONSTANCE.isStop()) { if (CONSTANCE.isStop()) {
Log.d(TAG, "++++++++++++++++ onStop +++++++++++++++++"); Log.d(TAG, "任务【" + mConfigEntity.TEMP_FILE.getName() + "】已停止");
CONSTANCE.isDownloading = false; CONSTANCE.isDownloading = false;
mListener.onStop(CONSTANCE.CURRENT_LOCATION); mListener.onStop(CONSTANCE.CURRENT_LOCATION);
} }
} else { } else {
Log.d(TAG, "++++++++++++++++ onStop +++++++++++++++++"); Log.d(TAG, "任务【" + mConfigEntity.TEMP_FILE.getName() + "】已停止");
CONSTANCE.isDownloading = false; CONSTANCE.isDownloading = false;
mListener.onStop(CONSTANCE.CURRENT_LOCATION); mListener.onStop(CONSTANCE.CURRENT_LOCATION);
} }
@ -172,7 +179,7 @@ final class SingleThreadTask implements Runnable {
* 下载中 * 下载中
*/ */
private void progress(long len) { private void progress(long len) {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
mChildCurrentLocation += len; mChildCurrentLocation += len;
CONSTANCE.CURRENT_LOCATION += len; CONSTANCE.CURRENT_LOCATION += len;
mListener.onProgress(CONSTANCE.CURRENT_LOCATION); mListener.onProgress(CONSTANCE.CURRENT_LOCATION);
@ -183,10 +190,14 @@ final class SingleThreadTask implements Runnable {
* 取消下载 * 取消下载
*/ */
protected void cancel() { protected void cancel() {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
if (mConfigEntity.isSupportBreakpoint) { if (mConfigEntity.isSupportBreakpoint) {
CONSTANCE.CANCEL_NUM++; CONSTANCE.CANCEL_NUM++;
Log.d(TAG, "++++++++++ thread_" + mConfigEntity.THREAD_ID + "_cancel ++++++++++"); Log.d(TAG, "任务【"
+ mConfigEntity.TEMP_FILE.getName()
+ "】thread__"
+ mConfigEntity.THREAD_ID
+ "__取消下载");
if (CONSTANCE.isCancel()) { if (CONSTANCE.isCancel()) {
File configFile = new File(mConfigFPath); File configFile = new File(mConfigFPath);
if (configFile.exists()) { if (configFile.exists()) {
@ -195,12 +206,12 @@ final class SingleThreadTask implements Runnable {
if (mConfigEntity.TEMP_FILE.exists()) { if (mConfigEntity.TEMP_FILE.exists()) {
mConfigEntity.TEMP_FILE.delete(); mConfigEntity.TEMP_FILE.delete();
} }
Log.d(TAG, "++++++++++++++++ onCancel +++++++++++++++++"); Log.d(TAG, "任务【" + mConfigEntity.TEMP_FILE.getName() + "】已取消");
CONSTANCE.isDownloading = false; CONSTANCE.isDownloading = false;
mListener.onCancel(); mListener.onCancel();
} }
} else { } else {
Log.d(TAG, "++++++++++++++++ onCancel +++++++++++++++++"); Log.d(TAG, "任务【" + mConfigEntity.TEMP_FILE.getName() + "】已取消");
CONSTANCE.isDownloading = false; CONSTANCE.isDownloading = false;
mListener.onCancel(); mListener.onCancel();
} }
@ -211,7 +222,7 @@ final class SingleThreadTask implements Runnable {
* 下载失败 * 下载失败
*/ */
private void failDownload(long currentLocation, String msg, Exception ex) { private void failDownload(long currentLocation, String msg, Exception ex) {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
try { try {
CONSTANCE.FAIL_NUM++; CONSTANCE.FAIL_NUM++;
CONSTANCE.isDownloading = false; CONSTANCE.isDownloading = false;
@ -220,13 +231,13 @@ final class SingleThreadTask implements Runnable {
Log.e(TAG, msg + "\n" + CommonUtil.getPrintException(ex)); Log.e(TAG, msg + "\n" + CommonUtil.getPrintException(ex));
} }
if (mConfigEntity.isSupportBreakpoint) { if (mConfigEntity.isSupportBreakpoint) {
writeConfig(currentLocation); writeConfig(false, currentLocation);
if (CONSTANCE.isFail()) { if (CONSTANCE.isFail()) {
Log.d(TAG, "++++++++++++++++ onFail +++++++++++++++++"); Log.e(TAG, "任务【" + mConfigEntity.TEMP_FILE.getName() + "】下载失败");
mListener.onFail(); mListener.onFail();
} }
} else { } else {
Log.d(TAG, "++++++++++++++++ onFail +++++++++++++++++"); Log.e(TAG, "任务【" + mConfigEntity.TEMP_FILE.getName() + "】下载失败");
mListener.onFail(); mListener.onFail();
} }
} catch (IOException e) { } catch (IOException e) {
@ -238,13 +249,22 @@ final class SingleThreadTask implements Runnable {
/** /**
* 将记录写入到配置文件 * 将记录写入到配置文件
*/ */
private void writeConfig(long record) throws IOException { private void writeConfig(boolean isComplete, long record) throws IOException {
if (record > 0) { synchronized (AriaManager.LOCK) {
String key = mConfigEntity.TEMP_FILE.getName() + "_record_" + mConfigEntity.THREAD_ID; String key = null, value = null;
if (0 < record && record < mConfigEntity.END_LOCATION) {
key = mConfigEntity.TEMP_FILE.getName() + "_record_" + mConfigEntity.THREAD_ID;
value = String.valueOf(record);
} else if (record >= mConfigEntity.END_LOCATION || isComplete) {
key = mConfigEntity.TEMP_FILE.getName() + "_state_" + mConfigEntity.THREAD_ID;
value = "1";
}
if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
File configFile = new File(mConfigFPath); File configFile = new File(mConfigFPath);
Properties pro = CommonUtil.loadConfig(configFile); Properties pro = CommonUtil.loadConfig(configFile);
pro.setProperty(key, String.valueOf(record)); pro.setProperty(key, value);
CommonUtil.saveConfig(configFile, pro); CommonUtil.saveConfig(configFile, pro);
} }
} }
} }
}

@ -53,7 +53,7 @@ public abstract class AbsTarget<ENTITY extends AbsEntity, TASK_ENTITY extends Ab
* 2最高优先级任务会一直存在直到用户手动暂停或任务完成 * 2最高优先级任务会一直存在直到用户手动暂停或任务完成
* 3任务调度器不会暂停最高优先级任务 * 3任务调度器不会暂停最高优先级任务
* 4用户手动暂停或任务完成后第二次重新执行该任务该命令将失效 * 4用户手动暂停或任务完成后第二次重新执行该任务该命令将失效
* 5如果下载队列中已经满了则会停止队尾的任务 * 5如果下载队列中已经满了则会停止队尾的任务当高优先级任务完成后该队尾任务将自动执行
* 6把任务设置为最高优先级任务后将自动执行任务不需要重新调用start()启动任务 * 6把任务设置为最高优先级任务后将自动执行任务不需要重新调用start()启动任务
*/ */
protected void setHighestPriority() { protected void setHighestPriority() {

@ -33,6 +33,10 @@ public abstract class AbsTask<TASK_ENTITY extends AbsTaskEntity, ENTITY extends
protected Context mContext; protected Context mContext;
private boolean isHeighestTask = false; private boolean isHeighestTask = false;
@Override public void stopAndWait() {
}
/** /**
* @return 返回原始byte速度需要你在配置文件中配置 * @return 返回原始byte速度需要你在配置文件中配置
* <pre> * <pre>

@ -21,6 +21,11 @@ package com.arialyy.aria.core.inf;
public interface ITask<ENTITY extends AbsEntity> { public interface ITask<ENTITY extends AbsEntity> {
/**
* 暂停任务并让任务处于等待状态
*/
public void stopAndWait();
/** /**
* 设置任务为最高优先级任务在下载队列中有且只有一个最高优先级任务 * 设置任务为最高优先级任务在下载队列中有且只有一个最高优先级任务
*/ */
@ -88,6 +93,7 @@ public interface ITask<ENTITY extends AbsEntity> {
/** /**
* 获取单位转换后的进度 * 获取单位转换后的进度
*
* @return 返回 3mb * @return 返回 3mb
*/ */
public String getConvertCurrentProgress(); public String getConvertCurrentProgress();

@ -37,11 +37,10 @@ public class DownloadTaskQueue
extends AbsTaskQueue<DownloadTask, DownloadTaskEntity, DownloadEntity> { extends AbsTaskQueue<DownloadTask, DownloadTaskEntity, DownloadEntity> {
private static final String TAG = "DownloadTaskQueue"; private static final String TAG = "DownloadTaskQueue";
private static volatile DownloadTaskQueue INSTANCE = null; private static volatile DownloadTaskQueue INSTANCE = null;
private static final Object LOCK = new Object();
public static DownloadTaskQueue getInstance() { public static DownloadTaskQueue getInstance() {
if (INSTANCE == null) { if (INSTANCE == null) {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
INSTANCE = new DownloadTaskQueue(); INSTANCE = new DownloadTaskQueue();
} }
} }
@ -77,7 +76,8 @@ public class DownloadTaskQueue
DownloadTask oldTsk = mExecutePool.pollTask(); DownloadTask oldTsk = mExecutePool.pollTask();
if (oldTsk != null && oldTsk.isRunning()) { if (oldTsk != null && oldTsk.isRunning()) {
if (i == maxSize - 1) { if (i == maxSize - 1) {
oldTsk.stop(); oldTsk.stopAndWait();
mCachePool.putTaskToFirst(oldTsk);
break; break;
} }
tempTasks.add(oldTsk); tempTasks.add(oldTsk);

@ -16,6 +16,7 @@
package com.arialyy.aria.core.queue; package com.arialyy.aria.core.queue;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.ITask; import com.arialyy.aria.core.inf.ITask;
@ -32,7 +33,6 @@ import com.arialyy.aria.core.upload.UploadTaskEntity;
public class TaskFactory { public class TaskFactory {
private static final String TAG = "TaskFactory"; private static final String TAG = "TaskFactory";
private static final Object LOCK = new Object();
private static volatile TaskFactory INSTANCE = null; private static volatile TaskFactory INSTANCE = null;
private TaskFactory() { private TaskFactory() {
@ -41,7 +41,7 @@ public class TaskFactory {
public static TaskFactory getInstance() { public static TaskFactory getInstance() {
if (INSTANCE == null) { if (INSTANCE == null) {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
INSTANCE = new TaskFactory(); INSTANCE = new TaskFactory();
} }
} }

@ -18,6 +18,7 @@ package com.arialyy.aria.core.queue;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.queue.pool.ExecutePool; import com.arialyy.aria.core.queue.pool.ExecutePool;
import com.arialyy.aria.core.scheduler.UploadSchedulers; import com.arialyy.aria.core.scheduler.UploadSchedulers;
import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadEntity;
@ -31,11 +32,10 @@ import com.arialyy.aria.core.upload.UploadTaskEntity;
public class UploadTaskQueue extends AbsTaskQueue<UploadTask, UploadTaskEntity, UploadEntity> { public class UploadTaskQueue extends AbsTaskQueue<UploadTask, UploadTaskEntity, UploadEntity> {
private static final String TAG = "UploadTaskQueue"; private static final String TAG = "UploadTaskQueue";
private static volatile UploadTaskQueue INSTANCE = null; private static volatile UploadTaskQueue INSTANCE = null;
private static final Object LOCK = new Object();
public static UploadTaskQueue getInstance() { public static UploadTaskQueue getInstance() {
if (INSTANCE == null) { if (INSTANCE == null) {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
INSTANCE = new UploadTaskQueue(); INSTANCE = new UploadTaskQueue();
} }
} }

@ -18,10 +18,13 @@ package com.arialyy.aria.core.queue.pool;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.inf.ITask; import com.arialyy.aria.core.inf.ITask;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -31,7 +34,6 @@ import java.util.concurrent.TimeUnit;
*/ */
public class CachePool<TASK extends ITask> implements IPool<TASK> { public class CachePool<TASK extends ITask> implements IPool<TASK> {
private static final String TAG = "CachePool"; private static final String TAG = "CachePool";
private static final Object LOCK = new Object();
private static final int MAX_NUM = Integer.MAX_VALUE; //最大下载任务数 private static final int MAX_NUM = Integer.MAX_VALUE; //最大下载任务数
private static final long TIME_OUT = 1000; private static final long TIME_OUT = 1000;
private Map<String, TASK> mCacheMap; private Map<String, TASK> mCacheMap;
@ -49,8 +51,28 @@ public class CachePool<TASK extends ITask> implements IPool<TASK> {
return mCacheMap; return mCacheMap;
} }
/**
* 将任务放在队首
*/
public boolean putTaskToFirst(TASK task) {
if (mCacheQueue.isEmpty()) {
return putTask(task);
} else {
Set<TASK> temps = new LinkedHashSet<>();
temps.add(task);
for (int i = 0, len = size(); i < len; i++) {
TASK temp = pollTask();
temps.add(temp);
}
for (TASK t : temps) {
putTask(t);
}
return true;
}
}
@Override public boolean putTask(TASK task) { @Override public boolean putTask(TASK task) {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
if (task == null) { if (task == null) {
Log.e(TAG, "下载任务不能为空!!"); Log.e(TAG, "下载任务不能为空!!");
return false; return false;
@ -71,7 +93,7 @@ public class CachePool<TASK extends ITask> implements IPool<TASK> {
} }
@Override public TASK pollTask() { @Override public TASK pollTask() {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
try { try {
TASK task = null; TASK task = null;
task = mCacheQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS); task = mCacheQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
@ -88,7 +110,7 @@ public class CachePool<TASK extends ITask> implements IPool<TASK> {
} }
@Override public TASK getTask(String downloadUrl) { @Override public TASK getTask(String downloadUrl) {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
if (TextUtils.isEmpty(downloadUrl)) { if (TextUtils.isEmpty(downloadUrl)) {
Log.e(TAG, "请传入有效的下载链接"); Log.e(TAG, "请传入有效的下载链接");
return null; return null;
@ -99,7 +121,7 @@ public class CachePool<TASK extends ITask> implements IPool<TASK> {
} }
@Override public boolean removeTask(TASK task) { @Override public boolean removeTask(TASK task) {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
if (task == null) { if (task == null) {
Log.e(TAG, "任务不能为空"); Log.e(TAG, "任务不能为空");
return false; return false;
@ -112,7 +134,7 @@ public class CachePool<TASK extends ITask> implements IPool<TASK> {
} }
@Override public boolean removeTask(String downloadUrl) { @Override public boolean removeTask(String downloadUrl) {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
if (TextUtils.isEmpty(downloadUrl)) { if (TextUtils.isEmpty(downloadUrl)) {
Log.e(TAG, "请传入有效的下载链接"); Log.e(TAG, "请传入有效的下载链接");
return false; return false;

@ -33,7 +33,6 @@ import java.util.concurrent.TimeUnit;
*/ */
public class ExecutePool<TASK extends ITask> implements IPool<TASK> { public class ExecutePool<TASK extends ITask> implements IPool<TASK> {
private static final String TAG = "ExecutePool"; private static final String TAG = "ExecutePool";
private static final Object LOCK = new Object();
private static final long TIME_OUT = 1000; private static final long TIME_OUT = 1000;
private ArrayBlockingQueue<TASK> mExecuteQueue; private ArrayBlockingQueue<TASK> mExecuteQueue;
private Map<String, TASK> mExecuteMap; private Map<String, TASK> mExecuteMap;
@ -57,7 +56,7 @@ public class ExecutePool<TASK extends ITask> implements IPool<TASK> {
} }
@Override public boolean putTask(TASK task) { @Override public boolean putTask(TASK task) {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
if (task == null) { if (task == null) {
Log.e(TAG, "任务不能为空!!"); Log.e(TAG, "任务不能为空!!");
return false; return false;
@ -141,7 +140,7 @@ public class ExecutePool<TASK extends ITask> implements IPool<TASK> {
} }
@Override public TASK pollTask() { @Override public TASK pollTask() {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
try { try {
TASK task = null; TASK task = null;
task = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS); task = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
@ -158,7 +157,7 @@ public class ExecutePool<TASK extends ITask> implements IPool<TASK> {
} }
@Override public TASK getTask(String downloadUrl) { @Override public TASK getTask(String downloadUrl) {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
if (TextUtils.isEmpty(downloadUrl)) { if (TextUtils.isEmpty(downloadUrl)) {
Log.e(TAG, "请传入有效的任务key"); Log.e(TAG, "请传入有效的任务key");
return null; return null;
@ -169,7 +168,7 @@ public class ExecutePool<TASK extends ITask> implements IPool<TASK> {
} }
@Override public boolean removeTask(TASK task) { @Override public boolean removeTask(TASK task) {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
if (task == null) { if (task == null) {
Log.e(TAG, "任务不能为空"); Log.e(TAG, "任务不能为空");
return false; return false;
@ -182,7 +181,7 @@ public class ExecutePool<TASK extends ITask> implements IPool<TASK> {
} }
@Override public boolean removeTask(String downloadUrl) { @Override public boolean removeTask(String downloadUrl) {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
if (TextUtils.isEmpty(downloadUrl)) { if (TextUtils.isEmpty(downloadUrl)) {
Log.e(TAG, "请传入有效的任务key"); Log.e(TAG, "请传入有效的任务key");
return false; return false;

@ -19,11 +19,13 @@ import android.os.CountDownTimer;
import android.os.Message; import android.os.Message;
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.download.DownloadTask;
import com.arialyy.aria.core.inf.AbsEntity; import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.ITask; import com.arialyy.aria.core.inf.ITask;
import com.arialyy.aria.core.queue.ITaskQueue; import com.arialyy.aria.core.queue.ITaskQueue;
import com.arialyy.aria.core.upload.UploadTask;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -65,6 +67,9 @@ public abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskEntity, ENTITY ex
ENTITY entity = task.getEntity(); ENTITY entity = task.getEntity();
switch (msg.what) { switch (msg.what) {
case STOP: case STOP:
if (task.getEntity().getState() == IEntity.STATE_WAIT) {
break;
}
case CANCEL: case CANCEL:
mQueue.removeTask(entity); mQueue.removeTask(entity);
if (mQueue.executePoolSize() < AriaManager.getInstance(AriaManager.APP) if (mQueue.executePoolSize() < AriaManager.getInstance(AriaManager.APP)
@ -147,10 +152,17 @@ public abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskEntity, ENTITY ex
* @param task 下载任务 * @param task 下载任务
*/ */
private void handleFailTask(final TASK task) { private void handleFailTask(final TASK task) {
final long interval = long interval = 2000;
AriaManager.getInstance(AriaManager.APP).getUploadConfig().getReTryInterval(); int num = 10;
final int reTryNum = AriaManager.getInstance(AriaManager.APP).getUploadConfig().getReTryNum(); if (task instanceof DownloadTask) {
interval = AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getReTryInterval();
num = AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getReTryNum();
} else if (task instanceof UploadTask) {
interval = AriaManager.getInstance(AriaManager.APP).getUploadConfig().getReTryInterval();
num = AriaManager.getInstance(AriaManager.APP).getUploadConfig().getReTryNum();
}
final int reTryNum = num;
CountDownTimer timer = new CountDownTimer(interval, 1000) { CountDownTimer timer = new CountDownTimer(interval, 1000) {
@Override public void onTick(long millisUntilFinished) { @Override public void onTick(long millisUntilFinished) {
@ -161,11 +173,6 @@ public abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskEntity, ENTITY ex
if (entity.getFailNum() < reTryNum) { if (entity.getFailNum() < reTryNum) {
TASK task = mQueue.getTask(entity); TASK task = mQueue.getTask(entity);
mQueue.reTryStart(task); mQueue.reTryStart(task);
try {
Thread.sleep(interval);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else { } else {
mQueue.removeTask(entity); mQueue.removeTask(entity);
startNextTask(); startNextTask();

@ -16,6 +16,7 @@
package com.arialyy.aria.core.scheduler; package com.arialyy.aria.core.scheduler;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.queue.DownloadTaskQueue; import com.arialyy.aria.core.queue.DownloadTaskQueue;
import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadEntity;
@ -29,7 +30,6 @@ public class DownloadSchedulers
extends AbsSchedulers<DownloadTaskEntity, DownloadEntity, DownloadTask, DownloadTaskQueue> { extends AbsSchedulers<DownloadTaskEntity, DownloadEntity, DownloadTask, DownloadTaskQueue> {
private static final String TAG = "DownloadSchedulers"; private static final String TAG = "DownloadSchedulers";
private static final Object LOCK = new Object();
private static volatile DownloadSchedulers INSTANCE = null; private static volatile DownloadSchedulers INSTANCE = null;
private DownloadSchedulers() { private DownloadSchedulers() {
@ -38,7 +38,7 @@ public class DownloadSchedulers
public static DownloadSchedulers getInstance() { public static DownloadSchedulers getInstance() {
if (INSTANCE == null) { if (INSTANCE == null) {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
INSTANCE = new DownloadSchedulers(); INSTANCE = new DownloadSchedulers();
} }
} }

@ -15,6 +15,7 @@
*/ */
package com.arialyy.aria.core.scheduler; package com.arialyy.aria.core.scheduler;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.queue.UploadTaskQueue; import com.arialyy.aria.core.queue.UploadTaskQueue;
import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTask; import com.arialyy.aria.core.upload.UploadTask;
@ -27,7 +28,6 @@ import com.arialyy.aria.core.upload.UploadTaskEntity;
public class UploadSchedulers public class UploadSchedulers
extends AbsSchedulers<UploadTaskEntity, UploadEntity, UploadTask, UploadTaskQueue> { extends AbsSchedulers<UploadTaskEntity, UploadEntity, UploadTask, UploadTaskQueue> {
private static final String TAG = "UploadSchedulers"; private static final String TAG = "UploadSchedulers";
private static final Object LOCK = new Object();
private static volatile UploadSchedulers INSTANCE = null; private static volatile UploadSchedulers INSTANCE = null;
private UploadSchedulers() { private UploadSchedulers() {
@ -36,7 +36,7 @@ public class UploadSchedulers
public static UploadSchedulers getInstance() { public static UploadSchedulers getInstance() {
if (INSTANCE == null) { if (INSTANCE == null) {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
INSTANCE = new UploadSchedulers(); INSTANCE = new UploadSchedulers();
} }
} }

@ -22,6 +22,7 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.util.Log; import android.util.Log;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.util.CheckUtil; import com.arialyy.aria.util.CheckUtil;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import java.util.List; import java.util.List;
@ -32,7 +33,6 @@ import java.util.List;
*/ */
public class DbUtil { public class DbUtil {
private static final String TAG = "DbUtil"; private static final String TAG = "DbUtil";
private static final Object LOCK = new Object();
private volatile static DbUtil INSTANCE = null; private volatile static DbUtil INSTANCE = null;
private int ROW_ID = 7; private int ROW_ID = 7;
private SQLiteDatabase mDb; private SQLiteDatabase mDb;
@ -48,7 +48,7 @@ public class DbUtil {
public static DbUtil init(Context context) { public static DbUtil init(Context context) {
if (context instanceof Application) { if (context instanceof Application) {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
if (INSTANCE == null) { if (INSTANCE == null) {
INSTANCE = new DbUtil(context); INSTANCE = new DbUtil(context);
} }

@ -23,6 +23,7 @@ import android.database.sqlite.SQLiteOpenHelper;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.util.CheckUtil; import com.arialyy.aria.util.CheckUtil;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -47,11 +48,10 @@ final class SqlHelper extends SQLiteOpenHelper {
private static final int DEL_DATA = 6; private static final int DEL_DATA = 6;
private static volatile SqlHelper INSTANCE = null; private static volatile SqlHelper INSTANCE = null;
private static final Object LOCK = new Object();
static SqlHelper init(Context context) { static SqlHelper init(Context context) {
if (INSTANCE == null) { if (INSTANCE == null) {
synchronized (LOCK) { synchronized (AriaManager.LOCK) {
INSTANCE = new SqlHelper(context.getApplicationContext()); INSTANCE = new SqlHelper(context.getApplicationContext());
checkTable(INSTANCE.getWritableDatabase()); checkTable(INSTANCE.getWritableDatabase());
} }

@ -159,7 +159,7 @@ compile 'com.arialyy.aria:Aria:3.1.4'
<ca name="" path=""/> <ca name="" path=""/>
<!--是否需要转换速度单位,转换完成后为:1b/s、1kb/s、1mb/s、1gb/s、1tb/s,如果不需要将返回byte长度--> <!--是否需要转换速度单位,转换完成后为:1b/s、1kb/s、1mb/s、1gb/s、1tb/s,如果不需要将返回byte长度-->
<cnvertSpeed value="false"/> <convertSpeed value="false"/>
</download> </download>
@ -226,6 +226,11 @@ Aria.download(this).removeAllTask();
int percent = task.getPercent(); int percent = task.getPercent();
} }
``` ```
* 设置高优先级任务
如果你希望优先下载某一个任务,你可以
``` java
Aria.download(this).load(DOWNLOAD_URL).setDownloadPath(PATH).setHighestPriority();
```
**tips:为了防止内存泄露的情况,事件类需要使用staic进行修饰** **tips:为了防止内存泄露的情况,事件类需要使用staic进行修饰**
@ -272,8 +277,8 @@ Aria.download(this).removeAllTask();
## 开发日志 ## 开发日志
+ v_3.1.5 优化代码结构,增加优先下载任务功能。
+ v_3.1.4 修复快速切换,暂停、恢复功能时,概率性出现的重新下载问题,添加onPre()回调,onPre()用于请求地址之前执行界面UI更新操作。 + v_3.1.4 修复快速切换,暂停、恢复功能时,概率性出现的重新下载问题,添加onPre()回调,onPre()用于请求地址之前执行界面UI更新操作。
+ v_3.1.2 优化代码结构
+ v_3.1.0 添加Aria配置文件,优化代码 + v_3.1.0 添加Aria配置文件,优化代码
+ v_3.0.3 修复暂停后删除任务,闪退问题,添加删除记录的api + v_3.0.3 修复暂停后删除任务,闪退问题,添加删除记录的api
+ v_3.0.2 支持30x重定向链接下载 + v_3.0.2 支持30x重定向链接下载

@ -17,7 +17,7 @@
<reTryNum value="10"/> <reTryNum value="10"/>
<!--设置重试间隔,单位为毫秒,默认2000毫秒--> <!--设置重试间隔,单位为毫秒,默认2000毫秒-->
<reTryInterval value="2000"/> <reTryInterval value="5000"/>
<!--设置url连接超时时间,单位为毫秒,默认5000毫秒--> <!--设置url连接超时时间,单位为毫秒,默认5000毫秒-->
<connectTimeOut value="5000"/> <connectTimeOut value="5000"/>

@ -127,7 +127,7 @@ public class HighestPriorityActivity extends BaseActivity<ActivityHighestPriorit
+ " 2、最高优先级任务会一直存在,直到用户手动暂停或任务完成\n" + " 2、最高优先级任务会一直存在,直到用户手动暂停或任务完成\n"
+ " 3、任务调度器不会暂停最高优先级任务\n" + " 3、任务调度器不会暂停最高优先级任务\n"
+ " 4、用户手动暂停或任务完成后,第二次重新执行该任务,该命令将失效\n" + " 4、用户手动暂停或任务完成后,第二次重新执行该任务,该命令将失效\n"
+ " 5、如果下载队列中已经满了,则会停止队尾的任务\n" + " 5、如果下载队列中已经满了,则会停止队尾的任务,当高优先级任务完成后,该队尾任务将自动执行\n"
+ " 6、把任务设置为最高优先级任务后,将自动执行任务,不需要重新调用start()启动任务"; + " 6、把任务设置为最高优先级任务后,将自动执行任务,不需要重新调用start()启动任务";
showMsgDialog(title, msg); showMsgDialog(title, msg);
break; break;

@ -22,11 +22,14 @@ import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import butterknife.Bind; import butterknife.Bind;
import com.arialyy.aria.core.Aria; import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.frame.util.show.L; import com.arialyy.frame.util.show.L;
import com.arialyy.simple.R; import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity; import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.ActivityMultiDownloadBinding; import com.arialyy.simple.databinding.ActivityMultiDownloadBinding;
import java.util.ArrayList;
import java.util.List;
/** /**
* Created by AriaL on 2017/1/6. * Created by AriaL on 2017/1/6.
@ -35,6 +38,7 @@ import com.arialyy.simple.databinding.ActivityMultiDownloadBinding;
public class MultiDownloadActivity extends BaseActivity<ActivityMultiDownloadBinding> { public class MultiDownloadActivity extends BaseActivity<ActivityMultiDownloadBinding> {
@Bind(R.id.list) RecyclerView mList; @Bind(R.id.list) RecyclerView mList;
private DownloadAdapter mAdapter; private DownloadAdapter mAdapter;
private List<DownloadEntity> mData = new ArrayList<>();
@Override protected int setLayoutId() { @Override protected int setLayoutId() {
return R.layout.activity_multi_download; return R.layout.activity_multi_download;
@ -43,7 +47,11 @@ public class MultiDownloadActivity extends BaseActivity<ActivityMultiDownloadBin
@Override protected void init(Bundle savedInstanceState) { @Override protected void init(Bundle savedInstanceState) {
super.init(savedInstanceState); super.init(savedInstanceState);
setTitle("下载列表"); setTitle("下载列表");
mAdapter = new DownloadAdapter(this, Aria.download(this).getTaskList()); List<DownloadEntity> temps = Aria.download(this).getTaskList();
if (temps != null && !temps.isEmpty()) {
mData.addAll(temps);
}
mAdapter = new DownloadAdapter(this, mData);
mList.setLayoutManager(new LinearLayoutManager(this)); mList.setLayoutManager(new LinearLayoutManager(this));
mList.setAdapter(mAdapter); mList.setAdapter(mAdapter);
} }

Loading…
Cancel
Save