任务组队列完成
This commit is contained in:
@ -16,8 +16,10 @@
|
|||||||
package com.arialyy.aria.core.command.group;
|
package com.arialyy.aria.core.command.group;
|
||||||
|
|
||||||
import com.arialyy.aria.core.command.AbsCmd;
|
import com.arialyy.aria.core.command.AbsCmd;
|
||||||
|
import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
|
||||||
import com.arialyy.aria.core.download.DownloadTaskEntity;
|
import com.arialyy.aria.core.download.DownloadTaskEntity;
|
||||||
import com.arialyy.aria.core.inf.AbsTaskEntity;
|
import com.arialyy.aria.core.inf.AbsTaskEntity;
|
||||||
|
import com.arialyy.aria.core.queue.DownloadGroupTaskQueue;
|
||||||
import com.arialyy.aria.core.queue.DownloadTaskQueue;
|
import com.arialyy.aria.core.queue.DownloadTaskQueue;
|
||||||
import com.arialyy.aria.core.queue.UploadTaskQueue;
|
import com.arialyy.aria.core.queue.UploadTaskQueue;
|
||||||
import com.arialyy.aria.core.upload.UploadTaskEntity;
|
import com.arialyy.aria.core.upload.UploadTaskEntity;
|
||||||
@ -36,12 +38,9 @@ public abstract class AbsGroupCmd<T extends AbsTaskEntity> extends AbsCmd<T> {
|
|||||||
mTargetName = targetName;
|
mTargetName = targetName;
|
||||||
mTaskEntity = entity;
|
mTaskEntity = entity;
|
||||||
TAG = CommonUtil.getClassName(this);
|
TAG = CommonUtil.getClassName(this);
|
||||||
if (entity instanceof DownloadTaskEntity) {
|
if (entity instanceof DownloadGroupTaskEntity) {
|
||||||
mQueue = DownloadTaskQueue.getInstance();
|
mQueue = DownloadGroupTaskQueue.getInstance();
|
||||||
isDownloadCmd = true;
|
isDownloadCmd = true;
|
||||||
} else if (entity instanceof UploadTaskEntity) {
|
|
||||||
mQueue = UploadTaskQueue.getInstance();
|
|
||||||
isDownloadCmd = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ class AddCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T> {
|
|||||||
|
|
||||||
@Override public void executeCmd() {
|
@Override public void executeCmd() {
|
||||||
if (!canExeCmd) return;
|
if (!canExeCmd) return;
|
||||||
AbsNormalTask task = mQueue.getTask(mTaskEntity.getEntity());
|
AbsNormalTask task = (AbsNormalTask) mQueue.getTask(mTaskEntity.getEntity());
|
||||||
if (task == null) {
|
if (task == null) {
|
||||||
mTaskEntity.getEntity().setState(IEntity.STATE_WAIT);
|
mTaskEntity.getEntity().setState(IEntity.STATE_WAIT);
|
||||||
mQueue.createTask(mTargetName, mTaskEntity);
|
mQueue.createTask(mTargetName, mTaskEntity);
|
||||||
|
@ -31,9 +31,9 @@ class CancelCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T> {
|
|||||||
|
|
||||||
@Override public void executeCmd() {
|
@Override public void executeCmd() {
|
||||||
if (!canExeCmd) return;
|
if (!canExeCmd) return;
|
||||||
AbsNormalTask task = mQueue.getTask(mTaskEntity.getEntity());
|
AbsNormalTask task = (AbsNormalTask) mQueue.getTask(mTaskEntity.getEntity());
|
||||||
if (task == null) {
|
if (task == null) {
|
||||||
task = mQueue.createTask(mTargetName, mTaskEntity);
|
task = (AbsNormalTask) mQueue.createTask(mTargetName, mTaskEntity);
|
||||||
}
|
}
|
||||||
if (task != null) {
|
if (task != null) {
|
||||||
if (!TextUtils.isEmpty(mTargetName)) {
|
if (!TextUtils.isEmpty(mTargetName)) {
|
||||||
|
@ -16,8 +16,10 @@
|
|||||||
package com.arialyy.aria.core.command.normal;
|
package com.arialyy.aria.core.command.normal;
|
||||||
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import com.arialyy.aria.core.download.DownloadTask;
|
||||||
import com.arialyy.aria.core.inf.AbsNormalTask;
|
import com.arialyy.aria.core.inf.AbsNormalTask;
|
||||||
import com.arialyy.aria.core.inf.AbsTaskEntity;
|
import com.arialyy.aria.core.inf.AbsTaskEntity;
|
||||||
|
import com.arialyy.aria.core.queue.DownloadTaskQueue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by lyy on 2017/6/2.
|
* Created by lyy on 2017/6/2.
|
||||||
@ -28,6 +30,8 @@ import com.arialyy.aria.core.inf.AbsTaskEntity;
|
|||||||
* 4、用户手动暂停或任务完成后,第二次重新执行该任务,该命令将失效
|
* 4、用户手动暂停或任务完成后,第二次重新执行该任务,该命令将失效
|
||||||
* 5、如果下载队列中已经满了,则会停止队尾的任务,当高优先级任务完成后,该队尾任务将自动执行
|
* 5、如果下载队列中已经满了,则会停止队尾的任务,当高优先级任务完成后,该队尾任务将自动执行
|
||||||
* 6、把任务设置为最高优先级任务后,将自动执行任务,不需要重新调用start()启动任务
|
* 6、把任务设置为最高优先级任务后,将自动执行任务,不需要重新调用start()启动任务
|
||||||
|
*
|
||||||
|
* 目前只只支持单下载任务的最高优先级任务
|
||||||
*/
|
*/
|
||||||
final class HighestPriorityCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T> {
|
final class HighestPriorityCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T> {
|
||||||
/**
|
/**
|
||||||
@ -39,15 +43,15 @@ final class HighestPriorityCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T>
|
|||||||
|
|
||||||
@Override public void executeCmd() {
|
@Override public void executeCmd() {
|
||||||
if (!canExeCmd) return;
|
if (!canExeCmd) return;
|
||||||
AbsNormalTask task = mQueue.getTask(mTaskEntity.getEntity());
|
DownloadTask task = (DownloadTask) mQueue.getTask(mTaskEntity.getEntity());
|
||||||
if (task == null) {
|
if (task == null) {
|
||||||
task = mQueue.createTask(mTargetName, mTaskEntity);
|
task = (DownloadTask) mQueue.createTask(mTargetName, mTaskEntity);
|
||||||
}
|
}
|
||||||
if (task != null) {
|
if (task != null) {
|
||||||
if (!TextUtils.isEmpty(mTargetName)) {
|
if (!TextUtils.isEmpty(mTargetName)) {
|
||||||
task.setTargetName(mTargetName);
|
task.setTargetName(mTargetName);
|
||||||
}
|
}
|
||||||
mQueue.setTaskHighestPriority(task);
|
((DownloadTaskQueue) mQueue).setTaskHighestPriority(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,10 +39,10 @@ final class ResumeAllCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private AbsNormalTask createTask(DownloadEntity entity) {
|
private AbsNormalTask createTask(DownloadEntity entity) {
|
||||||
AbsNormalTask task = mQueue.getTask(entity);
|
AbsNormalTask task = (AbsNormalTask) mQueue.getTask(entity);
|
||||||
if (task == null) {
|
if (task == null) {
|
||||||
DownloadTaskEntity taskEntity = new DownloadTaskEntity(entity);
|
DownloadTaskEntity taskEntity = new DownloadTaskEntity(entity);
|
||||||
task = mQueue.createTask(mTargetName, taskEntity);
|
task = (AbsNormalTask) mQueue.createTask(mTargetName, taskEntity);
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "添加命令执行失败,【该任务已经存在】");
|
Log.w(TAG, "添加命令执行失败,【该任务已经存在】");
|
||||||
}
|
}
|
||||||
|
@ -47,9 +47,9 @@ class StartCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T> {
|
|||||||
maxTaskNum = manager.getUploadConfig().getMaxTaskNum();
|
maxTaskNum = manager.getUploadConfig().getMaxTaskNum();
|
||||||
}
|
}
|
||||||
|
|
||||||
AbsNormalTask task = mQueue.getTask(mTaskEntity.getEntity());
|
AbsNormalTask task = (AbsNormalTask) mQueue.getTask(mTaskEntity.getEntity());
|
||||||
if (task == null) {
|
if (task == null) {
|
||||||
task = mQueue.createTask(mTargetName, mTaskEntity);
|
task = (AbsNormalTask) mQueue.createTask(mTargetName, mTaskEntity);
|
||||||
if (!TextUtils.isEmpty(mTargetName)) {
|
if (!TextUtils.isEmpty(mTargetName)) {
|
||||||
task.setTargetName(mTargetName);
|
task.setTargetName(mTargetName);
|
||||||
}
|
}
|
||||||
|
@ -34,10 +34,10 @@ class StopCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T> {
|
|||||||
|
|
||||||
@Override public void executeCmd() {
|
@Override public void executeCmd() {
|
||||||
if (!canExeCmd) return;
|
if (!canExeCmd) return;
|
||||||
AbsNormalTask task = mQueue.getTask(mTaskEntity.getEntity());
|
AbsNormalTask task = (AbsNormalTask) mQueue.getTask(mTaskEntity.getEntity());
|
||||||
if (task == null) {
|
if (task == null) {
|
||||||
if (mTaskEntity.getEntity().getState() == IEntity.STATE_RUNNING) {
|
if (mTaskEntity.getEntity().getState() == IEntity.STATE_RUNNING) {
|
||||||
task = mQueue.createTask(mTargetName, mTaskEntity);
|
task = (AbsNormalTask) mQueue.createTask(mTargetName, mTaskEntity);
|
||||||
mQueue.stopTask(task);
|
mQueue.stopTask(task);
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "停止命令执行失败,【调度器中没有该任务】");
|
Log.w(TAG, "停止命令执行失败,【调度器中没有该任务】");
|
||||||
|
@ -1,269 +1,205 @@
|
|||||||
///*
|
/*
|
||||||
// * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||||
// *
|
*
|
||||||
// * Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// * you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
// * You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
// *
|
*
|
||||||
// * http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
// *
|
*
|
||||||
// * Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
// * distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// * See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
// * limitations under the License.
|
* limitations under the License.
|
||||||
// */
|
*/
|
||||||
//package com.arialyy.aria.core.download;
|
package com.arialyy.aria.core.download;
|
||||||
//
|
|
||||||
//import android.content.Context;
|
import android.content.Context;
|
||||||
//import android.os.Handler;
|
import android.os.Handler;
|
||||||
//import android.util.SparseArray;
|
import com.arialyy.aria.core.AriaManager;
|
||||||
//import com.arialyy.aria.core.Aria;
|
import com.arialyy.aria.core.download.downloader.DownloadGroupUtil;
|
||||||
//import com.arialyy.aria.core.AriaManager;
|
import com.arialyy.aria.core.download.downloader.DownloadListener;
|
||||||
//import com.arialyy.aria.core.download.downloader.DownloadListener;
|
import com.arialyy.aria.core.download.downloader.IDownloadUtil;
|
||||||
//import com.arialyy.aria.core.download.downloader.DownloadUtil;
|
import com.arialyy.aria.core.inf.AbsGroupTask;
|
||||||
//import com.arialyy.aria.core.inf.AbsGroupTask;
|
import com.arialyy.aria.core.inf.IEntity;
|
||||||
//import com.arialyy.aria.core.inf.IEntity;
|
import com.arialyy.aria.core.scheduler.DownloadSchedulers;
|
||||||
//import com.arialyy.aria.core.scheduler.DownloadSchedulers;
|
import com.arialyy.aria.core.scheduler.ISchedulers;
|
||||||
//import com.arialyy.aria.core.scheduler.ISchedulers;
|
import com.arialyy.aria.util.CheckUtil;
|
||||||
//import com.arialyy.aria.util.CheckUtil;
|
import com.arialyy.aria.util.CommonUtil;
|
||||||
//import com.arialyy.aria.util.CommonUtil;
|
import java.lang.ref.WeakReference;
|
||||||
//import java.lang.ref.WeakReference;
|
|
||||||
//import java.util.HashMap;
|
/**
|
||||||
//import java.util.List;
|
* Created by AriaL on 2017/6/27.
|
||||||
//import java.util.Map;
|
* 任务组任务
|
||||||
//import java.util.concurrent.ExecutorService;
|
*/
|
||||||
//import java.util.concurrent.Executors;
|
public class DownloadGroupTask extends AbsGroupTask<DownloadGroupTaskEntity, DownloadGroupEntity> {
|
||||||
//
|
private DListener mListener;
|
||||||
///**
|
private IDownloadUtil mUtil;
|
||||||
// * Created by AriaL on 2017/6/27.
|
|
||||||
// * 任务组任务
|
private DownloadGroupTask(DownloadGroupTaskEntity taskEntity, Handler outHandler) {
|
||||||
// */
|
mTaskEntity = taskEntity;
|
||||||
//public class DownloadGroupTask extends AbsGroupTask<DownloadTaskEntity, DownloadGroupEntity> {
|
mEntity = taskEntity.getEntity();
|
||||||
// DListener mListener;
|
mOutHandler = outHandler;
|
||||||
// SparseArray<DownloadUtil> mUtils = new SparseArray<>();
|
mContext = AriaManager.APP;
|
||||||
// boolean isStop = false;
|
mListener = new DListener(mContext, this, mOutHandler);
|
||||||
//
|
mUtil = new DownloadGroupUtil(mListener, mTaskEntity);
|
||||||
// private ExecutorService mFixedThreadPool;
|
}
|
||||||
//
|
|
||||||
// private DownloadGroupTask(DownloadTaskEntity taskEntity, Handler outHandler) {
|
@Override public boolean isRunning() {
|
||||||
// mTaskEntity = taskEntity;
|
return mUtil.isDownloading();
|
||||||
// mEntity = taskEntity.groupEntity;
|
}
|
||||||
// mOutHandler = outHandler;
|
|
||||||
// mContext = AriaManager.APP;
|
@Override public void start() {
|
||||||
// mListener = new DListener(mContext, this, mOutHandler);
|
mUtil.stopDownload();
|
||||||
// mFixedThreadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
}
|
||||||
// }
|
|
||||||
//
|
@Override public void stop() {
|
||||||
// @Override public void start() {
|
mUtil.startDownload();
|
||||||
// List<DownloadEntity> childs = mEntity.getChild();
|
}
|
||||||
// int i = 1;
|
|
||||||
// mListener.sendInState2Target(ISchedulers.PRE);
|
@Override public void cancel() {
|
||||||
// for (DownloadEntity entity : childs) {
|
mUtil.cancelDownload();
|
||||||
// DownloadUtil util = createChildDownload(entity);
|
}
|
||||||
// if (isStop) break;
|
|
||||||
// mUtils.append(i, util);
|
/**
|
||||||
// mFixedThreadPool.execute(util);
|
* 下载监听类
|
||||||
// i++;
|
*/
|
||||||
// }
|
private static class DListener extends DownloadListener {
|
||||||
// }
|
WeakReference<Handler> outHandler;
|
||||||
//
|
WeakReference<DownloadGroupTask> wTask;
|
||||||
// /**
|
Context context;
|
||||||
// * 创建任务组单个任务下载工具
|
long lastLen = 0; //上一次发送长度
|
||||||
// */
|
boolean isFirst = true;
|
||||||
// private DownloadUtil createChildDownload(DownloadEntity entity) {
|
DownloadGroupEntity entity;
|
||||||
// DownloadTaskEntity taskEntity = new DownloadTaskEntity(entity);
|
DownloadGroupTask task;
|
||||||
// taskEntity.headers = mTaskEntity.headers;
|
boolean isConvertSpeed = false;
|
||||||
// taskEntity.requestEnum = mTaskEntity.requestEnum;
|
|
||||||
// taskEntity.redirectUrlKey = mTaskEntity.redirectUrlKey;
|
DListener(Context context, DownloadGroupTask task, Handler outHandler) {
|
||||||
// taskEntity.removeFile = mTaskEntity.removeFile;
|
this.context = context;
|
||||||
// return new DownloadUtil(mContext, taskEntity, mListener);
|
this.outHandler = new WeakReference<>(outHandler);
|
||||||
// }
|
this.wTask = new WeakReference<>(task);
|
||||||
//
|
this.task = wTask.get();
|
||||||
// @Override public void stop() {
|
this.entity = this.task.getEntity();
|
||||||
// isStop = true;
|
final AriaManager manager = AriaManager.getInstance(context);
|
||||||
// if (mFixedThreadPool != null) {
|
isConvertSpeed = manager.getDownloadConfig().isConvertSpeed();
|
||||||
// mFixedThreadPool.shutdown();
|
}
|
||||||
// }
|
|
||||||
// for (int i = 1, len = mUtils.size(); i <= len; i++) {
|
@Override public void onPre() {
|
||||||
// DownloadUtil util = mUtils.get(i);
|
saveData(IEntity.STATE_PRE, -1);
|
||||||
// if (util != null && util.isDownloading()) {
|
sendInState2Target(ISchedulers.PRE);
|
||||||
// util.stopDownload();
|
}
|
||||||
// }
|
|
||||||
// }
|
@Override public void onPostPre(long fileSize) {
|
||||||
// }
|
entity.setFileSize(fileSize);
|
||||||
//
|
saveData(IEntity.STATE_POST_PRE, -1);
|
||||||
// @Override public void cancel() {
|
sendInState2Target(ISchedulers.POST_PRE);
|
||||||
// isStop = true;
|
}
|
||||||
// if (mFixedThreadPool != null) {
|
|
||||||
// mFixedThreadPool.shutdown();
|
@Override public void onStart(long startLocation) {
|
||||||
// }
|
saveData(IEntity.STATE_RUNNING, startLocation);
|
||||||
// for (int i = 1, len = mUtils.size(); i <= len; i++) {
|
sendInState2Target(ISchedulers.START);
|
||||||
// DownloadUtil util = mUtils.get(i);
|
}
|
||||||
// if (util != null) {
|
|
||||||
// util.cancelDownload();
|
@Override public void onResume(long resumeLocation) {
|
||||||
// }
|
saveData(IEntity.STATE_RUNNING, resumeLocation);
|
||||||
// }
|
sendInState2Target(ISchedulers.RESUME);
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// /**
|
@Override public void onProgress(long currentLocation) {
|
||||||
// * 下载监听类
|
long speed = currentLocation - lastLen;
|
||||||
// */
|
if (isFirst) {
|
||||||
// private static class DListener extends DownloadListener {
|
speed = 0;
|
||||||
// WeakReference<Handler> outHandler;
|
isFirst = false;
|
||||||
// WeakReference<DownloadGroupTask> wTask;
|
}
|
||||||
// Context context;
|
handleSpeed(speed);
|
||||||
// long lastLen = 0; //上一次发送长度
|
lastLen = currentLocation;
|
||||||
// long lastTime = 0;
|
sendInState2Target(ISchedulers.RUNNING);
|
||||||
// long INTERVAL_TIME = 1000; //1m更新周期
|
}
|
||||||
// boolean isFirst = true;
|
|
||||||
// DownloadGroupEntity groupEntity;
|
@Override public void onStop(long stopLocation) {
|
||||||
// DownloadGroupTask task;
|
saveData(IEntity.STATE_STOP, stopLocation);
|
||||||
// boolean isConvertSpeed = false;
|
handleSpeed(0);
|
||||||
// Map<String, DownloadEntity> mEntityMap = new HashMap<>();
|
sendInState2Target(ISchedulers.STOP);
|
||||||
//
|
}
|
||||||
// DListener(Context context, DownloadGroupTask task, Handler outHandler) {
|
|
||||||
// this.context = context;
|
@Override public void onCancel() {
|
||||||
// this.outHandler = new WeakReference<>(outHandler);
|
saveData(IEntity.STATE_CANCEL, -1);
|
||||||
// this.wTask = new WeakReference<>(task);
|
handleSpeed(0);
|
||||||
// this.task = wTask.get();
|
sendInState2Target(ISchedulers.CANCEL);
|
||||||
// this.groupEntity = this.task.getEntity();
|
}
|
||||||
// final AriaManager manager = AriaManager.getInstance(context);
|
|
||||||
// isConvertSpeed = manager.getDownloadConfig().isConvertSpeed();
|
@Override public void onComplete() {
|
||||||
// for (DownloadEntity entity : groupEntity.getChild()) {
|
saveData(IEntity.STATE_COMPLETE, entity.getFileSize());
|
||||||
// mEntityMap.put(entity.getDownloadUrl(), entity);
|
handleSpeed(0);
|
||||||
// }
|
sendInState2Target(ISchedulers.COMPLETE);
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// @Override public void onPre(String url) {
|
@Override public void onFail() {
|
||||||
// saveData(url, IEntity.STATE_PRE, -1);
|
entity.setFailNum(entity.getFailNum() + 1);
|
||||||
// }
|
saveData(IEntity.STATE_FAIL, -1);
|
||||||
//
|
handleSpeed(0);
|
||||||
// @Override public void onPostPre(String url, long fileSize) {
|
sendInState2Target(ISchedulers.FAIL);
|
||||||
// DownloadEntity entity = mEntityMap.get(url);
|
}
|
||||||
// if (entity != null){
|
|
||||||
// entity.setFileSize(fileSize);
|
private void handleSpeed(long speed) {
|
||||||
// }
|
if (isConvertSpeed) {
|
||||||
// saveData(url, IEntity.STATE_POST_PRE, -1);
|
entity.setConvertSpeed(CommonUtil.formatFileSize(speed) + "/s");
|
||||||
// }
|
} else {
|
||||||
//
|
entity.setSpeed(speed);
|
||||||
// @Override public void onStart(String url, long startLocation) {
|
}
|
||||||
// downloadEntity.setState(IEntity.STATE_RUNNING);
|
}
|
||||||
// sendInState2Target(ISchedulers.START);
|
|
||||||
// sendIntent(Aria.ACTION_START, startLocation);
|
/**
|
||||||
// }
|
* 将任务状态发送给下载器
|
||||||
//
|
*
|
||||||
// @Override public void onResume(String url, long resumeLocation) {
|
* @param state {@link DownloadSchedulers#START}
|
||||||
// downloadEntity.setState(IEntity.STATE_RUNNING);
|
*/
|
||||||
// sendInState2Target(ISchedulers.RESUME);
|
private void sendInState2Target(int state) {
|
||||||
// sendIntent(Aria.ACTION_RESUME, resumeLocation);
|
if (outHandler.get() != null) {
|
||||||
// }
|
outHandler.get().obtainMessage(state, task).sendToTarget();
|
||||||
//
|
}
|
||||||
// @Override public void onProgress(String url, long currentLocation) {
|
}
|
||||||
// if (System.currentTimeMillis() - lastTime > INTERVAL_TIME) {
|
|
||||||
// long speed = currentLocation - lastLen;
|
private void saveData(int state, long location) {
|
||||||
// sendIntent.putExtra(Aria.CURRENT_LOCATION, currentLocation);
|
if (state == IEntity.STATE_CANCEL) {
|
||||||
// sendIntent.putExtra(Aria.CURRENT_SPEED, speed);
|
entity.deleteData();
|
||||||
// lastTime = System.currentTimeMillis();
|
} else {
|
||||||
// if (isFirst) {
|
entity.setState(state);
|
||||||
// speed = 0;
|
if (location != -1) {
|
||||||
// isFirst = false;
|
entity.setCurrentProgress(location);
|
||||||
// }
|
}
|
||||||
// handleSpeed(speed);
|
entity.update();
|
||||||
// downloadEntity.setCurrentProgress(currentLocation);
|
}
|
||||||
// lastLen = currentLocation;
|
}
|
||||||
// sendInState2Target(ISchedulers.RUNNING);
|
}
|
||||||
// context.sendBroadcast(sendIntent);
|
|
||||||
// }
|
public static class Builder {
|
||||||
// }
|
DownloadGroupTaskEntity taskEntity;
|
||||||
//
|
Handler outHandler;
|
||||||
// @Override public void onStop(String url, long stopLocation) {
|
String targetName;
|
||||||
// downloadEntity.setState(task.isWait ? IEntity.STATE_WAIT : IEntity.STATE_STOP);
|
|
||||||
// handleSpeed(0);
|
public Builder(String targetName, DownloadGroupTaskEntity taskEntity) {
|
||||||
// sendInState2Target(ISchedulers.STOP);
|
CheckUtil.checkTaskEntity(taskEntity);
|
||||||
// sendIntent(Aria.ACTION_STOP, stopLocation);
|
this.targetName = targetName;
|
||||||
// }
|
this.taskEntity = taskEntity;
|
||||||
//
|
}
|
||||||
// @Override public void onCancel(String url) {
|
|
||||||
// downloadEntity.setState(IEntity.STATE_CANCEL);
|
/**
|
||||||
// handleSpeed(0);
|
* 设置自定义Handler处理下载状态时间
|
||||||
// sendInState2Target(ISchedulers.CANCEL);
|
*
|
||||||
// sendIntent(Aria.ACTION_CANCEL, -1);
|
* @param schedulers {@link ISchedulers}
|
||||||
// downloadEntity.deleteData();
|
*/
|
||||||
// }
|
public DownloadGroupTask.Builder setOutHandler(ISchedulers schedulers) {
|
||||||
//
|
this.outHandler = new Handler(schedulers);
|
||||||
// @Override public void onComplete(String url) {
|
return this;
|
||||||
// downloadEntity.setState(IEntity.STATE_COMPLETE);
|
}
|
||||||
// downloadEntity.setDownloadComplete(true);
|
|
||||||
// handleSpeed(0);
|
public DownloadGroupTask build() {
|
||||||
// sendInState2Target(ISchedulers.COMPLETE);
|
DownloadGroupTask task = new DownloadGroupTask(taskEntity, outHandler);
|
||||||
// sendIntent(Aria.ACTION_COMPLETE, downloadEntity.getFileSize());
|
task.setTargetName(targetName);
|
||||||
// }
|
taskEntity.save();
|
||||||
//
|
return task;
|
||||||
// @Override public void onFail(String url) {
|
}
|
||||||
// downloadEntity.setFailNum(downloadEntity.getFailNum() + 1);
|
}
|
||||||
// downloadEntity.setState(IEntity.STATE_FAIL);
|
}
|
||||||
// handleSpeed(0);
|
|
||||||
// sendInState2Target(ISchedulers.FAIL);
|
|
||||||
// sendIntent(Aria.ACTION_FAIL, -1);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private void handleSpeed(long speed) {
|
|
||||||
// if (isConvertSpeed) {
|
|
||||||
// downloadEntity.setConvertSpeed(CommonUtil.formatFileSize(speed) + "/s");
|
|
||||||
// } else {
|
|
||||||
// downloadEntity.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(String url, int state, long location) {
|
|
||||||
// DownloadEntity child = mEntityMap.get(url);
|
|
||||||
// if (child != null) {
|
|
||||||
// child.setState(state);
|
|
||||||
// child.setDownloadComplete(state == IEntity.STATE_COMPLETE);
|
|
||||||
// child.setCurrentProgress(location);
|
|
||||||
// child.update();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public static class Builder {
|
|
||||||
// DownloadTaskEntity taskEntity;
|
|
||||||
// Handler outHandler;
|
|
||||||
// String targetName;
|
|
||||||
//
|
|
||||||
// public Builder(String targetName, DownloadTaskEntity taskEntity) {
|
|
||||||
// CheckUtil.checkTaskEntity(taskEntity);
|
|
||||||
// this.targetName = targetName;
|
|
||||||
// this.taskEntity = taskEntity;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 设置自定义Handler处理下载状态时间
|
|
||||||
// *
|
|
||||||
// * @param schedulers {@link ISchedulers}
|
|
||||||
// */
|
|
||||||
// public DownloadGroupTask.Builder setOutHandler(ISchedulers schedulers) {
|
|
||||||
// this.outHandler = new Handler(schedulers);
|
|
||||||
// return this;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public DownloadGroupTask build() {
|
|
||||||
// DownloadGroupTask task = new DownloadGroupTask(taskEntity, outHandler);
|
|
||||||
// task.setTargetName(targetName);
|
|
||||||
// taskEntity.downloadEntity.save();
|
|
||||||
// return task;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
@ -46,11 +46,11 @@ public class DownloadTask extends AbsNormalTask<DownloadEntity> {
|
|||||||
private boolean isWait = false;
|
private boolean isWait = false;
|
||||||
|
|
||||||
private DownloadTask(DownloadTaskEntity taskEntity, Handler outHandler) {
|
private DownloadTask(DownloadTaskEntity taskEntity, Handler outHandler) {
|
||||||
mEntity = taskEntity.downloadEntity;
|
mEntity = taskEntity.getEntity();
|
||||||
mOutHandler = outHandler;
|
mOutHandler = outHandler;
|
||||||
mContext = AriaManager.APP;
|
mContext = AriaManager.APP;
|
||||||
mListener = new DListener(mContext, this, mOutHandler);
|
mListener = new DListener(mContext, this, mOutHandler);
|
||||||
mUtil = new DownloadUtil(mContext, taskEntity, mListener);
|
mUtil = new DownloadUtil(taskEntity, mListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -194,7 +194,7 @@ public class DownloadTask extends AbsNormalTask<DownloadEntity> {
|
|||||||
public DownloadTask build() {
|
public DownloadTask build() {
|
||||||
DownloadTask task = new DownloadTask(taskEntity, outHandler);
|
DownloadTask task = new DownloadTask(taskEntity, outHandler);
|
||||||
task.setTargetName(targetName);
|
task.setTargetName(targetName);
|
||||||
taskEntity.downloadEntity.save();
|
taskEntity.getEntity().save();
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,14 +68,14 @@ public class DownloadGroupUtil implements IDownloadUtil {
|
|||||||
/**
|
/**
|
||||||
* 下载器映射表,key为下载地址
|
* 下载器映射表,key为下载地址
|
||||||
*/
|
*/
|
||||||
private Map<String, DownloadThreader> mDownloaderMap = new HashMap<>();
|
private Map<String, Downloader> mDownloaderMap = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件信息回调组
|
* 文件信息回调组
|
||||||
*/
|
*/
|
||||||
private SparseArray<FileInfoThread.OnFileInfoCallback> mFileInfoCallbacks = new SparseArray<>();
|
private SparseArray<FileInfoThread.OnFileInfoCallback> mFileInfoCallbacks = new SparseArray<>();
|
||||||
|
|
||||||
DownloadGroupUtil(IDownloadListener listener, DownloadGroupTaskEntity taskEntity) {
|
public DownloadGroupUtil(IDownloadListener listener, DownloadGroupTaskEntity taskEntity) {
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
mTaskEntity = taskEntity;
|
mTaskEntity = taskEntity;
|
||||||
mInfoPool = Executors.newCachedThreadPool();
|
mInfoPool = Executors.newCachedThreadPool();
|
||||||
@ -116,9 +116,9 @@ public class DownloadGroupUtil implements IDownloadUtil {
|
|||||||
|
|
||||||
Set<String> keys = mDownloaderMap.keySet();
|
Set<String> keys = mDownloaderMap.keySet();
|
||||||
for (String key : keys) {
|
for (String key : keys) {
|
||||||
DownloadThreader db = mDownloaderMap.get(key);
|
Downloader dt = mDownloaderMap.get(key);
|
||||||
if (db != null) {
|
if (dt != null) {
|
||||||
db.cancelDownload();
|
dt.cancelDownload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,9 +135,9 @@ public class DownloadGroupUtil implements IDownloadUtil {
|
|||||||
|
|
||||||
Set<String> keys = mDownloaderMap.keySet();
|
Set<String> keys = mDownloaderMap.keySet();
|
||||||
for (String key : keys) {
|
for (String key : keys) {
|
||||||
DownloadThreader db = mDownloaderMap.get(key);
|
Downloader dt = mDownloaderMap.get(key);
|
||||||
if (db != null) {
|
if (dt != null) {
|
||||||
db.stopDownload();
|
dt.stopDownload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -188,7 +188,7 @@ public class DownloadGroupUtil implements IDownloadUtil {
|
|||||||
}
|
}
|
||||||
mFailNum++;
|
mFailNum++;
|
||||||
failNum++;
|
failNum++;
|
||||||
if (failNum < 10){
|
if (failNum < 10) {
|
||||||
mInfoPool.execute(createFileInfoThread(te));
|
mInfoPool.execute(createFileInfoThread(te));
|
||||||
}
|
}
|
||||||
if (mInitNum + mFailNum == mTaskEntity.getEntity().getChild().size()) {
|
if (mInitNum + mFailNum == mTaskEntity.getEntity().getChild().size()) {
|
||||||
@ -228,7 +228,7 @@ public class DownloadGroupUtil implements IDownloadUtil {
|
|||||||
*/
|
*/
|
||||||
private void startChildDownload(DownloadTaskEntity taskEntity) {
|
private void startChildDownload(DownloadTaskEntity taskEntity) {
|
||||||
ChildDownloadListener listener = new ChildDownloadListener(taskEntity);
|
ChildDownloadListener listener = new ChildDownloadListener(taskEntity);
|
||||||
DownloadThreader dt = new DownloadThreader(listener, taskEntity);
|
Downloader dt = new Downloader(listener, taskEntity);
|
||||||
mDownloaderMap.put(taskEntity.getEntity().getDownloadUrl(), dt);
|
mDownloaderMap.put(taskEntity.getEntity().getDownloadUrl(), dt);
|
||||||
mExePool.execute(dt);
|
mExePool.execute(dt);
|
||||||
}
|
}
|
||||||
|
@ -16,23 +16,8 @@
|
|||||||
|
|
||||||
package com.arialyy.aria.core.download.downloader;
|
package com.arialyy.aria.core.download.downloader;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.SparseArray;
|
|
||||||
import com.arialyy.aria.core.AriaManager;
|
|
||||||
import com.arialyy.aria.core.download.DownloadEntity;
|
|
||||||
import com.arialyy.aria.core.download.DownloadTaskEntity;
|
import com.arialyy.aria.core.download.DownloadTaskEntity;
|
||||||
import com.arialyy.aria.orm.DbEntity;
|
|
||||||
import com.arialyy.aria.util.BufferedRandomAccessFile;
|
|
||||||
import com.arialyy.aria.util.CommonUtil;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by lyy on 2015/8/25.
|
* Created by lyy on 2015/8/25.
|
||||||
@ -40,170 +25,49 @@ import java.util.concurrent.Executors;
|
|||||||
*/
|
*/
|
||||||
public class DownloadUtil implements IDownloadUtil, Runnable {
|
public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||||
private static final String TAG = "DownloadUtil";
|
private static final String TAG = "DownloadUtil";
|
||||||
/**
|
|
||||||
* 线程数
|
|
||||||
*/
|
|
||||||
private int THREAD_NUM;
|
|
||||||
/**
|
|
||||||
* 小于1m的文件不启用多线程
|
|
||||||
*/
|
|
||||||
private static final long SUB_LEN = 1024 * 1024;
|
|
||||||
//下载监听
|
|
||||||
private IDownloadListener mListener;
|
private IDownloadListener mListener;
|
||||||
private int mConnectTimeOut = 0; //连接超时时间
|
private Downloader mDT;
|
||||||
private boolean isNewTask = true;
|
|
||||||
private boolean isSupportBreakpoint = true;
|
|
||||||
private Context mContext;
|
|
||||||
private DownloadEntity mDownloadEntity;
|
|
||||||
private DownloadTaskEntity mTaskEntity;
|
private DownloadTaskEntity mTaskEntity;
|
||||||
private ExecutorService mFixedThreadPool;
|
|
||||||
private File mDownloadFile; //下载的文件
|
|
||||||
private File mConfigFile;//下载信息配置文件
|
|
||||||
private SparseArray<Runnable> mTask = new SparseArray<>();
|
|
||||||
private DownloadStateConstance CONSTANCE;
|
|
||||||
|
|
||||||
DownloadUtil(Context context, DownloadTaskEntity entity, IDownloadListener downloadListener) {
|
public DownloadUtil(DownloadTaskEntity entity, IDownloadListener downloadListener) {
|
||||||
mDownloadEntity = entity.getEntity();
|
|
||||||
mContext = context.getApplicationContext();
|
|
||||||
mTaskEntity = entity;
|
mTaskEntity = entity;
|
||||||
mListener = downloadListener;
|
mListener = downloadListener;
|
||||||
// 线程下载数改变后,新的下载才会生效
|
mDT = new Downloader(downloadListener, entity);
|
||||||
//mFixedThreadPool = Executors.newFixedThreadPool(Integer.MAX_VALUE);
|
|
||||||
CONSTANCE = new DownloadStateConstance();
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
mConnectTimeOut = AriaManager.getInstance(mContext).getDownloadConfig().getConnectTimeOut();
|
|
||||||
mDownloadFile = new File(mTaskEntity.getEntity().getDownloadPath());
|
|
||||||
//读取已完成的线程数
|
|
||||||
mConfigFile = new File(mContext.getFilesDir().getPath()
|
|
||||||
+ AriaManager.DOWNLOAD_TEMP_DIR
|
|
||||||
+ mDownloadFile.getName()
|
|
||||||
+ ".properties");
|
|
||||||
checkTask();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查任务是否是新任务,新任务条件:
|
|
||||||
* 1、文件不存在
|
|
||||||
* 2、下载记录文件不存在
|
|
||||||
* 3、下载记录文件缺失或不匹配
|
|
||||||
* 4、数据库记录不存在
|
|
||||||
*/
|
|
||||||
private void checkTask() {
|
|
||||||
try {
|
|
||||||
if (!mConfigFile.exists()) { //记录文件被删除,则重新下载
|
|
||||||
isNewTask = true;
|
|
||||||
CommonUtil.createFile(mConfigFile.getPath());
|
|
||||||
} else if (!mDownloadFile.exists()) {
|
|
||||||
isNewTask = true;
|
|
||||||
} else if (DbEntity.findData(DownloadEntity.class, "downloadUrl=?",
|
|
||||||
mDownloadEntity.getDownloadUrl()) == null) {
|
|
||||||
isNewTask = true;
|
|
||||||
} else {
|
|
||||||
isNewTask = !mDownloadFile.exists();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
failDownload("下载失败,记录文件被删除");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IDownloadListener getListener() {
|
|
||||||
return mListener;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public long getFileSize() {
|
@Override public long getFileSize() {
|
||||||
return mDownloadEntity.getFileSize();
|
return mDT.getFileSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前下载位置
|
* 获取当前下载位置
|
||||||
*/
|
*/
|
||||||
@Override public long getCurrentLocation() {
|
@Override public long getCurrentLocation() {
|
||||||
return CONSTANCE.CURRENT_LOCATION;
|
return mDT.getCurrentLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean isDownloading() {
|
@Override public boolean isDownloading() {
|
||||||
return CONSTANCE.isDownloading;
|
return mDT.isDownloading();
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaxSpeed(double maxSpeed) {
|
|
||||||
for (int i = 0; i < THREAD_NUM; i++) {
|
|
||||||
SingleThreadTask task = (SingleThreadTask) mTask.get(i);
|
|
||||||
if (task != null) {
|
|
||||||
task.setMaxSpeed(maxSpeed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 取消下载
|
* 取消下载
|
||||||
*/
|
*/
|
||||||
@Override public void cancelDownload() {
|
@Override public void cancelDownload() {
|
||||||
CONSTANCE.isCancel = true;
|
mDT.cancelDownload();
|
||||||
CONSTANCE.isDownloading = false;
|
|
||||||
if (mFixedThreadPool != null) {
|
|
||||||
mFixedThreadPool.shutdown();
|
|
||||||
}
|
|
||||||
for (int i = 0; i < THREAD_NUM; i++) {
|
|
||||||
SingleThreadTask task = (SingleThreadTask) mTask.get(i);
|
|
||||||
if (task != null) {
|
|
||||||
task.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CommonUtil.delDownloadTaskConfig(mTaskEntity.removeFile, mDownloadEntity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 停止下载
|
* 停止下载
|
||||||
*/
|
*/
|
||||||
@Override public void stopDownload() {
|
@Override public void stopDownload() {
|
||||||
CONSTANCE.isStop = true;
|
mDT.stopDownload();
|
||||||
CONSTANCE.isDownloading = false;
|
|
||||||
if (mFixedThreadPool != null) {
|
|
||||||
mFixedThreadPool.shutdown();
|
|
||||||
}
|
|
||||||
for (int i = 0; i < THREAD_NUM; i++) {
|
|
||||||
SingleThreadTask task = (SingleThreadTask) mTask.get(i);
|
|
||||||
if (task != null) {
|
|
||||||
task.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除下载记录文件
|
|
||||||
*/
|
|
||||||
public void delConfigFile() {
|
|
||||||
if (mContext != null && mDownloadEntity != null) {
|
|
||||||
File dFile = new File(mDownloadEntity.getDownloadPath());
|
|
||||||
File config =
|
|
||||||
new File(mContext.getFilesDir().getPath() + "/temp/" + dFile.getName() + ".properties");
|
|
||||||
if (config.exists()) {
|
|
||||||
config.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除temp文件
|
|
||||||
*/
|
|
||||||
public void delTempFile() {
|
|
||||||
if (mContext != null && mDownloadEntity != null) {
|
|
||||||
File dFile = new File(mDownloadEntity.getDownloadPath());
|
|
||||||
if (dFile.exists()) {
|
|
||||||
dFile.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 多线程断点续传下载文件,开始下载
|
* 多线程断点续传下载文件,开始下载
|
||||||
*/
|
*/
|
||||||
@Override public void startDownload() {
|
@Override public void startDownload() {
|
||||||
CONSTANCE.cleanState();
|
|
||||||
mListener.onPre();
|
mListener.onPre();
|
||||||
new Thread(this).start();
|
new Thread(this).start();
|
||||||
}
|
}
|
||||||
@ -212,295 +76,24 @@ public class DownloadUtil implements IDownloadUtil, Runnable {
|
|||||||
startDownload();
|
startDownload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setMaxSpeed(double maxSpeed) {
|
||||||
|
mDT.setMaxSpeed(maxSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
private void failDownload(String msg) {
|
private void failDownload(String msg) {
|
||||||
Log.e(TAG, msg);
|
Log.e(TAG, msg);
|
||||||
CONSTANCE.isDownloading = false;
|
|
||||||
mListener.onFail();
|
mListener.onFail();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
HttpURLConnection conn = null;
|
new Thread(new FileInfoThread(mTaskEntity, new FileInfoThread.OnFileInfoCallback() {
|
||||||
try {
|
@Override public void onComplete(String url, int code) {
|
||||||
URL url = new URL(mDownloadEntity.getDownloadUrl());
|
mDT.startDownload();
|
||||||
conn = ConnectionHelp.handleConnection(url);
|
|
||||||
conn = ConnectionHelp.setConnectParam(mTaskEntity, conn);
|
|
||||||
conn.setRequestProperty("Range", "bytes=" + 0 + "-");
|
|
||||||
conn.setConnectTimeout(mConnectTimeOut);
|
|
||||||
conn.connect();
|
|
||||||
handleConnect(conn);
|
|
||||||
} catch (IOException e) {
|
|
||||||
failDownload("下载失败【downloadUrl:"
|
|
||||||
+ mDownloadEntity.getDownloadUrl()
|
|
||||||
+ "】\n【filePath:"
|
|
||||||
+ mDownloadFile.getPath()
|
|
||||||
+ "】\n"
|
|
||||||
+ CommonUtil.getPrintException(e));
|
|
||||||
} finally {
|
|
||||||
if (conn != null) {
|
|
||||||
conn.disconnect();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
@Override public void onFail(String url, String errorMsg) {
|
||||||
* 处理状态码
|
failDownload(errorMsg);
|
||||||
*/
|
|
||||||
private void handleConnect(HttpURLConnection conn) throws IOException {
|
|
||||||
int len = conn.getContentLength();
|
|
||||||
//if (len < 0) { //网络被劫持时会出现这个问题
|
|
||||||
// failDownload("下载失败,网络被劫持");
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
int code = conn.getResponseCode();
|
|
||||||
//https://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81
|
|
||||||
//206支持断点
|
|
||||||
if (code == HttpURLConnection.HTTP_PARTIAL) {
|
|
||||||
if (!checkLen(len)) return;
|
|
||||||
isSupportBreakpoint = true;
|
|
||||||
mListener.supportBreakpoint(true);
|
|
||||||
handleBreakpoint(conn);
|
|
||||||
} else if (code == HttpURLConnection.HTTP_OK) {
|
|
||||||
//在conn.setRequestProperty("Range", "bytes=" + 0 + "-");下,200为不支持断点状态
|
|
||||||
if (!checkLen(len)) return;
|
|
||||||
isSupportBreakpoint = false;
|
|
||||||
mListener.supportBreakpoint(false);
|
|
||||||
Log.w(TAG, "该下载链接不支持断点下载");
|
|
||||||
handleBreakpoint(conn);
|
|
||||||
} else if (code == HttpURLConnection.HTTP_NOT_FOUND) {
|
|
||||||
Log.w(TAG, "任务【" + mDownloadEntity.getDownloadUrl() + "】下载失败,错误码:404");
|
|
||||||
mListener.onCancel();
|
|
||||||
} else if (code == HttpURLConnection.HTTP_MOVED_TEMP
|
|
||||||
|| code == HttpURLConnection.HTTP_MOVED_PERM
|
|
||||||
|| code == HttpURLConnection.HTTP_SEE_OTHER) {
|
|
||||||
handle302Turn(conn);
|
|
||||||
} else {
|
|
||||||
failDownload("任务【" + mDownloadEntity.getDownloadUrl() + "】下载失败,错误码:" + code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查长度是否合法
|
|
||||||
*
|
|
||||||
* @param len 从服务器获取的文件长度
|
|
||||||
* @return true, 合法
|
|
||||||
*/
|
|
||||||
private boolean checkLen(long len) {
|
|
||||||
if (len < 0) {
|
|
||||||
failDownload("任务【" + mDownloadEntity.getDownloadUrl() + "】下载失败,文件长度小于0");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理30x跳转
|
|
||||||
*/
|
|
||||||
private void handle302Turn(HttpURLConnection conn) throws IOException {
|
|
||||||
String newUrl = conn.getHeaderField(mTaskEntity.redirectUrlKey);
|
|
||||||
Log.d(TAG, "30x跳转,新url为【" + newUrl + "】");
|
|
||||||
mDownloadEntity.setRedirect(true);
|
|
||||||
mDownloadEntity.setRedirectUrl(newUrl);
|
|
||||||
mDownloadEntity.update();
|
|
||||||
String cookies = conn.getHeaderField("Set-Cookie");
|
|
||||||
conn = (HttpURLConnection) new URL(newUrl).openConnection();
|
|
||||||
conn = ConnectionHelp.setConnectParam(mTaskEntity, conn);
|
|
||||||
conn.setRequestProperty("Cookie", cookies);
|
|
||||||
conn.setRequestProperty("Range", "bytes=" + 0 + "-");
|
|
||||||
conn.setConnectTimeout(mConnectTimeOut);
|
|
||||||
conn.connect();
|
|
||||||
handleConnect(conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理断点
|
|
||||||
*/
|
|
||||||
private void handleBreakpoint(HttpURLConnection conn) throws IOException {
|
|
||||||
//不支持断点只能单线程下载
|
|
||||||
if (!isSupportBreakpoint) {
|
|
||||||
handleNoSupportBreakpointDownload(conn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int fileLength = conn.getContentLength();
|
|
||||||
Properties pro = createConfigFile(fileLength);
|
|
||||||
int blockSize = fileLength / THREAD_NUM;
|
|
||||||
int[] recordL = new int[THREAD_NUM];
|
|
||||||
int rl = 0;
|
|
||||||
for (int i = 0; i < THREAD_NUM; i++) {
|
|
||||||
recordL[i] = -1;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < THREAD_NUM; i++) {
|
|
||||||
long startL = i * blockSize, endL = (i + 1) * blockSize;
|
|
||||||
Object state = pro.getProperty(mDownloadFile.getName() + "_state_" + i);
|
|
||||||
if (state != null && Integer.parseInt(state + "") == 1) { //该线程已经完成
|
|
||||||
if (resumeRecordLocation(i, startL, endL)) return;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
//分配下载位置
|
})).start();
|
||||||
Object record = pro.getProperty(mDownloadFile.getName() + "_record_" + i);
|
|
||||||
//如果有记录,则恢复下载
|
|
||||||
if (!isNewTask && record != null && Long.parseLong(record + "") >= 0) {
|
|
||||||
Long r = Long.parseLong(record + "");
|
|
||||||
CONSTANCE.CURRENT_LOCATION += r - startL;
|
|
||||||
Log.d(TAG, "任务【" + mDownloadEntity.getFileName() + "】线程__" + i + "__恢复下载");
|
|
||||||
mListener.onChildResume(r);
|
|
||||||
startL = r;
|
|
||||||
recordL[rl] = i;
|
|
||||||
rl++;
|
|
||||||
} else {
|
|
||||||
//handleNewTask(fileLength);
|
|
||||||
isNewTask = true;
|
|
||||||
}
|
|
||||||
if (isNewTask) {
|
|
||||||
recordL[rl] = i;
|
|
||||||
rl++;
|
|
||||||
}
|
|
||||||
if (i == (THREAD_NUM - 1)) {
|
|
||||||
//最后一个线程的结束位置即为文件的总长度
|
|
||||||
endL = fileLength;
|
|
||||||
}
|
|
||||||
addSingleTask(i, startL, endL, fileLength);
|
|
||||||
}
|
|
||||||
startSingleTask(recordL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理不支持断点的下载
|
|
||||||
*/
|
|
||||||
private void handleNoSupportBreakpointDownload(HttpURLConnection conn) {
|
|
||||||
ChildThreadConfigEntity entity = new ChildThreadConfigEntity();
|
|
||||||
long len = conn.getContentLength();
|
|
||||||
entity.FILE_SIZE = len;
|
|
||||||
entity.DOWNLOAD_URL = mDownloadEntity.isRedirect() ? mDownloadEntity.getRedirectUrl()
|
|
||||||
: mDownloadEntity.getDownloadUrl();
|
|
||||||
entity.TEMP_FILE = mDownloadFile;
|
|
||||||
entity.THREAD_ID = 0;
|
|
||||||
entity.START_LOCATION = 0;
|
|
||||||
entity.END_LOCATION = entity.FILE_SIZE;
|
|
||||||
entity.CONFIG_FILE_PATH = mConfigFile.getPath();
|
|
||||||
entity.IS_SUPPORT_BREAK_POINT = isSupportBreakpoint;
|
|
||||||
entity.DOWNLOAD_TASK_ENTITY = mTaskEntity;
|
|
||||||
THREAD_NUM = 1;
|
|
||||||
CONSTANCE.THREAD_NUM = THREAD_NUM;
|
|
||||||
SingleThreadTask task = new SingleThreadTask(CONSTANCE, mListener, entity);
|
|
||||||
mTask.put(0, task);
|
|
||||||
mFixedThreadPool.execute(task);
|
|
||||||
mListener.onPostPre(len);
|
|
||||||
mListener.onStart(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建配置文件
|
|
||||||
*/
|
|
||||||
private Properties createConfigFile(long fileLength) throws IOException {
|
|
||||||
Properties pro = null;
|
|
||||||
//必须建一个文件
|
|
||||||
CommonUtil.createFile(mDownloadFile.getPath());
|
|
||||||
BufferedRandomAccessFile file =
|
|
||||||
new BufferedRandomAccessFile(new File(mDownloadFile.getPath()), "rwd", 8192);
|
|
||||||
//设置文件长度
|
|
||||||
file.setLength(fileLength);
|
|
||||||
file.close();
|
|
||||||
mListener.onPostPre(fileLength);
|
|
||||||
//分配每条线程的下载区间
|
|
||||||
pro = CommonUtil.loadConfig(mConfigFile);
|
|
||||||
if (pro.isEmpty()) {
|
|
||||||
handleNewTask(fileLength);
|
|
||||||
} else {
|
|
||||||
Set<Object> keys = pro.keySet();
|
|
||||||
int num = 0;
|
|
||||||
for (Object key : keys) {
|
|
||||||
if (String.valueOf(key).contains("_record_")) {
|
|
||||||
num++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (num == 0) {
|
|
||||||
handleNewTask(fileLength);
|
|
||||||
return pro;
|
|
||||||
}
|
|
||||||
THREAD_NUM = num;
|
|
||||||
for (int i = 0; i < THREAD_NUM; i++) {
|
|
||||||
if (pro.getProperty(mDownloadFile.getName() + "_record_" + i) == null) {
|
|
||||||
Object state = pro.getProperty(mDownloadFile.getName() + "_state_" + i);
|
|
||||||
if (state != null && Integer.parseInt(state + "") == 1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
handleNewTask(fileLength);
|
|
||||||
return pro;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
isNewTask = false;
|
|
||||||
}
|
|
||||||
return pro;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理新任务
|
|
||||||
*/
|
|
||||||
private void handleNewTask(long fileLength) {
|
|
||||||
isNewTask = true;
|
|
||||||
THREAD_NUM = fileLength < SUB_LEN ? 1
|
|
||||||
: AriaManager.getInstance(mContext).getDownloadConfig().getThreadNum();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 恢复记录地址
|
|
||||||
*
|
|
||||||
* @return true 表示下载完成
|
|
||||||
*/
|
|
||||||
private boolean resumeRecordLocation(int i, long startL, long endL) {
|
|
||||||
CONSTANCE.CURRENT_LOCATION += endL - startL;
|
|
||||||
Log.d(TAG, "++++++++++ 线程_" + i + "_已经下载完成 ++++++++++");
|
|
||||||
CONSTANCE.COMPLETE_THREAD_NUM++;
|
|
||||||
CONSTANCE.STOP_NUM++;
|
|
||||||
CONSTANCE.CANCEL_NUM++;
|
|
||||||
if (CONSTANCE.isComplete()) {
|
|
||||||
if (mConfigFile.exists()) {
|
|
||||||
mConfigFile.delete();
|
|
||||||
}
|
|
||||||
mListener.onComplete();
|
|
||||||
CONSTANCE.isDownloading = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建单线程任务
|
|
||||||
*/
|
|
||||||
private void addSingleTask(int i, long startL, long endL, long fileLength) {
|
|
||||||
ChildThreadConfigEntity entity = new ChildThreadConfigEntity();
|
|
||||||
entity.FILE_SIZE = fileLength;
|
|
||||||
entity.DOWNLOAD_URL = mDownloadEntity.isRedirect() ? mDownloadEntity.getRedirectUrl()
|
|
||||||
: mDownloadEntity.getDownloadUrl();
|
|
||||||
entity.TEMP_FILE = mDownloadFile;
|
|
||||||
entity.THREAD_ID = i;
|
|
||||||
entity.START_LOCATION = startL;
|
|
||||||
entity.END_LOCATION = endL;
|
|
||||||
entity.CONFIG_FILE_PATH = mConfigFile.getPath();
|
|
||||||
entity.IS_SUPPORT_BREAK_POINT = isSupportBreakpoint;
|
|
||||||
entity.DOWNLOAD_TASK_ENTITY = mTaskEntity;
|
|
||||||
CONSTANCE.THREAD_NUM = THREAD_NUM;
|
|
||||||
SingleThreadTask task = new SingleThreadTask(CONSTANCE, mListener, entity);
|
|
||||||
mTask.put(i, task);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 启动单线程下载任务
|
|
||||||
*/
|
|
||||||
private void startSingleTask(int[] recordL) {
|
|
||||||
if (CONSTANCE.CURRENT_LOCATION > 0) {
|
|
||||||
mListener.onResume(CONSTANCE.CURRENT_LOCATION);
|
|
||||||
} 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.execute(task);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -33,9 +33,10 @@ import java.util.concurrent.Executors;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by AriaL on 2017/7/1.
|
* Created by AriaL on 2017/7/1.
|
||||||
|
* 文件下载器
|
||||||
*/
|
*/
|
||||||
class DownloadThreader implements Runnable, IDownloadUtil {
|
class Downloader implements Runnable, IDownloadUtil {
|
||||||
private final String TAG = "DownloadThreader";
|
private final String TAG = "Downloader";
|
||||||
private IDownloadListener mListener;
|
private IDownloadListener mListener;
|
||||||
private DownloadTaskEntity mTaskEntity;
|
private DownloadTaskEntity mTaskEntity;
|
||||||
private DownloadEntity mEntity;
|
private DownloadEntity mEntity;
|
||||||
@ -45,15 +46,33 @@ class DownloadThreader implements Runnable, IDownloadUtil {
|
|||||||
private File mTempFile; //下载的文件
|
private File mTempFile; //下载的文件
|
||||||
private boolean isNewTask = true;
|
private boolean isNewTask = true;
|
||||||
private int mThreadNum, mRealThreadNum;
|
private int mThreadNum, mRealThreadNum;
|
||||||
private DownloadStateConstance mConstance;
|
private StateConstance mConstance;
|
||||||
private SparseArray<Runnable> mTask = new SparseArray<>();
|
private SparseArray<Runnable> mTask = new SparseArray<>();
|
||||||
|
|
||||||
DownloadThreader(IDownloadListener listener, DownloadTaskEntity taskEntity) {
|
/**
|
||||||
|
* 小于1m的文件不启用多线程
|
||||||
|
*/
|
||||||
|
private static final long SUB_LEN = 1024 * 1024;
|
||||||
|
|
||||||
|
Downloader(IDownloadListener listener, DownloadTaskEntity taskEntity) {
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
mTaskEntity = taskEntity;
|
mTaskEntity = taskEntity;
|
||||||
mEntity = mTaskEntity.getEntity();
|
mEntity = mTaskEntity.getEntity();
|
||||||
mContext = AriaManager.APP;
|
mContext = AriaManager.APP;
|
||||||
mConstance = new DownloadStateConstance();
|
mConstance = new StateConstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMaxSpeed(double maxSpeed) {
|
||||||
|
for (int i = 0; i < mThreadNum; i++) {
|
||||||
|
SingleThreadTask task = (SingleThreadTask) mTask.get(i);
|
||||||
|
if (task != null) {
|
||||||
|
task.setMaxSpeed(maxSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public StateConstance getConstance() {
|
||||||
|
return mConstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
@ -106,15 +125,16 @@ class DownloadThreader implements Runnable, IDownloadUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public void startDownload() {
|
@Override public void startDownload() {
|
||||||
|
mConstance.cleanState();
|
||||||
mConstance.isDownloading = true;
|
mConstance.isDownloading = true;
|
||||||
try {
|
try {
|
||||||
if (!mTaskEntity.isSupportBP) {
|
if (!mTaskEntity.isSupportBP) {
|
||||||
mThreadNum = 1;
|
mThreadNum = 1;
|
||||||
handleNoSupportBreakpointDownload();
|
handleNoSupportBreakpointDownload();
|
||||||
} else {
|
} else {
|
||||||
mThreadNum =
|
mThreadNum = isNewTask ? (mEntity.getFileSize() <= SUB_LEN ? 1
|
||||||
isNewTask ? AriaManager.getInstance(mContext).getDownloadConfig().getThreadNum()
|
: AriaManager.getInstance(mContext).getDownloadConfig().getThreadNum())
|
||||||
: mRealThreadNum;
|
: mRealThreadNum;
|
||||||
mFixedThreadPool = Executors.newFixedThreadPool(mThreadNum);
|
mFixedThreadPool = Executors.newFixedThreadPool(mThreadNum);
|
||||||
handleBreakpoint();
|
handleBreakpoint();
|
||||||
}
|
}
|
@ -19,7 +19,7 @@ package com.arialyy.aria.core.download.downloader;
|
|||||||
/**
|
/**
|
||||||
* 下载监听
|
* 下载监听
|
||||||
*/
|
*/
|
||||||
interface IDownloadListener {
|
public interface IDownloadListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支持断点回调
|
* 支持断点回调
|
||||||
|
@ -20,7 +20,7 @@ package com.arialyy.aria.core.download.downloader;
|
|||||||
* Created by lyy on 2016/10/31.
|
* Created by lyy on 2016/10/31.
|
||||||
* 抽象的下载接口
|
* 抽象的下载接口
|
||||||
*/
|
*/
|
||||||
interface IDownloadUtil {
|
public interface IDownloadUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取文件大小
|
* 获取文件大小
|
||||||
|
@ -41,10 +41,10 @@ final class SingleThreadTask implements Runnable {
|
|||||||
private long mChildCurrentLocation = 0;
|
private long mChildCurrentLocation = 0;
|
||||||
private int mBufSize;
|
private int mBufSize;
|
||||||
private IDownloadListener mListener;
|
private IDownloadListener mListener;
|
||||||
private DownloadStateConstance CONSTANCE;
|
private StateConstance CONSTANCE;
|
||||||
private long mSleepTime = 0;
|
private long mSleepTime = 0;
|
||||||
|
|
||||||
SingleThreadTask(DownloadStateConstance constance, IDownloadListener listener,
|
SingleThreadTask(StateConstance constance, IDownloadListener listener,
|
||||||
ChildThreadConfigEntity downloadInfo) {
|
ChildThreadConfigEntity downloadInfo) {
|
||||||
AriaManager manager = AriaManager.getInstance(AriaManager.APP);
|
AriaManager manager = AriaManager.getInstance(AriaManager.APP);
|
||||||
CONSTANCE = constance;
|
CONSTANCE = constance;
|
||||||
|
@ -19,7 +19,7 @@ package com.arialyy.aria.core.download.downloader;
|
|||||||
* Created by lyy on 2017/1/18.
|
* Created by lyy on 2017/1/18.
|
||||||
* 下载状态常量
|
* 下载状态常量
|
||||||
*/
|
*/
|
||||||
final class DownloadStateConstance {
|
final class StateConstance {
|
||||||
int CANCEL_NUM = 0;
|
int CANCEL_NUM = 0;
|
||||||
int STOP_NUM = 0;
|
int STOP_NUM = 0;
|
||||||
int FAIL_NUM = 0;
|
int FAIL_NUM = 0;
|
||||||
@ -32,7 +32,7 @@ final class DownloadStateConstance {
|
|||||||
boolean isCancel = false;
|
boolean isCancel = false;
|
||||||
boolean isStop = false;
|
boolean isStop = false;
|
||||||
|
|
||||||
DownloadStateConstance() {
|
StateConstance() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanState() {
|
void cleanState() {
|
@ -32,6 +32,10 @@ public abstract class AbsEntity extends DbEntity implements IEntity, Parcelable
|
|||||||
* 单位转换后的速度
|
* 单位转换后的速度
|
||||||
*/
|
*/
|
||||||
@Ignore private String convertSpeed = "0b/s";
|
@Ignore private String convertSpeed = "0b/s";
|
||||||
|
/**
|
||||||
|
* 下载失败计数,每次开始都重置为0
|
||||||
|
*/
|
||||||
|
@Ignore private int failNum = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扩展字段
|
* 扩展字段
|
||||||
@ -51,6 +55,14 @@ public abstract class AbsEntity extends DbEntity implements IEntity, Parcelable
|
|||||||
*/
|
*/
|
||||||
private long completeTime;
|
private long completeTime;
|
||||||
|
|
||||||
|
public int getFailNum() {
|
||||||
|
return failNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFailNum(int failNum) {
|
||||||
|
this.failNum = failNum;
|
||||||
|
}
|
||||||
|
|
||||||
public long getSpeed() {
|
public long getSpeed() {
|
||||||
return speed;
|
return speed;
|
||||||
}
|
}
|
||||||
@ -117,6 +129,7 @@ public abstract class AbsEntity extends DbEntity implements IEntity, Parcelable
|
|||||||
@Override public void writeToParcel(Parcel dest, int flags) {
|
@Override public void writeToParcel(Parcel dest, int flags) {
|
||||||
dest.writeLong(this.speed);
|
dest.writeLong(this.speed);
|
||||||
dest.writeString(this.convertSpeed);
|
dest.writeString(this.convertSpeed);
|
||||||
|
dest.writeInt(this.failNum);
|
||||||
dest.writeString(this.str);
|
dest.writeString(this.str);
|
||||||
dest.writeLong(this.fileSize);
|
dest.writeLong(this.fileSize);
|
||||||
dest.writeInt(this.state);
|
dest.writeInt(this.state);
|
||||||
@ -127,6 +140,7 @@ public abstract class AbsEntity extends DbEntity implements IEntity, Parcelable
|
|||||||
protected AbsEntity(Parcel in) {
|
protected AbsEntity(Parcel in) {
|
||||||
this.speed = in.readLong();
|
this.speed = in.readLong();
|
||||||
this.convertSpeed = in.readString();
|
this.convertSpeed = in.readString();
|
||||||
|
this.failNum = in.readInt();
|
||||||
this.str = in.readString();
|
this.str = in.readString();
|
||||||
this.fileSize = in.readLong();
|
this.fileSize = in.readLong();
|
||||||
this.state = in.readInt();
|
this.state = in.readInt();
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.arialyy.aria.core.inf;
|
package com.arialyy.aria.core.inf;
|
||||||
|
|
||||||
import com.arialyy.aria.util.CommonUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by AriaL on 2017/6/29.
|
* Created by AriaL on 2017/6/29.
|
||||||
@ -25,47 +24,8 @@ public abstract class AbsGroupTask<TASK_ENTITY extends AbsTaskEntity, ENTITY ext
|
|||||||
|
|
||||||
protected TASK_ENTITY mTaskEntity;
|
protected TASK_ENTITY mTaskEntity;
|
||||||
|
|
||||||
@Override public int getPercent() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public long getFileSize() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public String getConvertFileSize() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public long getCurrentProgress() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public String getConvertCurrentProgress() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public int getState() {
|
|
||||||
return mEntity.getState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public String getExtendField() {
|
|
||||||
return mEntity.getStr();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public String getKey() {
|
@Override public String getKey() {
|
||||||
return mEntity.getGroupName();
|
return mEntity.getGroupName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean isRunning() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public ENTITY getEntity() {
|
|
||||||
return mEntity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void removeRecord() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -24,10 +24,7 @@ import com.arialyy.aria.orm.Ignore;
|
|||||||
* Created by AriaL on 2017/6/3.
|
* Created by AriaL on 2017/6/3.
|
||||||
*/
|
*/
|
||||||
public abstract class AbsNormalEntity extends AbsEntity implements Parcelable {
|
public abstract class AbsNormalEntity extends AbsEntity implements Parcelable {
|
||||||
/**
|
|
||||||
* 下载失败计数,每次开始都重置为0
|
|
||||||
*/
|
|
||||||
@Ignore private int failNum = 0;
|
|
||||||
/**
|
/**
|
||||||
* 文件名
|
* 文件名
|
||||||
*/
|
*/
|
||||||
@ -46,14 +43,6 @@ public abstract class AbsNormalEntity extends AbsEntity implements Parcelable {
|
|||||||
isGroupChild = groupChild;
|
isGroupChild = groupChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getFailNum() {
|
|
||||||
return failNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFailNum(int failNum) {
|
|
||||||
this.failNum = failNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFileName() {
|
public String getFileName() {
|
||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
@ -71,14 +60,12 @@ public abstract class AbsNormalEntity extends AbsEntity implements Parcelable {
|
|||||||
|
|
||||||
@Override public void writeToParcel(Parcel dest, int flags) {
|
@Override public void writeToParcel(Parcel dest, int flags) {
|
||||||
super.writeToParcel(dest, flags);
|
super.writeToParcel(dest, flags);
|
||||||
dest.writeInt(this.failNum);
|
|
||||||
dest.writeString(this.fileName);
|
dest.writeString(this.fileName);
|
||||||
dest.writeByte(this.isGroupChild ? (byte) 1 : (byte) 0);
|
dest.writeByte(this.isGroupChild ? (byte) 1 : (byte) 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AbsNormalEntity(Parcel in) {
|
protected AbsNormalEntity(Parcel in) {
|
||||||
super(in);
|
super(in);
|
||||||
this.failNum = in.readInt();
|
|
||||||
this.fileName = in.readString();
|
this.fileName = in.readString();
|
||||||
this.isGroupChild = in.readByte() != 0;
|
this.isGroupChild = in.readByte() != 0;
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ public abstract class AbsNormalTarget<TARGET extends AbsNormalTarget, ENTITY ext
|
|||||||
*
|
*
|
||||||
* @see #stop()
|
* @see #stop()
|
||||||
*/
|
*/
|
||||||
@Deprecated protected void pause() {
|
@Deprecated public void pause() {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.arialyy.aria.core.inf;
|
package com.arialyy.aria.core.inf;
|
||||||
|
|
||||||
import com.arialyy.aria.util.CommonUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by lyy on 2017/6/3.
|
* Created by lyy on 2017/6/3.
|
||||||
*/
|
*/
|
||||||
@ -47,54 +45,4 @@ public abstract class AbsNormalTask<ENTITY extends AbsEntity> extends AbsTask<EN
|
|||||||
public boolean isHighestPriorityTask() {
|
public boolean isHighestPriorityTask() {
|
||||||
return isHeighestTask;
|
return isHeighestTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取百分比进度
|
|
||||||
*
|
|
||||||
* @return 返回百分比进度,如果文件长度为0,返回0
|
|
||||||
*/
|
|
||||||
@Override public int getPercent() {
|
|
||||||
if (mEntity.getFileSize() == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return (int) (mEntity.getCurrentProgress() * 100 / mEntity.getFileSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取文件大小
|
|
||||||
*/
|
|
||||||
@Override public long getFileSize() {
|
|
||||||
return mEntity.getFileSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 转换单位后的文件长度
|
|
||||||
*
|
|
||||||
* @return 如果文件长度为0,则返回0m,否则返回转换后的长度1b、1kb、1mb、1gb、1tb
|
|
||||||
*/
|
|
||||||
@Override public String getConvertFileSize() {
|
|
||||||
if (mEntity.getFileSize() == 0) {
|
|
||||||
return "0mb";
|
|
||||||
}
|
|
||||||
return CommonUtil.formatFileSize(mEntity.getFileSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取当前下载进度
|
|
||||||
*/
|
|
||||||
@Override public long getCurrentProgress() {
|
|
||||||
return mEntity.getCurrentProgress();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取单位转换后的进度
|
|
||||||
*
|
|
||||||
* @return 如:已经下载3mb的大小,则返回{@code 3mb}
|
|
||||||
*/
|
|
||||||
@Override public String getConvertCurrentProgress() {
|
|
||||||
if (mEntity.getCurrentProgress() == 0) {
|
|
||||||
return "0b";
|
|
||||||
}
|
|
||||||
return CommonUtil.formatFileSize(mEntity.getCurrentProgress());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ package com.arialyy.aria.core.inf;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import com.arialyy.aria.util.CommonUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by AriaL on 2017/6/29.
|
* Created by AriaL on 2017/6/29.
|
||||||
@ -32,6 +33,56 @@ public abstract class AbsTask<ENTITY extends AbsEntity> implements ITask<ENTITY>
|
|||||||
private String mTargetName;
|
private String mTargetName;
|
||||||
protected Context mContext;
|
protected Context mContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前下载进度
|
||||||
|
*/
|
||||||
|
@Override public long getCurrentProgress() {
|
||||||
|
return mEntity.getCurrentProgress();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取单位转换后的进度
|
||||||
|
*
|
||||||
|
* @return 如:已经下载3mb的大小,则返回{@code 3mb}
|
||||||
|
*/
|
||||||
|
@Override public String getConvertCurrentProgress() {
|
||||||
|
if (mEntity.getCurrentProgress() == 0) {
|
||||||
|
return "0b";
|
||||||
|
}
|
||||||
|
return CommonUtil.formatFileSize(mEntity.getCurrentProgress());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换单位后的文件长度
|
||||||
|
*
|
||||||
|
* @return 如果文件长度为0,则返回0m,否则返回转换后的长度1b、1kb、1mb、1gb、1tb
|
||||||
|
*/
|
||||||
|
@Override public String getConvertFileSize() {
|
||||||
|
if (mEntity.getFileSize() == 0) {
|
||||||
|
return "0mb";
|
||||||
|
}
|
||||||
|
return CommonUtil.formatFileSize(mEntity.getFileSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件大小
|
||||||
|
*/
|
||||||
|
@Override public long getFileSize() {
|
||||||
|
return mEntity.getFileSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取百分比进度
|
||||||
|
*
|
||||||
|
* @return 返回百分比进度,如果文件长度为0,返回0
|
||||||
|
*/
|
||||||
|
@Override public int getPercent() {
|
||||||
|
if (mEntity.getFileSize() == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (int) (mEntity.getCurrentProgress() * 100 / mEntity.getFileSize());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 任务当前状态
|
* 任务当前状态
|
||||||
*
|
*
|
||||||
@ -96,13 +147,6 @@ public abstract class AbsTask<ENTITY extends AbsEntity> implements ITask<ENTITY>
|
|||||||
return mEntity;
|
return mEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除任务记录,删除后,再次启动该任务的下载时,将重新下载
|
|
||||||
*/
|
|
||||||
@Override public void removeRecord() {
|
|
||||||
mEntity.deleteData();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTargetName() {
|
public String getTargetName() {
|
||||||
return mTargetName;
|
return mTargetName;
|
||||||
}
|
}
|
||||||
|
@ -92,5 +92,4 @@ public interface ITask<ENTITY extends AbsEntity> {
|
|||||||
|
|
||||||
public void setTargetName(String targetName);
|
public void setTargetName(String targetName);
|
||||||
|
|
||||||
public void removeRecord();
|
|
||||||
}
|
}
|
||||||
|
@ -18,22 +18,25 @@ package com.arialyy.aria.core.queue;
|
|||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import com.arialyy.aria.core.AriaManager;
|
import com.arialyy.aria.core.AriaManager;
|
||||||
import com.arialyy.aria.core.inf.AbsNormalEntity;
|
import com.arialyy.aria.core.download.DownloadEntity;
|
||||||
import com.arialyy.aria.core.inf.AbsNormalTask;
|
import com.arialyy.aria.core.download.DownloadTask;
|
||||||
|
import com.arialyy.aria.core.inf.AbsEntity;
|
||||||
|
import com.arialyy.aria.core.inf.AbsTask;
|
||||||
import com.arialyy.aria.core.inf.AbsTaskEntity;
|
import com.arialyy.aria.core.inf.AbsTaskEntity;
|
||||||
import com.arialyy.aria.core.queue.pool.NormalCachePool;
|
import com.arialyy.aria.core.inf.IEntity;
|
||||||
import com.arialyy.aria.core.queue.pool.NormalExecutePool;
|
import com.arialyy.aria.core.queue.pool.BaseCachePool;
|
||||||
|
import com.arialyy.aria.core.queue.pool.BaseExecutePool;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by lyy on 2017/2/23.
|
* Created by lyy on 2017/2/23.
|
||||||
* 任务队列
|
* 任务队列
|
||||||
*/
|
*/
|
||||||
abstract class AbsTaskQueue<TASK extends AbsNormalTask, TASK_ENTITY extends AbsTaskEntity, ENTITY extends AbsNormalEntity>
|
abstract class AbsTaskQueue<TASK extends AbsTask, TASK_ENTITY extends AbsTaskEntity, ENTITY extends AbsEntity>
|
||||||
implements ITaskQueue<TASK, TASK_ENTITY, ENTITY> {
|
implements ITaskQueue<TASK, TASK_ENTITY, ENTITY> {
|
||||||
private final String TAG = "AbsTaskQueue";
|
private final String TAG = "AbsTaskQueue";
|
||||||
NormalCachePool<TASK> mCachePool = new NormalCachePool<>();
|
BaseCachePool<TASK> mCachePool = new BaseCachePool<>();
|
||||||
NormalExecutePool<TASK> mExecutePool;
|
BaseExecutePool<TASK> mExecutePool;
|
||||||
|
|
||||||
@Override public boolean taskIsRunning(String key) {
|
@Override public boolean taskIsRunning(String key) {
|
||||||
return mExecutePool.getTask(key) != null;
|
return mExecutePool.getTask(key) != null;
|
||||||
@ -70,17 +73,27 @@ abstract class AbsTaskQueue<TASK extends AbsNormalTask, TASK_ENTITY extends AbsT
|
|||||||
return AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getMaxTaskNum();
|
return AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getMaxTaskNum();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取实体的索引
|
||||||
|
*/
|
||||||
|
public abstract String getKey(ENTITY entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取配置文件配置的最大可执行任务数
|
||||||
|
*/
|
||||||
|
public abstract int getConfigMaxNum();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取任务执行池
|
* 获取任务执行池
|
||||||
*/
|
*/
|
||||||
public NormalExecutePool getExecutePool() {
|
public BaseExecutePool getExecutePool() {
|
||||||
return mExecutePool;
|
return mExecutePool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取缓存池
|
* 获取缓存池
|
||||||
*/
|
*/
|
||||||
public NormalCachePool getCachePool() {
|
public BaseCachePool getCachePool() {
|
||||||
return mCachePool;
|
return mCachePool;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,8 +115,31 @@ abstract class AbsTaskQueue<TASK extends AbsNormalTask, TASK_ENTITY extends AbsT
|
|||||||
return mExecutePool.size();
|
return mExecutePool.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void setTaskHighestPriority(TASK task) {
|
@Override public void setMaxTaskNum(int downloadNum) {
|
||||||
|
int oldMaxSize = getConfigMaxNum();
|
||||||
|
int diff = downloadNum - oldMaxSize;
|
||||||
|
if (oldMaxSize == downloadNum) {
|
||||||
|
Log.d(TAG, "设置的下载任务数和配置文件的下载任务数一直,跳过");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//设置的任务数小于配置任务数
|
||||||
|
if (diff <= -1 && mExecutePool.size() >= oldMaxSize) {
|
||||||
|
for (int i = 0, len = Math.abs(diff); i < len; i++) {
|
||||||
|
TASK eTask = mExecutePool.pollTask();
|
||||||
|
if (eTask != null) {
|
||||||
|
stopTask(eTask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mExecutePool.setMaxNum(downloadNum);
|
||||||
|
if (diff >= 1) {
|
||||||
|
for (int i = 0; i < diff; i++) {
|
||||||
|
TASK nextTask = getNextTask();
|
||||||
|
if (nextTask != null && nextTask.getState() == IEntity.STATE_WAIT) {
|
||||||
|
startTask(nextTask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public TASK getTask(String url) {
|
@Override public TASK getTask(String url) {
|
||||||
@ -124,7 +160,6 @@ abstract class AbsTaskQueue<TASK extends AbsNormalTask, TASK_ENTITY extends AbsT
|
|||||||
|
|
||||||
@Override public void stopTask(TASK task) {
|
@Override public void stopTask(TASK task) {
|
||||||
if (!task.isRunning()) Log.w(TAG, "停止任务失败,【任务已经停止】");
|
if (!task.isRunning()) Log.w(TAG, "停止任务失败,【任务已经停止】");
|
||||||
task.setHighestPriority(false);
|
|
||||||
if (mExecutePool.removeTask(task)) {
|
if (mExecutePool.removeTask(task)) {
|
||||||
task.stop();
|
task.stop();
|
||||||
} else {
|
} else {
|
||||||
@ -133,6 +168,17 @@ abstract class AbsTaskQueue<TASK extends AbsNormalTask, TASK_ENTITY extends AbsT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public void removeTask(ENTITY entity) {
|
||||||
|
TASK task = mExecutePool.getTask(getKey(entity));
|
||||||
|
if (task != null) {
|
||||||
|
Log.d(TAG, "从执行池删除任务,删除" + (mExecutePool.removeTask(task) ? "成功" : "失败"));
|
||||||
|
}
|
||||||
|
task = mCachePool.getTask(getKey(entity));
|
||||||
|
if (task != null) {
|
||||||
|
Log.d(TAG, "从缓存池删除任务,删除" + (mCachePool.removeTask(task) ? "成功" : "失败"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override public void reTryStart(TASK task) {
|
@Override public void reTryStart(TASK task) {
|
||||||
if (task == null) {
|
if (task == null) {
|
||||||
Log.w(TAG, "重试下载失败,task 为null");
|
Log.w(TAG, "重试下载失败,task 为null");
|
||||||
@ -145,6 +191,10 @@ abstract class AbsTaskQueue<TASK extends AbsNormalTask, TASK_ENTITY extends AbsT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public TASK getTask(ENTITY entity) {
|
||||||
|
return getTask(getKey(entity));
|
||||||
|
}
|
||||||
|
|
||||||
@Override public void removeTask(TASK task) {
|
@Override public void removeTask(TASK task) {
|
||||||
task.cancel();
|
task.cancel();
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,55 @@
|
|||||||
|
|
||||||
package com.arialyy.aria.core.queue;
|
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.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.DownloadGroupSchedulers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by AriaL on 2017/6/29.
|
* Created by AriaL on 2017/6/29.
|
||||||
* 任务组下载队列
|
* 任务组下载队列
|
||||||
*/
|
*/
|
||||||
public class DownloadGroupTaskQueue {
|
public class DownloadGroupTaskQueue
|
||||||
|
extends AbsTaskQueue<DownloadGroupTask, DownloadGroupTaskEntity, DownloadGroupEntity> {
|
||||||
|
private static volatile DownloadGroupTaskQueue INSTANCE = null;
|
||||||
|
|
||||||
|
private final String TAG = "DownloadGroupTaskQueue";
|
||||||
|
|
||||||
|
public static DownloadGroupTaskQueue getInstance() {
|
||||||
|
if (INSTANCE == null) {
|
||||||
|
synchronized (AriaManager.LOCK) {
|
||||||
|
INSTANCE = new DownloadGroupTaskQueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DownloadGroupTaskQueue() {
|
||||||
|
mExecutePool = new BaseExecutePool<>(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public DownloadGroupTask createTask(String targetName, DownloadGroupTaskEntity entity) {
|
||||||
|
DownloadGroupTask task = null;
|
||||||
|
if (!TextUtils.isEmpty(targetName)) {
|
||||||
|
task = (DownloadGroupTask) TaskFactory.getInstance()
|
||||||
|
.createTask(targetName, entity, DownloadGroupSchedulers.getInstance());
|
||||||
|
mCachePool.putTask(task);
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "target name 为 null!!");
|
||||||
|
}
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public String getKey(DownloadGroupEntity entity) {
|
||||||
|
return entity.getGroupName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getConfigMaxNum() {
|
||||||
|
return AriaManager.getInstance(AriaManager.APP).getDownloadConfig().oldMaxTaskNum;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,7 @@ import com.arialyy.aria.core.AriaManager;
|
|||||||
import com.arialyy.aria.core.download.DownloadEntity;
|
import com.arialyy.aria.core.download.DownloadEntity;
|
||||||
import com.arialyy.aria.core.download.DownloadTask;
|
import com.arialyy.aria.core.download.DownloadTask;
|
||||||
import com.arialyy.aria.core.download.DownloadTaskEntity;
|
import com.arialyy.aria.core.download.DownloadTaskEntity;
|
||||||
import com.arialyy.aria.core.inf.IEntity;
|
import com.arialyy.aria.core.queue.pool.DownloadExecutePool;
|
||||||
import com.arialyy.aria.core.queue.pool.NormalExecutePool;
|
|
||||||
import com.arialyy.aria.core.scheduler.DownloadSchedulers;
|
import com.arialyy.aria.core.scheduler.DownloadSchedulers;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -48,10 +47,21 @@ public class DownloadTaskQueue
|
|||||||
}
|
}
|
||||||
|
|
||||||
private DownloadTaskQueue() {
|
private DownloadTaskQueue() {
|
||||||
mExecutePool = new NormalExecutePool<>(true);
|
mExecutePool = new DownloadExecutePool(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void setTaskHighestPriority(DownloadTask task) {
|
@Override public String getKey(DownloadEntity entity) {
|
||||||
|
return entity.getDownloadUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getConfigMaxNum() {
|
||||||
|
return AriaManager.getInstance(AriaManager.APP).getDownloadConfig().oldMaxTaskNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置任务为最高优先级任务
|
||||||
|
*/
|
||||||
|
public void setTaskHighestPriority(DownloadTask task) {
|
||||||
task.setHighestPriority(true);
|
task.setHighestPriority(true);
|
||||||
Map<String, DownloadTask> exeTasks = mExecutePool.getAllTask();
|
Map<String, DownloadTask> exeTasks = mExecutePool.getAllTask();
|
||||||
if (exeTasks != null && !exeTasks.isEmpty()) {
|
if (exeTasks != null && !exeTasks.isEmpty()) {
|
||||||
@ -103,33 +113,6 @@ public class DownloadTaskQueue
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void setMaxTaskNum(int downloadNum) {
|
|
||||||
int oldMaxSize = AriaManager.getInstance(AriaManager.APP).getDownloadConfig().oldMaxTaskNum;
|
|
||||||
int diff = downloadNum - oldMaxSize;
|
|
||||||
if (oldMaxSize == downloadNum) {
|
|
||||||
Log.d(TAG, "设置的下载任务数和配置文件的下载任务数一直,跳过");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//设置的任务数小于配置任务数
|
|
||||||
if (diff <= -1 && mExecutePool.size() >= oldMaxSize) {
|
|
||||||
for (int i = 0, len = Math.abs(diff); i < len; i++) {
|
|
||||||
DownloadTask eTask = mExecutePool.pollTask();
|
|
||||||
if (eTask != null) {
|
|
||||||
stopTask(eTask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mExecutePool.setMaxNum(downloadNum);
|
|
||||||
if (diff >= 1) {
|
|
||||||
for (int i = 0; i < diff; i++) {
|
|
||||||
DownloadTask nextTask = getNextTask();
|
|
||||||
if (nextTask != null && nextTask.getDownloadEntity().getState() == IEntity.STATE_WAIT) {
|
|
||||||
startTask(nextTask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public DownloadTask createTask(String target, DownloadTaskEntity entity) {
|
@Override public DownloadTask createTask(String target, DownloadTaskEntity entity) {
|
||||||
DownloadTask task = null;
|
DownloadTask task = null;
|
||||||
if (!TextUtils.isEmpty(target)) {
|
if (!TextUtils.isEmpty(target)) {
|
||||||
@ -137,23 +120,13 @@ public class DownloadTaskQueue
|
|||||||
.createTask(target, entity, DownloadSchedulers.getInstance());
|
.createTask(target, entity, DownloadSchedulers.getInstance());
|
||||||
mCachePool.putTask(task);
|
mCachePool.putTask(task);
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "target name 为 null是!!");
|
Log.e(TAG, "target name 为 null!!");
|
||||||
}
|
}
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public DownloadTask getTask(DownloadEntity entity) {
|
@Override public void stopTask(DownloadTask task) {
|
||||||
return getTask(entity.getDownloadUrl());
|
task.setHighestPriority(false);
|
||||||
}
|
super.stopTask(task);
|
||||||
|
|
||||||
@Override public void removeTask(DownloadEntity entity) {
|
|
||||||
DownloadTask task = mExecutePool.getTask(entity.getDownloadUrl());
|
|
||||||
if (task != null) {
|
|
||||||
Log.d(TAG, "从执行池删除任务,删除" + (mExecutePool.removeTask(task) ? "成功" : "失败"));
|
|
||||||
}
|
|
||||||
task = mCachePool.getTask(entity.getDownloadUrl());
|
|
||||||
if (task != null) {
|
|
||||||
Log.d(TAG, "从缓存池删除任务,删除" + (mCachePool.removeTask(task) ? "成功" : "失败"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -19,7 +19,9 @@ package com.arialyy.aria.core.queue;
|
|||||||
import com.arialyy.aria.core.download.DownloadEntity;
|
import com.arialyy.aria.core.download.DownloadEntity;
|
||||||
import com.arialyy.aria.core.download.DownloadTaskEntity;
|
import com.arialyy.aria.core.download.DownloadTaskEntity;
|
||||||
import com.arialyy.aria.core.download.DownloadTask;
|
import com.arialyy.aria.core.download.DownloadTask;
|
||||||
|
import com.arialyy.aria.core.inf.AbsEntity;
|
||||||
import com.arialyy.aria.core.inf.AbsNormalTask;
|
import com.arialyy.aria.core.inf.AbsNormalTask;
|
||||||
|
import com.arialyy.aria.core.inf.AbsTask;
|
||||||
import com.arialyy.aria.core.inf.IEntity;
|
import com.arialyy.aria.core.inf.IEntity;
|
||||||
import com.arialyy.aria.core.inf.AbsTaskEntity;
|
import com.arialyy.aria.core.inf.AbsTaskEntity;
|
||||||
import com.arialyy.aria.core.upload.UploadEntity;
|
import com.arialyy.aria.core.upload.UploadEntity;
|
||||||
@ -30,7 +32,7 @@ import com.arialyy.aria.core.upload.UploadTaskEntity;
|
|||||||
* Created by lyy on 2016/8/16.
|
* Created by lyy on 2016/8/16.
|
||||||
* 任务功能接口
|
* 任务功能接口
|
||||||
*/
|
*/
|
||||||
public interface ITaskQueue<TASK extends AbsNormalTask, TASK_ENTITY extends AbsTaskEntity, ENTITY extends IEntity> {
|
public interface ITaskQueue<TASK extends AbsTask, TASK_ENTITY extends AbsTaskEntity, ENTITY extends AbsEntity> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过key判断任务是否正在执行
|
* 通过key判断任务是否正在执行
|
||||||
@ -50,13 +52,6 @@ public interface ITaskQueue<TASK extends AbsNormalTask, TASK_ENTITY extends AbsT
|
|||||||
*/
|
*/
|
||||||
void removeAllTask();
|
void removeAllTask();
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置任务为最高优先级任务
|
|
||||||
*
|
|
||||||
* @param task {@link DownloadTask}、{@link UploadTask}
|
|
||||||
*/
|
|
||||||
void setTaskHighestPriority(TASK task);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开始任务
|
* 开始任务
|
||||||
*
|
*
|
||||||
|
@ -17,12 +17,15 @@
|
|||||||
package com.arialyy.aria.core.queue;
|
package com.arialyy.aria.core.queue;
|
||||||
|
|
||||||
import com.arialyy.aria.core.AriaManager;
|
import com.arialyy.aria.core.AriaManager;
|
||||||
|
import com.arialyy.aria.core.download.DownloadGroupTask;
|
||||||
|
import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
|
||||||
import com.arialyy.aria.core.download.DownloadTask;
|
import com.arialyy.aria.core.download.DownloadTask;
|
||||||
import com.arialyy.aria.core.download.DownloadTaskEntity;
|
import com.arialyy.aria.core.download.DownloadTaskEntity;
|
||||||
import com.arialyy.aria.core.inf.ITask;
|
import com.arialyy.aria.core.inf.ITask;
|
||||||
import com.arialyy.aria.core.inf.AbsTaskEntity;
|
import com.arialyy.aria.core.inf.AbsTaskEntity;
|
||||||
import com.arialyy.aria.core.scheduler.DownloadSchedulers;
|
import com.arialyy.aria.core.scheduler.DownloadSchedulers;
|
||||||
import com.arialyy.aria.core.scheduler.ISchedulers;
|
import com.arialyy.aria.core.scheduler.ISchedulers;
|
||||||
|
import com.arialyy.aria.core.scheduler.UploadSchedulers;
|
||||||
import com.arialyy.aria.core.upload.UploadTask;
|
import com.arialyy.aria.core.upload.UploadTask;
|
||||||
import com.arialyy.aria.core.upload.UploadTaskEntity;
|
import com.arialyy.aria.core.upload.UploadTaskEntity;
|
||||||
|
|
||||||
@ -30,8 +33,7 @@ import com.arialyy.aria.core.upload.UploadTaskEntity;
|
|||||||
* Created by lyy on 2016/8/18.
|
* Created by lyy on 2016/8/18.
|
||||||
* 任务工厂
|
* 任务工厂
|
||||||
*/
|
*/
|
||||||
public class TaskFactory {
|
class TaskFactory {
|
||||||
private static final String TAG = "TaskFactory";
|
|
||||||
|
|
||||||
private static volatile TaskFactory INSTANCE = null;
|
private static volatile TaskFactory INSTANCE = null;
|
||||||
|
|
||||||
@ -53,20 +55,36 @@ public class TaskFactory {
|
|||||||
*
|
*
|
||||||
* @param entity 下载实体
|
* @param entity 下载实体
|
||||||
* @param schedulers 对应的任务调度器
|
* @param schedulers 对应的任务调度器
|
||||||
* @param <ENTITY> {@link DownloadTaskEntity}、{@link UploadTaskEntity}
|
* @param <TASK_ENTITY> {@link DownloadTaskEntity}、{@link UploadTaskEntity}、{@link
|
||||||
* @param <SCHEDULER> {@link DownloadSchedulers}
|
* DownloadGroupTaskEntity}
|
||||||
* @return {@link DownloadTask}、{@link UploadTask}
|
* @param <SCHEDULER> {@link DownloadSchedulers}、{@link UploadSchedulers}
|
||||||
|
* @return {@link DownloadTask}、{@link UploadTask}、{@link DownloadGroupTask}
|
||||||
*/
|
*/
|
||||||
<ENTITY extends AbsTaskEntity, SCHEDULER extends ISchedulers> ITask createTask(String targetName,
|
<TASK_ENTITY extends AbsTaskEntity, SCHEDULER extends ISchedulers> ITask createTask(
|
||||||
ENTITY entity, SCHEDULER schedulers) {
|
String targetName, TASK_ENTITY entity, SCHEDULER schedulers) {
|
||||||
if (entity instanceof DownloadTaskEntity) {
|
if (entity instanceof DownloadTaskEntity) {
|
||||||
return createDownloadTask(targetName, (DownloadTaskEntity) entity, schedulers);
|
return createDownloadTask(targetName, (DownloadTaskEntity) entity, schedulers);
|
||||||
} else if (entity instanceof UploadTaskEntity) {
|
} else if (entity instanceof UploadTaskEntity) {
|
||||||
return createUploadTask(targetName, (UploadTaskEntity) entity, schedulers);
|
return createUploadTask(targetName, (UploadTaskEntity) entity, schedulers);
|
||||||
|
} else if (entity instanceof DownloadGroupTaskEntity) {
|
||||||
|
return createDownloadGroupTask(targetName, (DownloadGroupTaskEntity) entity, schedulers);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建下载任务主任务
|
||||||
|
*
|
||||||
|
* @param entity 下载任务实体{@link DownloadGroupTask}
|
||||||
|
* @param schedulers {@link ISchedulers}
|
||||||
|
*/
|
||||||
|
private DownloadGroupTask createDownloadGroupTask(String targetName,
|
||||||
|
DownloadGroupTaskEntity entity, ISchedulers schedulers) {
|
||||||
|
DownloadGroupTask.Builder builder = new DownloadGroupTask.Builder(targetName, entity);
|
||||||
|
builder.setOutHandler(schedulers);
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param entity 上传任务实体{@link UploadTaskEntity}
|
* @param entity 上传任务实体{@link UploadTaskEntity}
|
||||||
* @param schedulers {@link ISchedulers}
|
* @param schedulers {@link ISchedulers}
|
||||||
|
@ -19,7 +19,7 @@ package com.arialyy.aria.core.queue;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import com.arialyy.aria.core.AriaManager;
|
import com.arialyy.aria.core.AriaManager;
|
||||||
import com.arialyy.aria.core.queue.pool.NormalExecutePool;
|
import com.arialyy.aria.core.queue.pool.BaseExecutePool;
|
||||||
import com.arialyy.aria.core.scheduler.UploadSchedulers;
|
import com.arialyy.aria.core.scheduler.UploadSchedulers;
|
||||||
import com.arialyy.aria.core.upload.UploadEntity;
|
import com.arialyy.aria.core.upload.UploadEntity;
|
||||||
import com.arialyy.aria.core.upload.UploadTask;
|
import com.arialyy.aria.core.upload.UploadTask;
|
||||||
@ -43,13 +43,18 @@ public class UploadTaskQueue extends AbsTaskQueue<UploadTask, UploadTaskEntity,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private UploadTaskQueue() {
|
private UploadTaskQueue() {
|
||||||
mExecutePool = new NormalExecutePool<>(false);
|
mExecutePool = new BaseExecutePool<>(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void setMaxTaskNum(int newMaxNum) {
|
@Override public String getKey(UploadEntity entity) {
|
||||||
|
return entity.getFilePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public int getConfigMaxNum() {
|
||||||
|
return AriaManager.getInstance(AriaManager.APP).getUploadConfig().oldMaxTaskNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override public UploadTask createTask(String targetName, UploadTaskEntity entity) {
|
@Override public UploadTask createTask(String targetName, UploadTaskEntity entity) {
|
||||||
UploadTask task = null;
|
UploadTask task = null;
|
||||||
if (!TextUtils.isEmpty(targetName)) {
|
if (!TextUtils.isEmpty(targetName)) {
|
||||||
@ -61,19 +66,4 @@ public class UploadTaskQueue extends AbsTaskQueue<UploadTask, UploadTaskEntity,
|
|||||||
}
|
}
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public UploadTask getTask(UploadEntity entity) {
|
|
||||||
return getTask(entity.getFilePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void removeTask(UploadEntity entity) {
|
|
||||||
UploadTask task = mExecutePool.getTask(entity.getFilePath());
|
|
||||||
if (task != null) {
|
|
||||||
Log.d(TAG, "从执行池删除任务,删除" + (mExecutePool.removeTask(task) ? "成功" : "失败"));
|
|
||||||
}
|
|
||||||
task = mCachePool.getTask(entity.getFilePath());
|
|
||||||
if (task != null) {
|
|
||||||
Log.d(TAG, "从缓存池删除任务,删除" + (mCachePool.removeTask(task) ? "成功" : "失败"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -32,14 +32,14 @@ import java.util.concurrent.TimeUnit;
|
|||||||
* Created by lyy on 2016/8/14.
|
* Created by lyy on 2016/8/14.
|
||||||
* 任务缓存池,所有下载任务最先缓存在这个池中
|
* 任务缓存池,所有下载任务最先缓存在这个池中
|
||||||
*/
|
*/
|
||||||
public class NormalCachePool<TASK extends ITask> implements IPool<TASK> {
|
public class BaseCachePool<TASK extends ITask> implements IPool<TASK> {
|
||||||
private static final String TAG = "NormalCachePool";
|
private static final String TAG = "BaseCachePool";
|
||||||
private static final int MAX_NUM = Integer.MAX_VALUE; //最大下载任务数
|
private static final int MAX_NUM = Integer.MAX_VALUE; //最大下载任务数
|
||||||
private static final long TIME_OUT = 1000;
|
private static final long TIME_OUT = 1000;
|
||||||
private Map<String, TASK> mCacheMap;
|
private Map<String, TASK> mCacheMap;
|
||||||
private LinkedBlockingQueue<TASK> mCacheQueue;
|
private LinkedBlockingQueue<TASK> mCacheQueue;
|
||||||
|
|
||||||
public NormalCachePool() {
|
public BaseCachePool() {
|
||||||
mCacheQueue = new LinkedBlockingQueue<>(MAX_NUM);
|
mCacheQueue = new LinkedBlockingQueue<>(MAX_NUM);
|
||||||
mCacheMap = new HashMap<>();
|
mCacheMap = new HashMap<>();
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ public class NormalCachePool<TASK extends ITask> implements IPool<TASK> {
|
|||||||
@Override public TASK pollTask() {
|
@Override public TASK pollTask() {
|
||||||
synchronized (AriaManager.LOCK) {
|
synchronized (AriaManager.LOCK) {
|
||||||
try {
|
try {
|
||||||
TASK task = null;
|
TASK task;
|
||||||
task = mCacheQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
|
task = mCacheQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
|
||||||
if (task != null) {
|
if (task != null) {
|
||||||
String url = task.getKey();
|
String url = task.getKey();
|
@ -23,7 +23,6 @@ import com.arialyy.aria.core.inf.ITask;
|
|||||||
import com.arialyy.aria.util.CommonUtil;
|
import com.arialyy.aria.util.CommonUtil;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -31,14 +30,14 @@ import java.util.concurrent.TimeUnit;
|
|||||||
* Created by lyy on 2016/8/15.
|
* Created by lyy on 2016/8/15.
|
||||||
* 任务执行池,所有当前下载任务都该任务池中,默认下载大小为2
|
* 任务执行池,所有当前下载任务都该任务池中,默认下载大小为2
|
||||||
*/
|
*/
|
||||||
public class NormalExecutePool<TASK extends ITask> implements IPool<TASK> {
|
public class BaseExecutePool<TASK extends ITask> implements IPool<TASK> {
|
||||||
private static final String TAG = "NormalExecutePool";
|
private final String TAG = "BaseExecutePool";
|
||||||
private static final long TIME_OUT = 1000;
|
final long TIME_OUT = 1000;
|
||||||
private ArrayBlockingQueue<TASK> mExecuteQueue;
|
ArrayBlockingQueue<TASK> mExecuteQueue;
|
||||||
private Map<String, TASK> mExecuteMap;
|
Map<String, TASK> mExecuteMap;
|
||||||
private int mSize;
|
protected int mSize;
|
||||||
|
|
||||||
public NormalExecutePool(boolean isDownload) {
|
public BaseExecutePool(boolean isDownload) {
|
||||||
if (isDownload) {
|
if (isDownload) {
|
||||||
mSize = AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getMaxTaskNum();
|
mSize = AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getMaxTaskNum();
|
||||||
} else {
|
} else {
|
||||||
@ -67,10 +66,6 @@ public class NormalExecutePool<TASK extends ITask> implements IPool<TASK> {
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if (mExecuteQueue.size() >= mSize) {
|
if (mExecuteQueue.size() >= mSize) {
|
||||||
Set<String> keys = mExecuteMap.keySet();
|
|
||||||
for (String key : keys) {
|
|
||||||
if (mExecuteMap.get(key).isHighestPriorityTask()) return false;
|
|
||||||
}
|
|
||||||
if (pollFirstTask()) {
|
if (pollFirstTask()) {
|
||||||
return putNewTask(task);
|
return putNewTask(task);
|
||||||
}
|
}
|
||||||
@ -106,7 +101,7 @@ public class NormalExecutePool<TASK extends ITask> implements IPool<TASK> {
|
|||||||
*
|
*
|
||||||
* @param newTask 新任务
|
* @param newTask 新任务
|
||||||
*/
|
*/
|
||||||
private boolean putNewTask(TASK newTask) {
|
boolean putNewTask(TASK newTask) {
|
||||||
String url = newTask.getKey();
|
String url = newTask.getKey();
|
||||||
boolean s = mExecuteQueue.offer(newTask);
|
boolean s = mExecuteQueue.offer(newTask);
|
||||||
Log.w(TAG, "任务添加" + (s ? "成功" : "失败,【" + url + "】"));
|
Log.w(TAG, "任务添加" + (s ? "成功" : "失败,【" + url + "】"));
|
||||||
@ -119,16 +114,13 @@ public class NormalExecutePool<TASK extends ITask> implements IPool<TASK> {
|
|||||||
/**
|
/**
|
||||||
* 队列满时,将移除下载队列中的第一个任务
|
* 队列满时,将移除下载队列中的第一个任务
|
||||||
*/
|
*/
|
||||||
private boolean pollFirstTask() {
|
boolean pollFirstTask() {
|
||||||
try {
|
try {
|
||||||
TASK oldTask = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
|
TASK oldTask = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
|
||||||
if (oldTask == null) {
|
if (oldTask == null) {
|
||||||
Log.e(TAG, "移除任务失败");
|
Log.e(TAG, "移除任务失败");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (oldTask.isHighestPriorityTask()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
oldTask.stop();
|
oldTask.stop();
|
||||||
String key = CommonUtil.keyToHashKey(oldTask.getKey());
|
String key = CommonUtil.keyToHashKey(oldTask.getKey());
|
||||||
mExecuteMap.remove(key);
|
mExecuteMap.remove(key);
|
||||||
@ -142,7 +134,7 @@ public class NormalExecutePool<TASK extends ITask> implements IPool<TASK> {
|
|||||||
@Override public TASK pollTask() {
|
@Override public TASK pollTask() {
|
||||||
synchronized (AriaManager.LOCK) {
|
synchronized (AriaManager.LOCK) {
|
||||||
try {
|
try {
|
||||||
TASK task = null;
|
TASK task;
|
||||||
task = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
|
task = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
|
||||||
if (task != null) {
|
if (task != null) {
|
||||||
String url = task.getKey();
|
String url = task.getKey();
|
@ -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.queue.pool;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
import com.arialyy.aria.core.AriaManager;
|
||||||
|
import com.arialyy.aria.core.download.DownloadTask;
|
||||||
|
import com.arialyy.aria.util.CommonUtil;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by AriaL on 2017/6/29.
|
||||||
|
* 单个下载任务的执行池
|
||||||
|
*/
|
||||||
|
public class DownloadExecutePool extends BaseExecutePool<DownloadTask> {
|
||||||
|
private final String TAG = "DownloadExecutePool";
|
||||||
|
|
||||||
|
public DownloadExecutePool(boolean isDownload) {
|
||||||
|
super(isDownload);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean putTask(DownloadTask task) {
|
||||||
|
synchronized (AriaManager.LOCK) {
|
||||||
|
if (task == null) {
|
||||||
|
Log.e(TAG, "任务不能为空!!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String url = task.getKey();
|
||||||
|
if (mExecuteQueue.contains(task)) {
|
||||||
|
Log.e(TAG, "队列中已经包含了该任务,任务key【" + url + "】");
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
if (mExecuteQueue.size() >= mSize) {
|
||||||
|
Set<String> keys = mExecuteMap.keySet();
|
||||||
|
for (String key : keys) {
|
||||||
|
if (mExecuteMap.get(key).isHighestPriorityTask()) return false;
|
||||||
|
}
|
||||||
|
if (pollFirstTask()) {
|
||||||
|
return putNewTask(task);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return putNewTask(task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override boolean pollFirstTask() {
|
||||||
|
try {
|
||||||
|
DownloadTask oldTask = mExecuteQueue.poll(TIME_OUT, TimeUnit.MICROSECONDS);
|
||||||
|
if (oldTask == null) {
|
||||||
|
Log.e(TAG, "移除任务失败");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (oldTask.isHighestPriorityTask()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
oldTask.stop();
|
||||||
|
String key = CommonUtil.keyToHashKey(oldTask.getKey());
|
||||||
|
mExecuteMap.remove(key);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -1,23 +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.queue.pool;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by AriaL on 2017/6/29.
|
|
||||||
* 任务组缓冲池
|
|
||||||
*/
|
|
||||||
public class GroupCachePool {
|
|
||||||
}
|
|
@ -1,23 +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.queue.pool;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by AriaL on 2017/6/29.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class GroupExecutePool {
|
|
||||||
}
|
|
@ -22,18 +22,18 @@ import com.arialyy.aria.core.inf.ITask;
|
|||||||
* Created by lyy on 2016/8/14.
|
* Created by lyy on 2016/8/14.
|
||||||
* 任务池
|
* 任务池
|
||||||
*/
|
*/
|
||||||
public interface IPool<T extends ITask> {
|
interface IPool<T extends ITask> {
|
||||||
/**
|
/**
|
||||||
* 将下载任务添加到任务池中
|
* 将下载任务添加到任务池中
|
||||||
*/
|
*/
|
||||||
public boolean putTask(T task);
|
boolean putTask(T task);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按照队列原则取出下载任务
|
* 按照队列原则取出下载任务
|
||||||
*
|
*
|
||||||
* @return 返回null或者下载任务
|
* @return 返回null或者下载任务
|
||||||
*/
|
*/
|
||||||
public T pollTask();
|
T pollTask();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过下载链接获取下载任务,当任务不为空时,队列将删除该下载任务
|
* 通过下载链接获取下载任务,当任务不为空时,队列将删除该下载任务
|
||||||
@ -41,7 +41,7 @@ public interface IPool<T extends ITask> {
|
|||||||
* @param downloadUrl 下载链接
|
* @param downloadUrl 下载链接
|
||||||
* @return 返回null或者下载任务
|
* @return 返回null或者下载任务
|
||||||
*/
|
*/
|
||||||
public T getTask(String downloadUrl);
|
T getTask(String downloadUrl);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除任务池中的下载任务
|
* 删除任务池中的下载任务
|
||||||
@ -49,7 +49,7 @@ public interface IPool<T extends ITask> {
|
|||||||
* @param task 下载任务
|
* @param task 下载任务
|
||||||
* @return true:移除成功
|
* @return true:移除成功
|
||||||
*/
|
*/
|
||||||
public boolean removeTask(T task);
|
boolean removeTask(T task);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过key除下载任务
|
* 通过key除下载任务
|
||||||
@ -57,12 +57,12 @@ public interface IPool<T extends ITask> {
|
|||||||
* @param key 下载链接
|
* @param key 下载链接
|
||||||
* @return true:移除成功
|
* @return true:移除成功
|
||||||
*/
|
*/
|
||||||
public boolean removeTask(String key);
|
boolean removeTask(String key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 池子大小
|
* 池子大小
|
||||||
*
|
*
|
||||||
* @return 返回缓存池或者执行池大小
|
* @return 返回缓存池或者执行池大小
|
||||||
*/
|
*/
|
||||||
public int size();
|
int size();
|
||||||
}
|
}
|
@ -20,8 +20,8 @@ import android.os.Message;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import com.arialyy.aria.core.AriaManager;
|
import com.arialyy.aria.core.AriaManager;
|
||||||
import com.arialyy.aria.core.download.DownloadTask;
|
import com.arialyy.aria.core.download.DownloadTask;
|
||||||
import com.arialyy.aria.core.inf.AbsNormalEntity;
|
import com.arialyy.aria.core.inf.AbsEntity;
|
||||||
import com.arialyy.aria.core.inf.AbsNormalTask;
|
import com.arialyy.aria.core.inf.AbsTask;
|
||||||
import com.arialyy.aria.core.inf.AbsTaskEntity;
|
import com.arialyy.aria.core.inf.AbsTaskEntity;
|
||||||
import com.arialyy.aria.core.inf.IEntity;
|
import com.arialyy.aria.core.inf.IEntity;
|
||||||
import com.arialyy.aria.core.queue.ITaskQueue;
|
import com.arialyy.aria.core.queue.ITaskQueue;
|
||||||
@ -34,19 +34,19 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
/**
|
/**
|
||||||
* Created by lyy on 2017/6/4.
|
* Created by lyy on 2017/6/4.
|
||||||
*/
|
*/
|
||||||
public abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskEntity, ENTITY extends AbsNormalEntity, TASK extends AbsNormalTask<TASK_ENTITY, ENTITY>, QUEUE extends ITaskQueue<TASK, TASK_ENTITY, ENTITY>>
|
abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskEntity, ENTITY extends AbsEntity, TASK extends AbsTask<ENTITY>, QUEUE extends ITaskQueue<TASK, TASK_ENTITY, ENTITY>>
|
||||||
implements ISchedulers<TASK> {
|
implements ISchedulers<TASK> {
|
||||||
private static final String TAG = "AbsSchedulers";
|
private final String TAG = "AbsSchedulers";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 下载的动态生成的代理类后缀
|
* 下载的动态生成的代理类后缀
|
||||||
*/
|
*/
|
||||||
String DOWNLOAD_PROXY_CLASS_SUFFIX = "$$DownloadListenerProxy";
|
private String DOWNLOAD_PROXY_CLASS_SUFFIX = "$$DownloadListenerProxy";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传的动态生成的代理类后缀
|
* 上传的动态生成的代理类后缀
|
||||||
*/
|
*/
|
||||||
String UPLOAD_PROXY_CLASS_SUFFIX = "$$UploadListenerProxy";
|
private String UPLOAD_PROXY_CLASS_SUFFIX = "$$UploadListenerProxy";
|
||||||
|
|
||||||
protected QUEUE mQueue;
|
protected QUEUE mQueue;
|
||||||
protected boolean isDownload = true;
|
protected boolean isDownload = true;
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* 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 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.DownloadGroupTaskQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by AriaL on 2017/7/2.
|
||||||
|
*/
|
||||||
|
public class DownloadGroupSchedulers extends
|
||||||
|
AbsSchedulers<DownloadGroupTaskEntity, DownloadGroupEntity, DownloadGroupTask, DownloadGroupTaskQueue> {
|
||||||
|
private final String TAG = "DownloadGroupSchedulers";
|
||||||
|
private static volatile DownloadGroupSchedulers INSTANCE = null;
|
||||||
|
|
||||||
|
private DownloadGroupSchedulers() {
|
||||||
|
mQueue = DownloadGroupTaskQueue.getInstance();
|
||||||
|
isDownload = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DownloadGroupSchedulers getInstance() {
|
||||||
|
if (INSTANCE == null) {
|
||||||
|
synchronized (AriaManager.LOCK) {
|
||||||
|
INSTANCE = new DownloadGroupSchedulers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
@ -29,7 +29,7 @@ import com.arialyy.aria.core.download.DownloadTask;
|
|||||||
public class DownloadSchedulers
|
public class DownloadSchedulers
|
||||||
extends AbsSchedulers<DownloadTaskEntity, DownloadEntity, DownloadTask, DownloadTaskQueue> {
|
extends AbsSchedulers<DownloadTaskEntity, DownloadEntity, DownloadTask, DownloadTaskQueue> {
|
||||||
|
|
||||||
private static final String TAG = "DownloadSchedulers";
|
private final String TAG = "DownloadSchedulers";
|
||||||
private static volatile DownloadSchedulers INSTANCE = null;
|
private static volatile DownloadSchedulers INSTANCE = null;
|
||||||
|
|
||||||
private DownloadSchedulers() {
|
private DownloadSchedulers() {
|
||||||
|
@ -51,7 +51,7 @@ final class UploadUtil implements Runnable {
|
|||||||
UploadUtil(UploadTaskEntity taskEntity, IUploadListener listener) {
|
UploadUtil(UploadTaskEntity taskEntity, IUploadListener listener) {
|
||||||
mTaskEntity = taskEntity;
|
mTaskEntity = taskEntity;
|
||||||
CheckUtil.checkTaskEntity(taskEntity);
|
CheckUtil.checkTaskEntity(taskEntity);
|
||||||
mUploadEntity = taskEntity.uploadEntity;
|
mUploadEntity = taskEntity.getEntity();
|
||||||
if (listener == null) {
|
if (listener == null) {
|
||||||
throw new IllegalArgumentException("上传监听不能为空");
|
throw new IllegalArgumentException("上传监听不能为空");
|
||||||
}
|
}
|
||||||
@ -162,11 +162,11 @@ final class UploadUtil implements Runnable {
|
|||||||
writer.append("Content-Disposition: form-data; name=\"")
|
writer.append("Content-Disposition: form-data; name=\"")
|
||||||
.append(attachment)
|
.append(attachment)
|
||||||
.append("\"; filename=\"")
|
.append("\"; filename=\"")
|
||||||
.append(mTaskEntity.uploadEntity.getFileName())
|
.append(mTaskEntity.getEntity().getFileName())
|
||||||
.append("\"")
|
.append("\"")
|
||||||
.append(LINE_END);
|
.append(LINE_END);
|
||||||
writer.append("Content-Type: ")
|
writer.append("Content-Type: ")
|
||||||
.append(URLConnection.guessContentTypeFromName(mTaskEntity.uploadEntity.getFileName()))
|
.append(URLConnection.guessContentTypeFromName(mTaskEntity.getEntity().getFileName()))
|
||||||
.append(LINE_END);
|
.append(LINE_END);
|
||||||
writer.append("Content-Transfer-Encoding: binary").append(LINE_END);
|
writer.append("Content-Transfer-Encoding: binary").append(LINE_END);
|
||||||
writer.append(LINE_END);
|
writer.append(LINE_END);
|
||||||
|
@ -88,9 +88,9 @@ public class CheckUtil {
|
|||||||
*/
|
*/
|
||||||
public static void checkTaskEntity(AbsTaskEntity entity) {
|
public static void checkTaskEntity(AbsTaskEntity entity) {
|
||||||
if (entity instanceof DownloadTaskEntity) {
|
if (entity instanceof DownloadTaskEntity) {
|
||||||
checkDownloadTaskEntity(((DownloadTaskEntity) entity).downloadEntity);
|
checkDownloadTaskEntity(((DownloadTaskEntity) entity).getEntity());
|
||||||
} else if (entity instanceof UploadTaskEntity) {
|
} else if (entity instanceof UploadTaskEntity) {
|
||||||
checkUploadTaskEntity(((UploadTaskEntity) entity).uploadEntity);
|
checkUploadTaskEntity(((UploadTaskEntity) entity).getEntity());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ public class CheckUtil {
|
|||||||
public static boolean checkCmdEntity(AbsTaskEntity entity, boolean checkType) {
|
public static boolean checkCmdEntity(AbsTaskEntity entity, boolean checkType) {
|
||||||
boolean b = false;
|
boolean b = false;
|
||||||
if (entity instanceof DownloadTaskEntity) {
|
if (entity instanceof DownloadTaskEntity) {
|
||||||
DownloadEntity entity1 = ((DownloadTaskEntity) entity).downloadEntity;
|
DownloadEntity entity1 = ((DownloadTaskEntity) entity).getEntity();
|
||||||
if (entity1 == null) {
|
if (entity1 == null) {
|
||||||
Log.e(TAG, "下载实体不能为空");
|
Log.e(TAG, "下载实体不能为空");
|
||||||
} else if (checkType && TextUtils.isEmpty(entity1.getDownloadUrl())) {
|
} else if (checkType && TextUtils.isEmpty(entity1.getDownloadUrl())) {
|
||||||
@ -114,7 +114,7 @@ public class CheckUtil {
|
|||||||
b = true;
|
b = true;
|
||||||
}
|
}
|
||||||
} else if (entity instanceof UploadTaskEntity) {
|
} else if (entity instanceof UploadTaskEntity) {
|
||||||
UploadEntity entity1 = ((UploadTaskEntity) entity).uploadEntity;
|
UploadEntity entity1 = ((UploadTaskEntity) entity).getEntity();
|
||||||
if (entity1 == null) {
|
if (entity1 == null) {
|
||||||
Log.e(TAG, "上传实体不能为空");
|
Log.e(TAG, "上传实体不能为空");
|
||||||
} else if (TextUtils.isEmpty(entity1.getFilePath())) {
|
} else if (TextUtils.isEmpty(entity1.getFilePath())) {
|
||||||
|
@ -40,7 +40,7 @@ class Configuration {
|
|||||||
/**
|
/**
|
||||||
* 旧任务数
|
* 旧任务数
|
||||||
*/
|
*/
|
||||||
public static int oldMaxTaskNum = 2;
|
public int oldMaxTaskNum = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否发送任务广播,true,发送
|
* 是否发送任务广播,true,发送
|
||||||
@ -176,7 +176,8 @@ class Configuration {
|
|||||||
try {
|
try {
|
||||||
for (Field field : fields) {
|
for (Field field : fields) {
|
||||||
int m = field.getModifiers();
|
int m = field.getModifiers();
|
||||||
if (Modifier.isFinal(m) || Modifier.isStatic(m)) {
|
if (field.getName().equals("oldMaxTaskNum") || Modifier.isFinal(m) || Modifier.isStatic(
|
||||||
|
m)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
|
@ -23,8 +23,7 @@ import java.util.Map;
|
|||||||
* Created by lyy on 2017/2/9.
|
* Created by lyy on 2017/2/9.
|
||||||
* 上传任务实体
|
* 上传任务实体
|
||||||
*/
|
*/
|
||||||
public class UploadTaskEntity extends AbsTaskEntity {
|
public class UploadTaskEntity extends AbsTaskEntity<UploadEntity> {
|
||||||
public UploadEntity uploadEntity;
|
|
||||||
public String uploadUrl; //上传路径
|
public String uploadUrl; //上传路径
|
||||||
public String attachment; //文件上传需要的key
|
public String attachment; //文件上传需要的key
|
||||||
public String contentType = "multipart/form-data"; //上传的文件类型
|
public String contentType = "multipart/form-data"; //上传的文件类型
|
||||||
@ -36,11 +35,8 @@ public class UploadTaskEntity extends AbsTaskEntity {
|
|||||||
*/
|
*/
|
||||||
public Map<String, String> formFields = new HashMap<>();
|
public Map<String, String> formFields = new HashMap<>();
|
||||||
|
|
||||||
public UploadTaskEntity(UploadEntity downloadEntity) {
|
public UploadTaskEntity(UploadEntity entity) {
|
||||||
this.uploadEntity = downloadEntity;
|
this.entity = entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public UploadEntity getEntity() {
|
|
||||||
return uploadEntity;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user