diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmdFactory.java b/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmdFactory.java index 9f447b49..8ed0d498 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmdFactory.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/AbsCmdFactory.java @@ -19,6 +19,7 @@ import com.arialyy.aria.core.inf.AbsTaskEntity; /** * Created by AriaL on 2017/6/29. + * 抽象命令工厂 */ public abstract class AbsCmdFactory { diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java index bf3b5fb5..375b2ffd 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java @@ -16,10 +16,9 @@ package com.arialyy.aria.core.command.normal; -import com.arialyy.aria.core.download.DownloadEntity; +import com.arialyy.aria.core.download.DownloadGroupEntity; import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.inf.AbsTaskEntity; -import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadTaskEntity; import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.util.CommonUtil; diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DListener.java b/Aria/src/main/java/com/arialyy/aria/core/download/DListener.java new file mode 100644 index 00000000..d415826e --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DListener.java @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.arialyy.aria.core.download; + +import android.os.Handler; +import com.arialyy.aria.core.AriaManager; +import com.arialyy.aria.core.download.downloader.DownloadListener; +import com.arialyy.aria.core.inf.AbsEntity; +import com.arialyy.aria.core.inf.AbsTask; +import com.arialyy.aria.core.inf.IEntity; +import com.arialyy.aria.core.scheduler.ISchedulers; +import com.arialyy.aria.util.CommonUtil; +import java.lang.ref.WeakReference; + +/** + * 下载监听类 + */ +final class DListener> + extends DownloadListener { + private WeakReference outHandler; + private long lastLen = 0; //上一次发送长度 + private boolean isFirst = true; + private ENTITY entity; + private TASK task; + private boolean isConvertSpeed = false; + boolean isWait = false; + + DListener(TASK task, Handler outHandler) { + this.outHandler = new WeakReference<>(outHandler); + this.task = new WeakReference<>(task).get(); + this.entity = this.task.getEntity(); + final AriaManager manager = AriaManager.getInstance(AriaManager.APP); + isConvertSpeed = manager.getDownloadConfig().isConvertSpeed(); + } + + @Override public void onPre() { + saveData(IEntity.STATE_PRE, -1); + sendInState2Target(ISchedulers.PRE); + } + + @Override public void onPostPre(long fileSize) { + entity.setFileSize(fileSize); + entity.setConvertFileSize(CommonUtil.formatFileSize(fileSize)); + saveData(IEntity.STATE_POST_PRE, -1); + sendInState2Target(ISchedulers.POST_PRE); + } + + @Override public void onStart(long startLocation) { + saveData(IEntity.STATE_RUNNING, startLocation); + sendInState2Target(ISchedulers.START); + } + + @Override public void onResume(long resumeLocation) { + saveData(IEntity.STATE_RUNNING, resumeLocation); + sendInState2Target(ISchedulers.RESUME); + } + + @Override public void onProgress(long currentLocation) { + entity.setCurrentProgress(currentLocation); + long speed = currentLocation - lastLen; + if (isFirst) { + speed = 0; + isFirst = false; + } + handleSpeed(speed); + sendInState2Target(ISchedulers.RUNNING); + lastLen = currentLocation; + } + + @Override public void onStop(long stopLocation) { + //saveData(IEntity.STATE_STOP, stopLocation); + saveData(isWait ? IEntity.STATE_WAIT : IEntity.STATE_STOP, stopLocation); + handleSpeed(0); + sendInState2Target(ISchedulers.STOP); + } + + @Override public void onCancel() { + saveData(IEntity.STATE_CANCEL, -1); + handleSpeed(0); + sendInState2Target(ISchedulers.CANCEL); + } + + @Override public void onComplete() { + saveData(IEntity.STATE_COMPLETE, entity.getFileSize()); + handleSpeed(0); + sendInState2Target(ISchedulers.COMPLETE); + } + + @Override public void onFail() { + entity.setFailNum(entity.getFailNum() + 1); + saveData(IEntity.STATE_FAIL, -1); + handleSpeed(0); + sendInState2Target(ISchedulers.FAIL); + } + + private void handleSpeed(long speed) { + if (isConvertSpeed) { + entity.setConvertSpeed(CommonUtil.formatFileSize(speed) + "/s"); + } else { + entity.setSpeed(speed); + } + } + + /** + * 将任务状态发送给下载器 + * + * @param state {@link ISchedulers#START} + */ + private void sendInState2Target(int state) { + if (outHandler.get() != null) { + outHandler.get().obtainMessage(state, task).sendToTarget(); + } + } + + private void saveData(int state, long location) { + if (state == IEntity.STATE_CANCEL) { + entity.deleteData(); + } else { + entity.setState(state); + if (location != -1) { + entity.setCurrentProgress(location); + } + entity.update(); + } + } +} \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupListener.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupListener.java deleted file mode 100644 index 9a60b807..00000000 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupListener.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.arialyy.aria.core.download; - -/** - * Created by AriaL on 2017/6/30. - */ - -public class DownloadGroupListener { - -} diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java index 591bdf79..1a375bba 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java @@ -15,19 +15,13 @@ */ package com.arialyy.aria.core.download; -import android.content.Context; import android.os.Handler; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.download.downloader.DownloadGroupUtil; -import com.arialyy.aria.core.download.downloader.DownloadListener; import com.arialyy.aria.core.download.downloader.IDownloadUtil; import com.arialyy.aria.core.inf.AbsGroupTask; -import com.arialyy.aria.core.inf.IEntity; -import com.arialyy.aria.core.scheduler.DownloadSchedulers; import com.arialyy.aria.core.scheduler.ISchedulers; import com.arialyy.aria.util.CheckUtil; -import com.arialyy.aria.util.CommonUtil; -import java.lang.ref.WeakReference; /** * Created by AriaL on 2017/6/27. @@ -35,7 +29,7 @@ import java.lang.ref.WeakReference; */ public class DownloadGroupTask extends AbsGroupTask { private final String TAG = "DownloadGroupTask"; - private DListener mListener; + private DListener mListener; private IDownloadUtil mUtil; private DownloadGroupTask(DownloadGroupTaskEntity taskEntity, Handler outHandler) { @@ -43,7 +37,7 @@ public class DownloadGroupTask extends AbsGroupTask(this, mOutHandler); mUtil = new DownloadGroupUtil(mListener, mTaskEntity); } @@ -73,121 +67,6 @@ public class DownloadGroupTask extends AbsGroupTask outHandler; - WeakReference wTask; - Context context; - long lastLen = 0; //上一次发送长度 - boolean isFirst = true; - DownloadGroupEntity entity; - DownloadGroupTask task; - boolean isConvertSpeed = false; - - DListener(Context context, DownloadGroupTask task, Handler outHandler) { - this.context = context; - this.outHandler = new WeakReference<>(outHandler); - this.wTask = new WeakReference<>(task); - this.task = wTask.get(); - this.entity = this.task.getEntity(); - final AriaManager manager = AriaManager.getInstance(context); - isConvertSpeed = manager.getDownloadConfig().isConvertSpeed(); - } - - @Override public void onPre() { - saveData(IEntity.STATE_PRE, -1); - sendInState2Target(ISchedulers.PRE); - } - - @Override public void onPostPre(long fileSize) { - entity.setFileSize(fileSize); - entity.setConvertFileSize(CommonUtil.formatFileSize(fileSize)); - saveData(IEntity.STATE_POST_PRE, -1); - sendInState2Target(ISchedulers.POST_PRE); - } - - @Override public void onStart(long startLocation) { - saveData(IEntity.STATE_RUNNING, startLocation); - sendInState2Target(ISchedulers.START); - } - - @Override public void onResume(long resumeLocation) { - saveData(IEntity.STATE_RUNNING, resumeLocation); - sendInState2Target(ISchedulers.RESUME); - } - - @Override public void onProgress(long currentLocation) { - entity.setCurrentProgress(currentLocation); - long speed = currentLocation - lastLen; - if (isFirst) { - speed = 0; - isFirst = false; - } - handleSpeed(speed); - sendInState2Target(ISchedulers.RUNNING); - lastLen = currentLocation; - } - - @Override public void onStop(long stopLocation) { - saveData(IEntity.STATE_STOP, stopLocation); - handleSpeed(0); - sendInState2Target(ISchedulers.STOP); - } - - @Override public void onCancel() { - saveData(IEntity.STATE_CANCEL, -1); - handleSpeed(0); - sendInState2Target(ISchedulers.CANCEL); - } - - @Override public void onComplete() { - saveData(IEntity.STATE_COMPLETE, entity.getFileSize()); - handleSpeed(0); - sendInState2Target(ISchedulers.COMPLETE); - } - - @Override public void onFail() { - entity.setFailNum(entity.getFailNum() + 1); - saveData(IEntity.STATE_FAIL, -1); - handleSpeed(0); - sendInState2Target(ISchedulers.FAIL); - } - - private void handleSpeed(long speed) { - if (isConvertSpeed) { - entity.setConvertSpeed(CommonUtil.formatFileSize(speed) + "/s"); - } else { - entity.setSpeed(speed); - } - } - - /** - * 将任务状态发送给下载器 - * - * @param state {@link DownloadSchedulers#START} - */ - private void sendInState2Target(int state) { - if (outHandler.get() != null) { - outHandler.get().obtainMessage(state, task).sendToTarget(); - } - } - - private void saveData(int state, long location) { - if (state == IEntity.STATE_CANCEL) { - entity.deleteData(); - } else { - entity.setState(state); - if (location != -1) { - entity.setCurrentProgress(location); - } - entity.update(); - } - } - } - public static class Builder { DownloadGroupTaskEntity taskEntity; Handler outHandler; diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java index ad12a0a2..6e08b321 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java @@ -16,19 +16,14 @@ package com.arialyy.aria.core.download; -import android.content.Context; import android.os.Handler; import android.util.Log; import com.arialyy.aria.core.AriaManager; -import com.arialyy.aria.core.download.downloader.DownloadListener; import com.arialyy.aria.core.download.downloader.SimpleDownloadUtil; -import com.arialyy.aria.core.download.downloader.IDownloadListener; import com.arialyy.aria.core.inf.AbsNormalTask; import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.scheduler.ISchedulers; -import com.arialyy.aria.util.CommonUtil; import java.io.File; -import java.lang.ref.WeakReference; /** * Created by lyy on 2016/8/11. @@ -37,15 +32,14 @@ import java.lang.ref.WeakReference; public class DownloadTask extends AbsNormalTask { public static final String TAG = "DownloadTask"; - private IDownloadListener mListener; + private DListener mListener; private SimpleDownloadUtil mUtil; - private boolean isWait = false; private DownloadTask(DownloadTaskEntity taskEntity, Handler outHandler) { mEntity = taskEntity.getEntity(); mOutHandler = outHandler; mContext = AriaManager.APP; - mListener = new DListener(mContext, this, mOutHandler); + mListener = new DListener<>(this, mOutHandler); mUtil = new SimpleDownloadUtil(taskEntity, mListener); } @@ -112,13 +106,10 @@ public class DownloadTask extends AbsNormalTask { * 开始下载 */ @Override public void start() { - isWait = false; + mListener.isWait = false; if (mUtil.isDownloading()) { Log.d(TAG, "任务正在下载"); } else { - if (mListener == null || isWait) { - mListener = new DListener(mContext, this, mOutHandler); - } mUtil.startDownload(); } } @@ -131,7 +122,7 @@ public class DownloadTask extends AbsNormalTask { } private void stop(boolean isWait) { - this.isWait = isWait; + mListener.isWait = isWait; if (mUtil.isDownloading()) { mUtil.stopDownload(); } else { @@ -185,125 +176,4 @@ public class DownloadTask extends AbsNormalTask { return task; } } - - /** - * 下载监听类 - */ - private static class DListener extends DownloadListener { - WeakReference outHandler; - WeakReference wTask; - Context context; - long lastLen = 0; //上一次发送长度 - long lastTime = 0; - long INTERVAL_TIME = 1000; //1m更新周期 - boolean isFirst = true; - DownloadEntity entity; - DownloadTask task; - boolean isConvertSpeed = false; - - DListener(Context context, DownloadTask task, Handler outHandler) { - this.context = context; - this.outHandler = new WeakReference<>(outHandler); - this.wTask = new WeakReference<>(task); - this.task = wTask.get(); - this.entity = this.task.getDownloadEntity(); - final AriaManager manager = AriaManager.getInstance(context); - isConvertSpeed = manager.getDownloadConfig().isConvertSpeed(); - } - - @Override public void supportBreakpoint(boolean support) { - if (!support) { - sendInState2Target(ISchedulers.SUPPORT_BREAK_POINT); - } - } - - @Override public void onPre() { - sendInState2Target(ISchedulers.PRE); - saveData(IEntity.STATE_PRE, -1); - } - - @Override public void onPostPre(long fileSize) { - entity.setFileSize(fileSize); - entity.setConvertFileSize(CommonUtil.formatFileSize(fileSize)); - sendInState2Target(ISchedulers.POST_PRE); - saveData(IEntity.STATE_POST_PRE, -1); - } - - @Override public void onResume(long resumeLocation) { - sendInState2Target(ISchedulers.RESUME); - saveData(IEntity.STATE_RUNNING, resumeLocation); - } - - @Override public void onStart(long startLocation) { - sendInState2Target(ISchedulers.START); - saveData(IEntity.STATE_RUNNING, startLocation); - } - - @Override public void onProgress(long currentLocation) { - if (System.currentTimeMillis() - lastTime > INTERVAL_TIME) { - long speed = currentLocation - lastLen; - lastTime = System.currentTimeMillis(); - if (isFirst) { - speed = 0; - isFirst = false; - } - handleSpeed(speed); - entity.setCurrentProgress(currentLocation); - lastLen = currentLocation; - sendInState2Target(ISchedulers.RUNNING); - } - } - - @Override public void onStop(long stopLocation) { - handleSpeed(0); - sendInState2Target(ISchedulers.STOP); - saveData(task.isWait ? IEntity.STATE_WAIT : IEntity.STATE_STOP, stopLocation); - } - - @Override public void onCancel() { - handleSpeed(0); - sendInState2Target(ISchedulers.CANCEL); - saveData(IEntity.STATE_CANCEL, -1); - entity.deleteData(); - } - - @Override public void onComplete() { - handleSpeed(0); - sendInState2Target(ISchedulers.COMPLETE); - saveData(IEntity.STATE_COMPLETE, entity.getFileSize()); - } - - @Override public void onFail() { - entity.setFailNum(entity.getFailNum() + 1); - handleSpeed(0); - sendInState2Target(ISchedulers.FAIL); - saveData(IEntity.STATE_FAIL, -1); - } - - private void handleSpeed(long speed) { - if (isConvertSpeed) { - entity.setConvertSpeed(CommonUtil.formatFileSize(speed) + "/s"); - } else { - entity.setSpeed(speed); - } - } - - /** - * 将任务状态发送给下载器 - * - * @param state {@link ISchedulers#START} - */ - private void sendInState2Target(int state) { - if (outHandler.get() != null) { - outHandler.get().obtainMessage(state, task).sendToTarget(); - } - } - - private void saveData(int state, long location) { - entity.setState(state); - entity.setComplete(state == IEntity.STATE_COMPLETE); - entity.setCurrentProgress(location); - entity.update(); - } - } } \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadGroupUtil.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadGroupUtil.java index f688f8ba..403d2b4c 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadGroupUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadGroupUtil.java @@ -350,8 +350,8 @@ public class DownloadGroupUtil implements IDownloadUtil { saveData(IEntity.STATE_COMPLETE, entity.getFileSize()); mCompleteNum++; if (mCompleteNum + mFailNum >= mActualTaskNum) { - mListener.onComplete(); closeTimer(); + mListener.onComplete(); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java index 173f691b..71789239 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java @@ -28,6 +28,8 @@ import java.io.File; import java.io.IOException; import java.util.Properties; import java.util.Set; +import java.util.Timer; +import java.util.TimerTask; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -53,6 +55,7 @@ class Downloader implements Runnable, IDownloadUtil { * 小于1m的文件不启用多线程 */ private static final long SUB_LEN = 1024 * 1024; + private Timer mTimer; Downloader(IDownloadListener listener, DownloadTaskEntity taskEntity) { mListener = listener; @@ -98,6 +101,7 @@ class Downloader implements Runnable, IDownloadUtil { mFixedThreadPool = Executors.newFixedThreadPool(mThreadNum); handleBreakpoint(); } + startTimer(); } catch (IOException e) { failDownload("下载失败【downloadUrl:" + mEntity.getDownloadUrl() @@ -108,6 +112,29 @@ class Downloader implements Runnable, IDownloadUtil { } } + /** + * 启动进度获取定时器 + */ + private void startTimer() { + mTimer = new Timer(true); + mTimer.schedule(new TimerTask() { + @Override public void run() { + if (mConstance.isComplete()) { + closeTimer(); + } else if (mConstance.CURRENT_LOCATION >= 0) { + mListener.onProgress(mConstance.CURRENT_LOCATION); + } + } + }, 0, 1000); + } + + private void closeTimer() { + if (mTimer != null) { + mTimer.purge(); + mTimer.cancel(); + } + } + @Override public long getFileSize() { return mEntity.getFileSize(); } @@ -124,6 +151,7 @@ class Downloader implements Runnable, IDownloadUtil { } @Override public void cancelDownload() { + closeTimer(); mConstance.isCancel = true; mConstance.isDownloading = false; if (mFixedThreadPool != null) { @@ -139,6 +167,7 @@ class Downloader implements Runnable, IDownloadUtil { } @Override public void stopDownload() { + closeTimer(); mConstance.isStop = true; mConstance.isDownloading = false; if (mFixedThreadPool != null) { @@ -370,6 +399,7 @@ class Downloader implements Runnable, IDownloadUtil { } private void failDownload(String errorMsg) { + closeTimer(); Log.e(TAG, errorMsg); mConstance.isDownloading = false; mListener.onFail(); diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/IDownloadUtil.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/IDownloadUtil.java index bcfe8a5a..5d2c7456 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/IDownloadUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/IDownloadUtil.java @@ -25,37 +25,37 @@ public interface IDownloadUtil { /** * 获取文件大小 */ - public long getFileSize(); + long getFileSize(); /** * 获取当前下载位置 */ - public long getCurrentLocation(); + long getCurrentLocation(); /** * 是否正在下载 * * @return true, 正在下载 */ - public boolean isDownloading(); + boolean isDownloading(); /** * 取消下载 */ - public void cancelDownload(); + void cancelDownload(); /** * 停止下载 */ - public void stopDownload(); + void stopDownload(); /** * 开始下载 */ - public void startDownload(); + void startDownload(); /** * 从上次断点恢复下载 */ - public void resumeDownload(); + void resumeDownload(); } \ No newline at end of file diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SingleThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SingleThreadTask.java index 278f4873..8efe4eb3 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SingleThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SingleThreadTask.java @@ -210,7 +210,6 @@ final class SingleThreadTask implements Runnable { synchronized (AriaManager.LOCK) { mChildCurrentLocation += len; CONSTANCE.CURRENT_LOCATION += len; - mListener.onProgress(CONSTANCE.CURRENT_LOCATION); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadGroupTaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadGroupTaskQueue.java index 325284ed..dbf5f665 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadGroupTaskQueue.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/DownloadGroupTaskQueue.java @@ -23,6 +23,7 @@ import com.arialyy.aria.core.download.DownloadGroupEntity; import com.arialyy.aria.core.download.DownloadGroupTask; import com.arialyy.aria.core.download.DownloadGroupTaskEntity; import com.arialyy.aria.core.queue.pool.BaseExecutePool; +import com.arialyy.aria.core.scheduler.DQueueMapping; import com.arialyy.aria.core.scheduler.DownloadGroupSchedulers; /** @@ -55,6 +56,8 @@ public class DownloadGroupTaskQueue .createTask(targetName, entity, DownloadGroupSchedulers.getInstance()); entity.key = entity.getEntity().getGroupName(); mCachePool.putTask(task); + + DQueueMapping.getInstance().addType(task.getKey(), DQueueMapping.QUEUE_TYPE_DOWNLOAD_GROUP); } else { Log.e(TAG, "target name 为 null!!"); } 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 95bece50..6f83e58f 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 @@ -23,6 +23,7 @@ import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.queue.pool.DownloadExecutePool; +import com.arialyy.aria.core.scheduler.DQueueMapping; import com.arialyy.aria.core.scheduler.DownloadSchedulers; import java.util.LinkedHashSet; import java.util.Map; @@ -120,9 +121,12 @@ public class DownloadTaskQueue .createTask(target, entity, DownloadSchedulers.getInstance()); entity.key = entity.getEntity().getDownloadPath(); mCachePool.putTask(task); + + DQueueMapping.getInstance().addType(task.getKey(), DQueueMapping.QUEUE_TYPE_DOWNLOAD); } else { Log.e(TAG, "target name 为 null!!"); } + return task; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/BaseExecutePool.java b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/BaseExecutePool.java index edcb67a4..9c3136dd 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/queue/pool/BaseExecutePool.java +++ b/Aria/src/main/java/com/arialyy/aria/core/queue/pool/BaseExecutePool.java @@ -20,6 +20,7 @@ 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.core.scheduler.DQueueMapping; import com.arialyy.aria.util.CommonUtil; import java.util.HashMap; import java.util.Map; @@ -165,22 +166,22 @@ public class BaseExecutePool implements IPool { Log.e(TAG, "任务不能为空"); return false; } else { - String key = CommonUtil.keyToHashKey(task.getKey()); - mExecuteMap.remove(key); - return mExecuteQueue.remove(task); + return removeTask(task.getKey()); } } } - @Override public boolean removeTask(String downloadUrl) { + @Override public boolean removeTask(String key) { synchronized (AriaManager.LOCK) { - if (TextUtils.isEmpty(downloadUrl)) { + if (TextUtils.isEmpty(key)) { Log.e(TAG, "请传入有效的任务key"); return false; } - String key = CommonUtil.keyToHashKey(downloadUrl); - TASK task = mExecuteMap.get(key); - mExecuteMap.remove(key); + String convertKey = CommonUtil.keyToHashKey(key); + TASK task = mExecuteMap.get(convertKey); + mExecuteMap.remove(convertKey); + + DQueueMapping.getInstance().removeType(key); return mExecuteQueue.remove(task); } } 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 833d8b69..57c7b6f7 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 @@ -16,6 +16,7 @@ package com.arialyy.aria.core.scheduler; import android.os.CountDownTimer; +import android.os.Handler; import android.os.Message; import android.util.Log; import com.arialyy.aria.core.AriaManager; @@ -117,13 +118,10 @@ abstract class AbsSchedulers) clazz.newInstance(); } catch (ClassNotFoundException e) { Log.e(TAG, targetName + ",没有Aria的Download或Upload注解方法"); - //e.printStackTrace(); } catch (InstantiationException e) { Log.e(TAG, e.getMessage()); - //e.printStackTrace(); } catch (IllegalAccessException e) { Log.e(TAG, e.getMessage()); - //e.printStackTrace(); } return listener; } @@ -134,7 +132,6 @@ abstract class AbsSchedulers 0; + } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/DQueueMapping.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/DQueueMapping.java new file mode 100644 index 00000000..f7be0703 --- /dev/null +++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/DQueueMapping.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.arialyy.aria.core.scheduler; + +import com.arialyy.aria.core.AriaManager; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +/** + * Created by Aria.Lao on 2017/7/13. + * 下载任务和队列的映射表 + */ +public class DQueueMapping { + + public static final int QUEUE_TYPE_DOWNLOAD = 0xa1; + public static final int QUEUE_TYPE_DOWNLOAD_GROUP = 0xa2; + public static final int QUEUE_NONE = 0xab2; + LinkedHashMap types = new LinkedHashMap<>(); + + private static volatile DQueueMapping instance = null; + + private DQueueMapping() { + + } + + public static DQueueMapping getInstance() { + if (instance == null) { + synchronized (AriaManager.LOCK) { + instance = new DQueueMapping(); + } + } + return instance; + } + + /** + * map中增加类型 + * + * @param key 任务的key + * @param type {@link #QUEUE_TYPE_DOWNLOAD}、{@link #QUEUE_TYPE_DOWNLOAD} + */ + public void addType(String key, int type) { + types.put(key, type); + } + + /** + * @param key 任务的key + */ + public void removeType(String key) { + types.remove(key); + } + + /** + * 获取下一个任务类型 + * + * @return {@link #QUEUE_TYPE_DOWNLOAD}、{@link #QUEUE_TYPE_DOWNLOAD} + */ + public int nextType() { + Iterator> iter = types.entrySet().iterator(); + if (iter.hasNext()) { + Map.Entry next = iter.next(); + int type = next.getValue(); + iter.remove(); + return type; + } + return QUEUE_NONE; + } +} diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadGroupSchedulers.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadGroupSchedulers.java index a663c886..4ff938ae 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadGroupSchedulers.java +++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadGroupSchedulers.java @@ -49,4 +49,21 @@ public class DownloadGroupSchedulers extends @Override String getProxySuffix() { return "$$DownloadGroupListenerProxy"; } + + @Override protected void startNextTask() { + if (!DownloadSchedulers.getInstance().hasNextTask()) { + nextSelf(); + } else { + Integer nextType = DQueueMapping.getInstance().nextType(); + if (nextType == DQueueMapping.QUEUE_TYPE_DOWNLOAD) { + DownloadSchedulers.getInstance().nextSelf(); + } else { + nextSelf(); + } + } + } + + void nextSelf() { + super.startNextTask(); + } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadSchedulers.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadSchedulers.java index 3c492174..b5fae673 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadSchedulers.java +++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadSchedulers.java @@ -21,6 +21,7 @@ import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.queue.DownloadTaskQueue; import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadTask; +import java.nio.MappedByteBuffer; /** * Created by lyy on 2016/8/16. @@ -52,4 +53,21 @@ public class DownloadSchedulers @Override String getProxySuffix() { return "$$DownloadListenerProxy"; } + + @Override protected void startNextTask() { + if (!DownloadGroupSchedulers.getInstance().hasNextTask()) { + nextSelf(); + } else { + Integer nextType = DQueueMapping.getInstance().nextType(); + if (nextType == DQueueMapping.QUEUE_TYPE_DOWNLOAD_GROUP) { + DownloadGroupSchedulers.getInstance().nextSelf(); + } else { + nextSelf(); + } + } + } + + void nextSelf() { + super.startNextTask(); + } } diff --git a/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java b/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java index 86df2895..41110643 100644 --- a/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java +++ b/AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java @@ -38,63 +38,63 @@ import java.lang.annotation.Target; /** * 如果你在方法中添加{@code @Download.onPre}注解,在预处理完成时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onPre { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onPre { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskPre}注解,在任务预处理完成时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskPre { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskPre { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskResume}注解,在任务恢复下载时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskResume { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskResume { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskStart}注解,在任务开始下载时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskStart { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskStart { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskStop}注解,在任务停止时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskStop { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskStop { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskCancel}l注解,在任务取消时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskCancel { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskCancel { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskFail)注解,在任务预失败时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskFail { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskFail { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskComplete}注解,在任务完成时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskComplete { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskComplete { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskRunning}注解,在任务正在下载,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskRunning { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskRunning { String[] value() default { AriaConstance.NO_URL }; } @@ -102,7 +102,7 @@ import java.lang.annotation.Target; * 如果你在方法中添加{@code @Download.onNoSupportBreakPoint}注解,如果该任务不支持断点,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) - public @interface onNoSupportBreakPoint { + @interface onNoSupportBreakPoint { String[] value() default { AriaConstance.NO_URL }; } } diff --git a/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java b/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java index 6d139b7b..c0777d82 100644 --- a/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java +++ b/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java @@ -37,63 +37,63 @@ import java.lang.annotation.Target; /** * 如果你在方法中添加{@code @Download.onPre}注解,在预处理完成时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onPre { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onPre { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskPre}注解,在任务预处理完成时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskPre { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskPre { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskResume}注解,在任务恢复下载时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskResume { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskResume { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskStart}注解,在任务开始下载时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskStart { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskStart { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskStop}注解,在任务停止时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskStop { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskStop { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskCancel}l注解,在任务取消时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskCancel { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskCancel { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskFail)注解,在任务预失败时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskFail { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskFail { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskComplete}注解,在任务完成时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskComplete { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskComplete { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Download.onTaskRunning}注解,在任务正在下载,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskRunning { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskRunning { String[] value() default { AriaConstance.NO_URL }; } } diff --git a/AriaAnnotations/src/main/java/com/arialyy/annotations/Upload.java b/AriaAnnotations/src/main/java/com/arialyy/annotations/Upload.java index 7906bcc7..609c6663 100644 --- a/AriaAnnotations/src/main/java/com/arialyy/annotations/Upload.java +++ b/AriaAnnotations/src/main/java/com/arialyy/annotations/Upload.java @@ -39,14 +39,14 @@ import java.lang.annotation.Target; /** * 如果你在方法中添加{@code @Upload.onPre}注解,在预处理完成时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onPre { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onPre { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Upload.onTaskPre}注解,在任务预处理完成时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskPre { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskPre { String[] value() default { AriaConstance.NO_URL }; } @@ -59,42 +59,42 @@ import java.lang.annotation.Target; /** * 如果你在方法中添加{@code @Upload.onTaskStart}注解,在任务开始下载时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskStart { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskStart { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Upload.onTaskStop}注解,在任务停止时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskStop { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskStop { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Upload.onTaskCancel}l注解,在任务取消时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskCancel { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskCancel { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Upload.onTaskFail)注解,在任务预失败时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskFail { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskFail { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Upload.onTaskComplete}注解,在任务完成时,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskComplete { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskComplete { String[] value() default { AriaConstance.NO_URL }; } /** * 如果你在方法中添加{@code @Upload.onTaskRunning}注解,在任务正在下载,Aria会调用该方法 */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface onTaskRunning { + @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onTaskRunning { String[] value() default { AriaConstance.NO_URL }; } @@ -102,7 +102,7 @@ import java.lang.annotation.Target; * 如果你在方法中添加{@code @Upload.onNoSupportBreakPoint}注解,如果该任务不支持断点,Aria会调用该方法 */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) - public @interface onNoSupportBreakPoint { + @interface onNoSupportBreakPoint { String[] value() default { AriaConstance.NO_URL }; } } diff --git a/app/src/main/java/com/arialyy/simple/download/multi_download/MultiTaskActivity.java b/app/src/main/java/com/arialyy/simple/download/multi_download/MultiTaskActivity.java index 77e14e0d..f5768e70 100644 --- a/app/src/main/java/com/arialyy/simple/download/multi_download/MultiTaskActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/multi_download/MultiTaskActivity.java @@ -97,6 +97,9 @@ public class MultiTaskActivity extends BaseActivity { mAdapter.updateBtState(task.getKey(), true); } + + + @Override protected void dataCallback(int result, Object data) { super.dataCallback(result, data); if (result == DownloadNumDialog.RESULT_CODE) {