任务组和单任务调度器同步

pull/330/head
AriaLyy 7 years ago
parent e21d2591af
commit e8a9754567
  1. 1
      Aria/src/main/java/com/arialyy/aria/core/command/AbsCmdFactory.java
  2. 3
      Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java
  3. 139
      Aria/src/main/java/com/arialyy/aria/core/download/DListener.java
  4. 24
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupListener.java
  5. 125
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java
  6. 138
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java
  7. 2
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadGroupUtil.java
  8. 30
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java
  9. 14
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/IDownloadUtil.java
  10. 1
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/SingleThreadTask.java
  11. 3
      Aria/src/main/java/com/arialyy/aria/core/queue/DownloadGroupTaskQueue.java
  12. 4
      Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java
  13. 17
      Aria/src/main/java/com/arialyy/aria/core/queue/pool/BaseExecutePool.java
  14. 21
      Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java
  15. 82
      Aria/src/main/java/com/arialyy/aria/core/scheduler/DQueueMapping.java
  16. 17
      Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadGroupSchedulers.java
  17. 18
      Aria/src/main/java/com/arialyy/aria/core/scheduler/DownloadSchedulers.java
  18. 20
      AriaAnnotations/src/main/java/com/arialyy/annotations/Download.java
  19. 18
      AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java
  20. 18
      AriaAnnotations/src/main/java/com/arialyy/annotations/Upload.java
  21. 3
      app/src/main/java/com/arialyy/simple/download/multi_download/MultiTaskActivity.java

@ -19,6 +19,7 @@ import com.arialyy.aria.core.inf.AbsTaskEntity;
/**
* Created by AriaL on 2017/6/29.
* 抽象命令工厂
*/
public abstract class AbsCmdFactory<CMD extends AbsCmd> {

@ -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;

@ -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<ENTITY extends AbsEntity, TASK extends AbsTask<ENTITY>>
extends DownloadListener {
private WeakReference<Handler> 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();
}
}
}

@ -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 {
}

@ -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<DownloadGroupTaskEntity, DownloadGroupEntity> {
private final String TAG = "DownloadGroupTask";
private DListener mListener;
private DListener<DownloadGroupEntity, DownloadGroupTask> mListener;
private IDownloadUtil mUtil;
private DownloadGroupTask(DownloadGroupTaskEntity taskEntity, Handler outHandler) {
@ -43,7 +37,7 @@ public class DownloadGroupTask extends AbsGroupTask<DownloadGroupTaskEntity, Dow
mEntity = taskEntity.getEntity();
mOutHandler = outHandler;
mContext = AriaManager.APP;
mListener = new DListener(mContext, this, mOutHandler);
mListener = new DListener<>(this, mOutHandler);
mUtil = new DownloadGroupUtil(mListener, mTaskEntity);
}
@ -73,121 +67,6 @@ public class DownloadGroupTask extends AbsGroupTask<DownloadGroupTaskEntity, Dow
mUtil.cancelDownload();
}
/**
* 下载监听类
*/
private static class DListener extends DownloadListener {
private final String TAG = "DListener";
WeakReference<Handler> outHandler;
WeakReference<DownloadGroupTask> 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;

@ -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<DownloadEntity> {
public static final String TAG = "DownloadTask";
private IDownloadListener mListener;
private DListener<DownloadEntity, DownloadTask> 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<DownloadEntity> {
* 开始下载
*/
@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<DownloadEntity> {
}
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<DownloadEntity> {
return task;
}
}
/**
* 下载监听类
*/
private static class DListener extends DownloadListener {
WeakReference<Handler> outHandler;
WeakReference<DownloadTask> 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();
}
}
}

@ -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();
}
}

@ -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();

@ -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();
}

@ -210,7 +210,6 @@ final class SingleThreadTask implements Runnable {
synchronized (AriaManager.LOCK) {
mChildCurrentLocation += len;
CONSTANCE.CURRENT_LOCATION += len;
mListener.onProgress(CONSTANCE.CURRENT_LOCATION);
}
}

@ -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!!");
}

@ -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;
}

@ -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<TASK extends ITask> implements IPool<TASK> {
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);
}
}

@ -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<TASK_ENTITY extends AbsTaskEntity, ENTITY extends A
listener = (AbsSchedulerListener<TASK>) 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<TASK_ENTITY extends AbsTaskEntity, ENTITY extends A
Log.e(TAG, "请传入下载任务");
return true;
}
//callback(msg.what, task);
ENTITY entity = task.getEntity();
switch (msg.what) {
case STOP:
@ -209,6 +206,11 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskEntity, ENTITY extends A
listener.onTaskCancel(task);
break;
case COMPLETE:
//new Handler().postDelayed(new Runnable() {
// @Override public void run() {
// listener.onTaskComplete(task);
// }
//}, 1000);
listener.onTaskComplete(task);
break;
case FAIL:
@ -262,7 +264,7 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskEntity, ENTITY extends A
/**
* 启动下一个任务条件任务停止取消下载任务完成
*/
private void startNextTask() {
protected void startNextTask() {
TASK newTask = mQueue.getNextTask();
if (newTask == null) {
Log.w(TAG, "没有下一任务");
@ -272,4 +274,13 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskEntity, ENTITY extends A
mQueue.startTask(newTask);
}
}
/**
* 是否有下一任务
*
* @return {@code true} {@code false}
*/
protected boolean hasNextTask() {
return mQueue.getCachePoolSize() > 0;
}
}

@ -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<String, Integer> 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<Map.Entry<String, Integer>> iter = types.entrySet().iterator();
if (iter.hasNext()) {
Map.Entry<String, Integer> next = iter.next();
int type = next.getValue();
iter.remove();
return type;
}
return QUEUE_NONE;
}
}

@ -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();
}
}

@ -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();
}
}

@ -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 };
}
}

@ -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 };
}
}

@ -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 };
}
}

@ -97,6 +97,9 @@ public class MultiTaskActivity extends BaseActivity<ActivityMultiBinding> {
mAdapter.updateBtState(task.getKey(), true);
}
@Override protected void dataCallback(int result, Object data) {
super.dataCallback(result, data);
if (result == DownloadNumDialog.RESULT_CODE) {

Loading…
Cancel
Save