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 3b2f54bf..7c14afa0 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java +++ b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java @@ -36,6 +36,7 @@ import com.arialyy.aria.orm.DbUtil; import com.arialyy.aria.util.CommonUtil; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -55,7 +56,7 @@ import org.xml.sax.SAXException; private static final String TAG = "AriaManager"; private static final String DOWNLOAD = "_download"; 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 UPLOAD_TEMP_DIR = "/Aria/temp/upload/"; @SuppressLint("StaticFieldLeak") private static volatile AriaManager INSTANCE = null; @@ -85,20 +86,6 @@ import org.xml.sax.SAXException; 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()); - } - } - /** * 如果需要在代码中修改下载配置,请使用以下方法 *
@@ -255,7 +242,13 @@ import org.xml.sax.SAXException; } else { try { 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(); } } 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生命周期回调 */ diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/CmdFactory.java b/Aria/src/main/java/com/arialyy/aria/core/command/CmdFactory.java index 7be00923..5be974de 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/CmdFactory.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/CmdFactory.java @@ -16,6 +16,7 @@ package com.arialyy.aria.core.command; +import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.inf.AbsTaskEntity; /** @@ -50,7 +51,6 @@ public class CmdFactory { public static final int TASK_SINGLE = 0x126; - private static final Object LOCK = new Object(); private static volatile CmdFactory INSTANCE = null; private CmdFactory() { @@ -59,7 +59,7 @@ public class CmdFactory { public static CmdFactory getInstance() { if (INSTANCE == null) { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { INSTANCE = new CmdFactory(); } } 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 7a3147b2..74999611 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 @@ -26,7 +26,7 @@ import com.arialyy.aria.core.inf.AbsTaskEntity; * 2、最高优先级任务会一直存在,直到用户手动暂停或任务完成 * 3、任务调度器不会暂停最高优先级任务 * 4、用户手动暂停或任务完成后,第二次重新执行该任务,该命令将失效 - * 5、如果下载队列中已经满了,则会停止队尾的任务 + * 5、如果下载队列中已经满了,则会停止队尾的任务,当高优先级任务完成后,该队尾任务将自动执行 * 6、把任务设置为最高优先级任务后,将自动执行任务,不需要重新调用start()启动任务 */ final class HighestPriorityCmdextends AbsCmd { diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java index 44bc443c..05e6c2d9 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java @@ -50,7 +50,7 @@ public class DownloadTarget extends AbsTarget { private IDownloadListener mListener; private Handler mOutHandler; private IDownloadUtil mUtil; + private boolean isWait = false; private DownloadTask(DownloadTaskEntity taskEntity, Handler outHandler) { mEntity = taskEntity.downloadEntity; @@ -78,15 +80,23 @@ public class DownloadTask extends AbsTask { return mEntity; } + /** + * 暂停任务,并让任务处于等待状态 + */ + @Override public void stopAndWait() { + super.stopAndWait(); + stop(true); + } /** * 开始下载 */ @Override public void start() { + isWait = false; if (mUtil.isDownloading()) { Log.d(TAG, "任务正在下载"); } else { - if (mListener == null) { + if (mListener == null || isWait) { mListener = new DListener(mContext, this, mOutHandler); } mUtil.startDownload(); @@ -97,10 +107,15 @@ public class DownloadTask extends AbsTask { * 停止下载 */ @Override public void stop() { + stop(false); + } + + private void stop(boolean isWait) { + this.isWait = isWait; if (mUtil.isDownloading()) { mUtil.stopDownload(); } else { - mEntity.setState(DownloadEntity.STATE_STOP); + mEntity.setState(isWait ? IEntity.STATE_WAIT : IEntity.STATE_STOP); mEntity.save(); if (mOutHandler != null) { mOutHandler.obtainMessage(DownloadSchedulers.STOP, this).sendToTarget(); @@ -201,7 +216,7 @@ public class DownloadTask extends AbsTask { @Override public void onPre() { super.onPre(); - downloadEntity.setState(DownloadEntity.STATE_PRE); + downloadEntity.setState(IEntity.STATE_PRE); sendInState2Target(ISchedulers.PRE); sendIntent(Aria.ACTION_PRE, -1); } @@ -209,21 +224,21 @@ public class DownloadTask extends AbsTask { @Override public void onPostPre(long fileSize) { super.onPostPre(fileSize); downloadEntity.setFileSize(fileSize); - downloadEntity.setState(DownloadEntity.STATE_POST_PRE); + downloadEntity.setState(IEntity.STATE_POST_PRE); sendInState2Target(ISchedulers.POST_PRE); sendIntent(Aria.ACTION_POST_PRE, -1); } @Override public void onResume(long resumeLocation) { super.onResume(resumeLocation); - downloadEntity.setState(DownloadEntity.STATE_RUNNING); + downloadEntity.setState(IEntity.STATE_RUNNING); sendInState2Target(ISchedulers.RESUME); sendIntent(Aria.ACTION_RESUME, resumeLocation); } @Override public void onStart(long startLocation) { super.onStart(startLocation); - downloadEntity.setState(DownloadEntity.STATE_RUNNING); + downloadEntity.setState(IEntity.STATE_RUNNING); sendInState2Target(ISchedulers.START); sendIntent(Aria.ACTION_START, startLocation); } @@ -249,7 +264,7 @@ public class DownloadTask extends AbsTask { @Override public void onStop(long stopLocation) { super.onStop(stopLocation); - downloadEntity.setState(DownloadEntity.STATE_STOP); + downloadEntity.setState(task.isWait ? IEntity.STATE_WAIT : IEntity.STATE_STOP); handleSpeed(0); sendInState2Target(ISchedulers.STOP); sendIntent(Aria.ACTION_STOP, stopLocation); @@ -257,7 +272,7 @@ public class DownloadTask extends AbsTask { @Override public void onCancel() { super.onCancel(); - downloadEntity.setState(DownloadEntity.STATE_CANCEL); + downloadEntity.setState(IEntity.STATE_CANCEL); handleSpeed(0); sendInState2Target(ISchedulers.CANCEL); sendIntent(Aria.ACTION_CANCEL, -1); @@ -266,7 +281,7 @@ public class DownloadTask extends AbsTask { @Override public void onComplete() { super.onComplete(); - downloadEntity.setState(DownloadEntity.STATE_COMPLETE); + downloadEntity.setState(IEntity.STATE_COMPLETE); downloadEntity.setDownloadComplete(true); handleSpeed(0); sendInState2Target(ISchedulers.COMPLETE); @@ -276,7 +291,7 @@ public class DownloadTask extends AbsTask { @Override public void onFail() { super.onFail(); downloadEntity.setFailNum(downloadEntity.getFailNum() + 1); - downloadEntity.setState(DownloadEntity.STATE_FAIL); + downloadEntity.setState(IEntity.STATE_FAIL); handleSpeed(0); sendInState2Target(ISchedulers.FAIL); sendIntent(Aria.ACTION_FAIL, -1); 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 7580849e..0dfda502 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 @@ -66,7 +66,7 @@ class DownloadUtil implements IDownloadUtil, Runnable { mDownloadTaskEntity = entity; mListener = downloadListener; // 线程下载数改变后,新的下载才会生效 - mFixedThreadPool = Executors.newFixedThreadPool(Integer.MAX_VALUE); + //mFixedThreadPool = Executors.newFixedThreadPool(Integer.MAX_VALUE); CONSTANCE = new DownloadStateConstance(); init(); } @@ -75,8 +75,10 @@ class DownloadUtil implements IDownloadUtil, Runnable { mConnectTimeOut = AriaManager.getInstance(mContext).getDownloadConfig().getConnectTimeOut(); mDownloadFile = new File(mDownloadTaskEntity.downloadEntity.getDownloadPath()); //读取已完成的线程数 - mConfigFile = new File( - mContext.getFilesDir().getPath() + AriaManager.DOWNLOAD_TEMP_DIR + mDownloadFile.getName() + ".properties"); + mConfigFile = new File(mContext.getFilesDir().getPath() + + AriaManager.DOWNLOAD_TEMP_DIR + + mDownloadFile.getName() + + ".properties"); try { if (!mConfigFile.exists()) { //记录文件被删除,则重新下载 handleNewTask(); @@ -111,7 +113,9 @@ class DownloadUtil implements IDownloadUtil, Runnable { @Override public void cancelDownload() { CONSTANCE.isCancel = true; CONSTANCE.isDownloading = false; - mFixedThreadPool.shutdown(); + if (mFixedThreadPool != null) { + mFixedThreadPool.shutdown(); + } for (int i = 0; i < THREAD_NUM; i++) { SingleThreadTask task = (SingleThreadTask) mTask.get(i); if (task != null) { @@ -126,7 +130,9 @@ class DownloadUtil implements IDownloadUtil, Runnable { @Override public void stopDownload() { CONSTANCE.isStop = true; CONSTANCE.isDownloading = false; - mFixedThreadPool.shutdown(); + if (mFixedThreadPool != null) { + mFixedThreadPool.shutdown(); + } for (int i = 0; i < THREAD_NUM; i++) { SingleThreadTask task = (SingleThreadTask) mTask.get(i); if (task != null) { @@ -304,7 +310,7 @@ class DownloadUtil implements IDownloadUtil, Runnable { if (!isNewTask && record != null && Long.parseLong(record + "") > 0) { Long r = Long.parseLong(record + ""); CONSTANCE.CURRENT_LOCATION += r - startL; - Log.d(TAG, "++++++++++ 线程_" + i + "_恢复下载 ++++++++++"); + Log.d(TAG, "任务【" + mDownloadEntity.getFileName() + "】线程__" + i + "__恢复下载"); mListener.onChildResume(r); startL = r; recordL[rl] = i; @@ -374,7 +380,7 @@ class DownloadUtil implements IDownloadUtil, Runnable { num++; } } - if (num == 0){ + if (num == 0) { handleNewTask(); return pro; } @@ -386,9 +392,10 @@ class DownloadUtil implements IDownloadUtil, Runnable { continue; } handleNewTask(); - break; + return pro; } } + isNewTask = false; } return pro; } @@ -452,10 +459,11 @@ class DownloadUtil implements IDownloadUtil, Runnable { } else { mListener.onStart(CONSTANCE.CURRENT_LOCATION); } + mFixedThreadPool = Executors.newFixedThreadPool(recordL.length); for (int l : recordL) { if (l == -1) continue; Runnable task = mTask.get(l); - if (task != null && !mFixedThreadPool.isShutdown()) { + if (task != null) { mFixedThreadPool.execute(task); } } 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 267b7926..973a956f 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 @@ -15,6 +15,7 @@ */ package com.arialyy.aria.core.download; +import android.text.TextUtils; import android.util.Log; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.util.BufferedRandomAccessFile; @@ -36,7 +37,6 @@ final class SingleThreadTask implements Runnable { private DownloadUtil.ConfigEntity mConfigEntity; private String mConfigFPath; private long mChildCurrentLocation = 0; - private static final Object LOCK = new Object(); private int mBufSize; private IDownloadListener mListener; private DownloadStateConstance CONSTANCE; @@ -62,9 +62,11 @@ final class SingleThreadTask implements Runnable { URL url = new URL(mConfigEntity.DOWNLOAD_URL); conn = ConnectionHelp.handleConnection(url); if (mConfigEntity.isSupportBreakpoint) { - Log.d(TAG, "线程_" + Log.d(TAG, "任务【" + + mConfigEntity.TEMP_FILE.getName() + + "】线程__" + mConfigEntity.THREAD_ID - + "_正在下载【开始位置 : " + + "__开始下载【开始位置 : " + mConfigEntity.START_LOCATION + ",结束位置:" + mConfigEntity.END_LOCATION @@ -112,9 +114,12 @@ final class SingleThreadTask implements Runnable { } //支持断点的处理 if (mConfigEntity.isSupportBreakpoint) { - Log.i(TAG, - "任务【" + mConfigEntity.TEMP_FILE.getName() + "】线程【" + mConfigEntity.THREAD_ID + "】下载完毕"); - writeConfig(1); + Log.i(TAG, "任务【" + + mConfigEntity.TEMP_FILE.getName() + + "】线程__" + + mConfigEntity.THREAD_ID + + "__下载完毕"); + writeConfig(true, 1); mListener.onChildComplete(mConfigEntity.END_LOCATION); CONSTANCE.COMPLETE_THREAD_NUM++; if (CONSTANCE.isComplete()) { @@ -143,22 +148,24 @@ final class SingleThreadTask implements Runnable { * 停止下载 */ protected void stop() { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { try { if (mConfigEntity.isSupportBreakpoint) { CONSTANCE.STOP_NUM++; - Log.d(TAG, "thread_" + Log.d(TAG, "任务【" + + mConfigEntity.TEMP_FILE.getName() + + "】thread__" + mConfigEntity.THREAD_ID - + "_stop, stop location ==> " + + "__停止, stop location ==> " + mChildCurrentLocation); - writeConfig(mChildCurrentLocation); + writeConfig(false, mChildCurrentLocation); if (CONSTANCE.isStop()) { - Log.d(TAG, "++++++++++++++++ onStop +++++++++++++++++"); + Log.d(TAG, "任务【" + mConfigEntity.TEMP_FILE.getName() + "】已停止"); CONSTANCE.isDownloading = false; mListener.onStop(CONSTANCE.CURRENT_LOCATION); } } else { - Log.d(TAG, "++++++++++++++++ onStop +++++++++++++++++"); + Log.d(TAG, "任务【" + mConfigEntity.TEMP_FILE.getName() + "】已停止"); CONSTANCE.isDownloading = false; mListener.onStop(CONSTANCE.CURRENT_LOCATION); } @@ -172,7 +179,7 @@ final class SingleThreadTask implements Runnable { * 下载中 */ private void progress(long len) { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { mChildCurrentLocation += len; CONSTANCE.CURRENT_LOCATION += len; mListener.onProgress(CONSTANCE.CURRENT_LOCATION); @@ -183,10 +190,14 @@ final class SingleThreadTask implements Runnable { * 取消下载 */ protected void cancel() { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { if (mConfigEntity.isSupportBreakpoint) { 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()) { File configFile = new File(mConfigFPath); if (configFile.exists()) { @@ -195,12 +206,12 @@ final class SingleThreadTask implements Runnable { if (mConfigEntity.TEMP_FILE.exists()) { mConfigEntity.TEMP_FILE.delete(); } - Log.d(TAG, "++++++++++++++++ onCancel +++++++++++++++++"); + Log.d(TAG, "任务【" + mConfigEntity.TEMP_FILE.getName() + "】已取消"); CONSTANCE.isDownloading = false; mListener.onCancel(); } } else { - Log.d(TAG, "++++++++++++++++ onCancel +++++++++++++++++"); + Log.d(TAG, "任务【" + mConfigEntity.TEMP_FILE.getName() + "】已取消"); CONSTANCE.isDownloading = false; mListener.onCancel(); } @@ -211,7 +222,7 @@ final class SingleThreadTask implements Runnable { * 下载失败 */ private void failDownload(long currentLocation, String msg, Exception ex) { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { try { CONSTANCE.FAIL_NUM++; CONSTANCE.isDownloading = false; @@ -220,13 +231,13 @@ final class SingleThreadTask implements Runnable { Log.e(TAG, msg + "\n" + CommonUtil.getPrintException(ex)); } if (mConfigEntity.isSupportBreakpoint) { - writeConfig(currentLocation); + writeConfig(false, currentLocation); if (CONSTANCE.isFail()) { - Log.d(TAG, "++++++++++++++++ onFail +++++++++++++++++"); + Log.e(TAG, "任务【" + mConfigEntity.TEMP_FILE.getName() + "】下载失败"); mListener.onFail(); } } else { - Log.d(TAG, "++++++++++++++++ onFail +++++++++++++++++"); + Log.e(TAG, "任务【" + mConfigEntity.TEMP_FILE.getName() + "】下载失败"); mListener.onFail(); } } catch (IOException e) { @@ -238,13 +249,22 @@ final class SingleThreadTask implements Runnable { /** * 将记录写入到配置文件 */ - private void writeConfig(long record) throws IOException { - if (record > 0) { - String key = mConfigEntity.TEMP_FILE.getName() + "_record_" + mConfigEntity.THREAD_ID; - File configFile = new File(mConfigFPath); - Properties pro = CommonUtil.loadConfig(configFile); - pro.setProperty(key, String.valueOf(record)); - CommonUtil.saveConfig(configFile, pro); + private void writeConfig(boolean isComplete, long record) throws IOException { + synchronized (AriaManager.LOCK) { + 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); + Properties pro = CommonUtil.loadConfig(configFile); + pro.setProperty(key, value); + CommonUtil.saveConfig(configFile, pro); + } } } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java index 779a178c..7edcb91e 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java @@ -53,7 +53,7 @@ public abstract class AbsTarget 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 8d1aeca8..c8b4efa2 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 @@ -21,6 +21,11 @@ package com.arialyy.aria.core.inf; public interface ITask { + /** + * 暂停任务,并让任务处于等待状态 + */ + public void stopAndWait(); + /** * 设置任务为最高优先级任务,在下载队列中,有且只有一个最高优先级任务 */ @@ -88,6 +93,7 @@ public interface ITask { /** * 获取单位转换后的进度 + * * @return 返回 3mb */ public String getConvertCurrentProgress(); diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java index 0a8aa594..1dfe99de 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java @@ -37,11 +37,10 @@ public class DownloadTaskQueue extends AbsTaskQueue { private static final String TAG = "DownloadTaskQueue"; private static volatile DownloadTaskQueue INSTANCE = null; - private static final Object LOCK = new Object(); public static DownloadTaskQueue getInstance() { if (INSTANCE == null) { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { INSTANCE = new DownloadTaskQueue(); } } @@ -77,7 +76,8 @@ public class DownloadTaskQueue DownloadTask oldTsk = mExecutePool.pollTask(); if (oldTsk != null && oldTsk.isRunning()) { if (i == maxSize - 1) { - oldTsk.stop(); + oldTsk.stopAndWait(); + mCachePool.putTaskToFirst(oldTsk); break; } tempTasks.add(oldTsk); diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/TaskFactory.java b/Aria/src/main/java/com/arialyy/aria/core/queue/TaskFactory.java index acd44dd5..ed67ec95 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/TaskFactory.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/TaskFactory.java @@ -16,6 +16,7 @@ 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.DownloadTaskEntity; import com.arialyy.aria.core.inf.ITask; @@ -32,7 +33,6 @@ import com.arialyy.aria.core.upload.UploadTaskEntity; public class TaskFactory { private static final String TAG = "TaskFactory"; - private static final Object LOCK = new Object(); private static volatile TaskFactory INSTANCE = null; private TaskFactory() { @@ -41,7 +41,7 @@ public class TaskFactory { public static TaskFactory getInstance() { if (INSTANCE == null) { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { INSTANCE = new TaskFactory(); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java index 011f0d48..2b56ac84 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java @@ -18,6 +18,7 @@ package com.arialyy.aria.core.queue; import android.text.TextUtils; import android.util.Log; +import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.queue.pool.ExecutePool; import com.arialyy.aria.core.scheduler.UploadSchedulers; import com.arialyy.aria.core.upload.UploadEntity; @@ -31,11 +32,10 @@ import com.arialyy.aria.core.upload.UploadTaskEntity; public class UploadTaskQueue extends AbsTaskQueue { private static final String TAG = "UploadTaskQueue"; private static volatile UploadTaskQueue INSTANCE = null; - private static final Object LOCK = new Object(); public static UploadTaskQueue getInstance() { if (INSTANCE == null) { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { INSTANCE = new UploadTaskQueue(); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/CachePool.java b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/CachePool.java index fb46b434..586839a9 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/CachePool.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/CachePool.java @@ -18,10 +18,13 @@ package com.arialyy.aria.core.queue.pool; import android.text.TextUtils; import android.util.Log; +import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.inf.ITask; import com.arialyy.aria.util.CommonUtil; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.Map; +import java.util.Set; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -31,7 +34,6 @@ import java.util.concurrent.TimeUnit; */ public class CachePool implements IPool { 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 long TIME_OUT = 1000; private Map mCacheMap; @@ -49,8 +51,28 @@ public class CachePool implements IPool { return mCacheMap; } + /** + * 将任务放在队首 + */ + public boolean putTaskToFirst(TASK task) { + if (mCacheQueue.isEmpty()) { + return putTask(task); + } else { + Set 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) { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { if (task == null) { Log.e(TAG, "下载任务不能为空!!"); return false; @@ -71,7 +93,7 @@ public class CachePool implements IPool { } @Override public TASK pollTask() { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { try { TASK task = null; task = mCacheQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS); @@ -88,7 +110,7 @@ public class CachePool implements IPool { } @Override public TASK getTask(String downloadUrl) { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { if (TextUtils.isEmpty(downloadUrl)) { Log.e(TAG, "请传入有效的下载链接"); return null; @@ -99,7 +121,7 @@ public class CachePool implements IPool { } @Override public boolean removeTask(TASK task) { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { if (task == null) { Log.e(TAG, "任务不能为空"); return false; @@ -112,7 +134,7 @@ public class CachePool implements IPool { } @Override public boolean removeTask(String downloadUrl) { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { if (TextUtils.isEmpty(downloadUrl)) { Log.e(TAG, "请传入有效的下载链接"); return false; 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 0ae398c1..4f9691af 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 @@ -33,7 +33,6 @@ import java.util.concurrent.TimeUnit; */ public class ExecutePool implements IPool { private static final String TAG = "ExecutePool"; - private static final Object LOCK = new Object(); private static final long TIME_OUT = 1000; private ArrayBlockingQueue mExecuteQueue; private Map mExecuteMap; @@ -57,7 +56,7 @@ public class ExecutePool implements IPool { } @Override public boolean putTask(TASK task) { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { if (task == null) { Log.e(TAG, "任务不能为空!!"); return false; @@ -141,7 +140,7 @@ public class ExecutePool implements IPool { } @Override public TASK pollTask() { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { try { TASK task = null; task = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS); @@ -158,7 +157,7 @@ public class ExecutePool implements IPool { } @Override public TASK getTask(String downloadUrl) { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { if (TextUtils.isEmpty(downloadUrl)) { Log.e(TAG, "请传入有效的任务key"); return null; @@ -169,7 +168,7 @@ public class ExecutePool implements IPool { } @Override public boolean removeTask(TASK task) { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { if (task == null) { Log.e(TAG, "任务不能为空"); return false; @@ -182,7 +181,7 @@ public class ExecutePool implements IPool { } @Override public boolean removeTask(String downloadUrl) { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { if (TextUtils.isEmpty(downloadUrl)) { Log.e(TAG, "请传入有效的任务key"); return false; 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 f8f26021..4fee513f 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 @@ -19,11 +19,13 @@ import android.os.CountDownTimer; import android.os.Message; import android.util.Log; import com.arialyy.aria.core.AriaManager; +import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.core.inf.AbsEntity; import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.ITask; import com.arialyy.aria.core.queue.ITaskQueue; +import com.arialyy.aria.core.upload.UploadTask; import java.util.Iterator; import java.util.Map; import java.util.Set; @@ -65,6 +67,9 @@ public abstract class AbsSchedulers { private static final String TAG = "DownloadSchedulers"; - private static final Object LOCK = new Object(); private static volatile DownloadSchedulers INSTANCE = null; private DownloadSchedulers() { @@ -38,7 +38,7 @@ public class DownloadSchedulers public static DownloadSchedulers getInstance() { if (INSTANCE == null) { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { INSTANCE = new DownloadSchedulers(); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/UploadSchedulers.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/UploadSchedulers.java index 5401bc1a..37a6e3d0 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/scheduler/UploadSchedulers.java +++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/UploadSchedulers.java @@ -15,6 +15,7 @@ */ package com.arialyy.aria.core.scheduler; +import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.queue.UploadTaskQueue; import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadTask; @@ -27,7 +28,6 @@ import com.arialyy.aria.core.upload.UploadTaskEntity; public class UploadSchedulers extends AbsSchedulers { private static final String TAG = "UploadSchedulers"; - private static final Object LOCK = new Object(); private static volatile UploadSchedulers INSTANCE = null; private UploadSchedulers() { @@ -36,7 +36,7 @@ public class UploadSchedulers public static UploadSchedulers getInstance() { if (INSTANCE == null) { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { INSTANCE = new UploadSchedulers(); } } diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DbUtil.java b/Aria/src/main/java/com/arialyy/aria/orm/DbUtil.java index b24cbd15..e02fd7d4 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DbUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DbUtil.java @@ -22,6 +22,7 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.support.annotation.NonNull; import android.util.Log; +import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.util.CheckUtil; import com.arialyy.aria.util.CommonUtil; import java.util.List; @@ -32,7 +33,6 @@ import java.util.List; */ public class DbUtil { private static final String TAG = "DbUtil"; - private static final Object LOCK = new Object(); private volatile static DbUtil INSTANCE = null; private int ROW_ID = 7; private SQLiteDatabase mDb; @@ -48,7 +48,7 @@ public class DbUtil { public static DbUtil init(Context context) { if (context instanceof Application) { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { if (INSTANCE == null) { INSTANCE = new DbUtil(context); } diff --git a/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java b/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java index f3f82bde..784900b1 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java @@ -23,6 +23,7 @@ import android.database.sqlite.SQLiteOpenHelper; import android.support.annotation.NonNull; import android.text.TextUtils; import android.util.Log; +import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.util.CheckUtil; import com.arialyy.aria.util.CommonUtil; import java.lang.reflect.Field; @@ -47,11 +48,10 @@ final class SqlHelper extends SQLiteOpenHelper { private static final int DEL_DATA = 6; private static volatile SqlHelper INSTANCE = null; - private static final Object LOCK = new Object(); static SqlHelper init(Context context) { if (INSTANCE == null) { - synchronized (LOCK) { + synchronized (AriaManager.LOCK) { INSTANCE = new SqlHelper(context.getApplicationContext()); checkTable(INSTANCE.getWritableDatabase()); } diff --git a/README.md b/README.md index a9e2a00f..25396481 100644 --- a/README.md +++ b/README.md @@ -159,7 +159,7 @@ compile 'com.arialyy.aria:Aria:3.1.4' - + @@ -226,6 +226,11 @@ Aria.download(this).removeAllTask(); int percent = task.getPercent(); } ``` +* 设置高优先级任务 +如果你希望优先下载某一个任务,你可以 +``` java +Aria.download(this).load(DOWNLOAD_URL).setDownloadPath(PATH).setHighestPriority(); +``` **tips:为了防止内存泄露的情况,事件类需要使用staic进行修饰** @@ -272,8 +277,8 @@ Aria.download(this).removeAllTask(); ## 开发日志 + + v_3.1.5 优化代码结构,增加优先下载任务功能。 + v_3.1.4 修复快速切换,暂停、恢复功能时,概率性出现的重新下载问题,添加onPre()回调,onPre()用于请求地址之前执行界面UI更新操作。 - + v_3.1.2 优化代码结构 + v_3.1.0 添加Aria配置文件,优化代码 + v_3.0.3 修复暂停后删除任务,闪退问题,添加删除记录的api + v_3.0.2 支持30x重定向链接下载 diff --git a/app/src/main/assets/aria_config.xml b/app/src/main/assets/aria_config.xml index 0c860dd8..01c497ee 100644 --- a/app/src/main/assets/aria_config.xml +++ b/app/src/main/assets/aria_config.xml @@ -17,7 +17,7 @@ - + diff --git a/app/src/main/java/com/arialyy/simple/download/HighestPriorityActivity.java b/app/src/main/java/com/arialyy/simple/download/HighestPriorityActivity.java index 38b365e5..aee06f79 100644 --- a/app/src/main/java/com/arialyy/simple/download/HighestPriorityActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/HighestPriorityActivity.java @@ -79,7 +79,7 @@ public class HighestPriorityActivity extends BaseActivity { @Bind(R.id.list) RecyclerView mList; private DownloadAdapter mAdapter; + private List mData = new ArrayList<>(); @Override protected int setLayoutId() { return R.layout.activity_multi_download; @@ -43,7 +47,11 @@ public class MultiDownloadActivity extends BaseActivity temps = Aria.download(this).getTaskList(); + if (temps != null && !temps.isEmpty()) { + mData.addAll(temps); + } + mAdapter = new DownloadAdapter(this, mData); mList.setLayoutManager(new LinearLayoutManager(this)); mList.setAdapter(mAdapter); }