parent
1e98b835de
commit
ef754f04cc
@ -1,368 +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; |
||||
|
||||
import android.text.TextUtils; |
||||
import com.arialyy.aria.core.common.AbsEntity; |
||||
import com.arialyy.aria.core.inf.IEntity; |
||||
import com.arialyy.aria.core.inf.ITaskQueue; |
||||
import com.arialyy.aria.core.inf.TaskSchedulerType; |
||||
import com.arialyy.aria.core.manager.TaskWrapperManager; |
||||
import com.arialyy.aria.core.manager.ThreadTaskManager; |
||||
import com.arialyy.aria.core.queue.pool.DGLoadSharePool; |
||||
import com.arialyy.aria.core.queue.pool.DLoadSharePool; |
||||
import com.arialyy.aria.core.queue.pool.UploadSharePool; |
||||
import com.arialyy.aria.core.task.DownloadGroupTask; |
||||
import com.arialyy.aria.core.task.DownloadTask; |
||||
import com.arialyy.aria.core.task.ITask; |
||||
import com.arialyy.aria.core.task.UploadTask; |
||||
import com.arialyy.aria.util.ALog; |
||||
import com.arialyy.aria.util.CommonUtil; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* Created by lyy on 2017/2/23. 任务队列 |
||||
*/ |
||||
public abstract class AbsTaskQueue<TASK extends ITask> |
||||
implements ITaskQueue<TASK> { |
||||
final int TYPE_D_QUEUE = 1; |
||||
final int TYPE_DG_QUEUE = 2; |
||||
final int TYPE_U_QUEUE = 3; |
||||
|
||||
private final String TAG = CommonUtil.getClassName(this); |
||||
BaseCachePool<TASK> mCachePool; |
||||
BaseExecutePool<TASK> mExecutePool; |
||||
|
||||
AbsTaskQueue() { |
||||
switch (getQueueType()) { |
||||
case TYPE_D_QUEUE: |
||||
mCachePool = DLoadSharePool.getInstance().cachePool; |
||||
mExecutePool = DLoadSharePool.getInstance().executePool; |
||||
break; |
||||
case TYPE_DG_QUEUE: |
||||
mCachePool = DGLoadSharePool.getInstance().cachePool; |
||||
mExecutePool = DGLoadSharePool.getInstance().executePool; |
||||
break; |
||||
case TYPE_U_QUEUE: |
||||
mCachePool = UploadSharePool.getInstance().cachePool; |
||||
mExecutePool = UploadSharePool.getInstance().executePool; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
abstract int getQueueType(); |
||||
|
||||
/** |
||||
* 获取执行中的任务 |
||||
* |
||||
* @return 没有执行中的任务,返回null |
||||
*/ |
||||
public <T extends AbsEntity> List<T> getRunningTask(Class<T> type) { |
||||
List<TASK> exeTask = mExecutePool.getAllTask(); |
||||
List<TASK> cacheTask = mCachePool.getAllTask(); |
||||
List<T> entities = new ArrayList<>(); |
||||
if (exeTask != null && !exeTask.isEmpty()) { |
||||
for (TASK task : exeTask) { |
||||
entities.add((T) task.getTaskWrapper().getEntity()); |
||||
} |
||||
} |
||||
if (cacheTask != null && !cacheTask.isEmpty()) { |
||||
for (TASK task : cacheTask) { |
||||
entities.add((T) task.getTaskWrapper().getEntity()); |
||||
} |
||||
} |
||||
return entities.isEmpty() ? null : entities; |
||||
} |
||||
|
||||
@Override public boolean taskIsRunning(String key) { |
||||
if (TextUtils.isEmpty(key)) { |
||||
ALog.w(TAG, "key为空,无法确认任务是否执行"); |
||||
return false; |
||||
} |
||||
TASK task = mExecutePool.getTask(key); |
||||
if (task == null && ThreadTaskManager.getInstance().taskIsRunning(key)) { |
||||
ThreadTaskManager.getInstance().removeTaskThread(key); |
||||
} |
||||
return task != null && task.isRunning() && taskExists(key); |
||||
} |
||||
|
||||
/** |
||||
* 恢复任务 如果执行队列任务未满,则直接启动任务。 如果执行队列已经满了,则暂停执行队列队首任务,并恢复指定任务 |
||||
* |
||||
* @param task 需要恢复的任务 |
||||
*/ |
||||
@Override public void resumeTask(TASK task) { |
||||
if (task == null) { |
||||
ALog.w(TAG, "resume task fail, task is null"); |
||||
return; |
||||
} |
||||
if (mExecutePool.taskExist(task.getKey())) { |
||||
ALog.w(TAG, String.format("task【%s】running", task.getKey())); |
||||
return; |
||||
} |
||||
if (mExecutePool.size() >= getMaxTaskNum()) { |
||||
task.getTaskWrapper().getEntity().setState(IEntity.STATE_WAIT); |
||||
mCachePool.putTaskToFirst(task); |
||||
stopTask(mExecutePool.pollTask()); |
||||
} else { |
||||
startTask(task); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 停止所有任务 |
||||
*/ |
||||
@Override public void stopAllTask() { |
||||
for (TASK task : mExecutePool.getAllTask()) { |
||||
if (task != null) { |
||||
int state = task.getTaskState(); |
||||
if (task.isRunning() || (state != IEntity.STATE_COMPLETE |
||||
&& state != IEntity.STATE_CANCEL)) { |
||||
task.stop(TaskSchedulerType.TYPE_STOP_NOT_NEXT); |
||||
} |
||||
} |
||||
} |
||||
|
||||
//for (String key : mCachePool.getAllTask().keySet()) {
|
||||
// TASK task = mCachePool.getAllTask().get(key);
|
||||
// if (task != null) {
|
||||
// task.stop(TaskSchedulerType.TYPE_STOP_NOT_NEXT);
|
||||
// }
|
||||
//}
|
||||
for (TASK task : mCachePool.getAllTask()) { |
||||
if (task != null) { |
||||
task.stop(TaskSchedulerType.TYPE_STOP_NOT_NEXT); |
||||
} |
||||
} |
||||
ThreadTaskManager.getInstance().removeAllThreadTask(); |
||||
mCachePool.clear(); |
||||
} |
||||
|
||||
/** |
||||
* 获取配置文件旧的最大任务数 |
||||
*/ |
||||
public abstract int getOldMaxNum(); |
||||
|
||||
/** |
||||
* 获取任务执行池 |
||||
*/ |
||||
public BaseExecutePool getExecutePool() { |
||||
return mExecutePool; |
||||
} |
||||
|
||||
/** |
||||
* 获取缓存池 |
||||
*/ |
||||
public BaseCachePool getCachePool() { |
||||
return mCachePool; |
||||
} |
||||
|
||||
/** |
||||
* 获取缓存任务数 |
||||
* |
||||
* @return 获取缓存的任务数 |
||||
*/ |
||||
@Override public int getCurrentCachePoolNum() { |
||||
return mCachePool.size(); |
||||
} |
||||
|
||||
/** |
||||
* 获取执行池中的任务数量 |
||||
* |
||||
* @return 当前正在执行的任务数 |
||||
*/ |
||||
@Override public int getCurrentExePoolNum() { |
||||
return mExecutePool.size(); |
||||
} |
||||
|
||||
@Override public void setMaxTaskNum(int maxNum) { |
||||
int oldMaxSize = getOldMaxSize(); |
||||
int diff = maxNum - oldMaxSize; |
||||
if (oldMaxSize == maxNum) { |
||||
ALog.w(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.setPoolSize(maxNum); |
||||
if (diff >= 1) { |
||||
for (int i = 0; i < diff; i++) { |
||||
TASK nextTask = getNextTask(); |
||||
if (nextTask != null && nextTask.getTaskState() == IEntity.STATE_WAIT) { |
||||
startTask(nextTask); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Override public TASK createTask(TASK_WRAPPER wrapper) { |
||||
TaskWrapperManager.getInstance().putTaskWrapper(wrapper); |
||||
return null; |
||||
} |
||||
|
||||
@Override public boolean taskExists(String key) { |
||||
return getTask(key) != null; |
||||
} |
||||
|
||||
@Override public TASK getTask(String key) { |
||||
TASK task = mExecutePool.getTask(key); |
||||
if (task == null) { |
||||
task = mCachePool.getTask(key); |
||||
} |
||||
ALog.i(TAG, "获取任务,key:" + key); |
||||
return task; |
||||
} |
||||
|
||||
/** |
||||
* 添加等待中的任务 |
||||
* |
||||
* @param task {@link DownloadTask}、{@link UploadTask}、{@link DownloadGroupTask} |
||||
*/ |
||||
void addTask(TASK task) { |
||||
if (task == null) { |
||||
ALog.w(TAG, "add task fail, task is null"); |
||||
return; |
||||
} |
||||
if (!mCachePool.taskExits(task.getKey())) { |
||||
mCachePool.putTask(task); |
||||
} |
||||
} |
||||
|
||||
@Override public void startTask(TASK task) { |
||||
startTask(task, TaskSchedulerType.TYPE_DEFAULT); |
||||
} |
||||
|
||||
@Override public void startTask(TASK task, int action) { |
||||
if (task == null) { |
||||
ALog.w(TAG, "create fail, task is null"); |
||||
} |
||||
if (mExecutePool.taskExist(task.getKey())) { |
||||
ALog.w(TAG, String.format("任务【%s】执行中", task.getKey())); |
||||
return; |
||||
} |
||||
ALog.i(TAG, "添加任务,key:" + task.getKey()); |
||||
mCachePool.removeTask(task); |
||||
mExecutePool.putTask(task); |
||||
task.getTaskWrapper().getEntity().setFailNum(0); |
||||
task.start(action); |
||||
} |
||||
|
||||
@Override public void stopTask(TASK task) { |
||||
if (task == null) { |
||||
ALog.w(TAG, "stop fail, task is null"); |
||||
return; |
||||
} |
||||
int state = task.getTaskState(); |
||||
boolean canStop = false; |
||||
switch (state) { |
||||
case IEntity.STATE_WAIT: |
||||
mCachePool.removeTask(task); |
||||
canStop = true; |
||||
break; |
||||
case IEntity.STATE_POST_PRE: |
||||
case IEntity.STATE_PRE: |
||||
case IEntity.STATE_RUNNING: |
||||
mExecutePool.removeTask(task); |
||||
canStop = true; |
||||
break; |
||||
case IEntity.STATE_STOP: |
||||
case IEntity.STATE_OTHER: |
||||
case IEntity.STATE_FAIL: |
||||
ALog.w(TAG, String.format("停止任务【%s】失败,原因:已停止", task.getTaskName())); |
||||
if (taskIsRunning(task.getKey())) { |
||||
removeTaskFormQueue(task.getKey()); |
||||
if (ThreadTaskManager.getInstance().taskIsRunning(task.getKey())) { |
||||
ThreadTaskManager.getInstance().removeTaskThread(task.getKey()); |
||||
} |
||||
} |
||||
break; |
||||
case IEntity.STATE_CANCEL: |
||||
ALog.w(TAG, String.format("停止任务【%s】失败,原因:任务已删除", task.getTaskName())); |
||||
break; |
||||
case IEntity.STATE_COMPLETE: |
||||
ALog.w(TAG, String.format("停止任务【%s】失败,原因:已完成", task.getTaskName())); |
||||
break; |
||||
} |
||||
|
||||
if (canStop) { |
||||
task.stop(); |
||||
} |
||||
} |
||||
|
||||
@Override public void removeTaskFormQueue(String key) { |
||||
TASK task = mExecutePool.getTask(key); |
||||
if (task != null) { |
||||
ALog.d(TAG, String.format("从执行池删除任务【%s】%s", task.getTaskName(), |
||||
(mExecutePool.removeTask(task) ? "成功" : "失败"))); |
||||
} |
||||
task = mCachePool.getTask(key); |
||||
if (task != null) { |
||||
ALog.d(TAG, String.format("从缓存池删除任务【%s】%s", task.getTaskName(), |
||||
(mCachePool.removeTask(task) ? "成功" : "失败"))); |
||||
} |
||||
} |
||||
|
||||
@Override public void reTryStart(TASK task) { |
||||
if (task == null) { |
||||
ALog.e(TAG, "reTry fail, task is null"); |
||||
return; |
||||
} |
||||
|
||||
int state = task.getTaskState(); |
||||
switch (state) { |
||||
case IEntity.STATE_POST_PRE: |
||||
case IEntity.STATE_PRE: |
||||
case IEntity.STATE_RUNNING: |
||||
ALog.w(TAG, String.format("任务【%s】没有停止,即将重新下载", task.getTaskName())); |
||||
task.stop(TaskSchedulerType.TYPE_STOP_NOT_NEXT); |
||||
task.start(); |
||||
break; |
||||
case IEntity.STATE_WAIT: |
||||
case IEntity.STATE_STOP: |
||||
case IEntity.STATE_OTHER: |
||||
case IEntity.STATE_FAIL: |
||||
task.start(); |
||||
break; |
||||
case IEntity.STATE_CANCEL: |
||||
ALog.e(TAG, String.format("任务【%s】重试失败,原因:任务已删除", task.getTaskName())); |
||||
break; |
||||
case IEntity.STATE_COMPLETE: |
||||
ALog.e(TAG, String.format("任务【%s】重试失败,原因:已完成", task.getTaskName())); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
@Override public void cancelTask(TASK task) { |
||||
cancelTask(task, TaskSchedulerType.TYPE_DEFAULT); |
||||
} |
||||
|
||||
@Override public void cancelTask(TASK task, int action) { |
||||
task.cancel(action); |
||||
} |
||||
|
||||
@Override public TASK getNextTask() { |
||||
return mCachePool.pollTask(); |
||||
} |
||||
} |
@ -1,83 +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.http.download |
||||
|
||||
import android.net.Uri |
||||
import com.arialyy.aria.core.DuaContext |
||||
import com.arialyy.aria.core.command.CancelCmd |
||||
import com.arialyy.aria.core.command.StopCmd |
||||
import com.arialyy.aria.core.common.TaskOption |
||||
import com.arialyy.aria.core.task.DownloadTask |
||||
import com.arialyy.aria.core.task.TaskCachePool |
||||
import com.arialyy.aria.util.FileUtils |
||||
import kotlinx.coroutines.Dispatchers |
||||
import kotlinx.coroutines.launch |
||||
import kotlinx.coroutines.withContext |
||||
import timber.log.Timber |
||||
|
||||
/** |
||||
* @Author laoyuyu |
||||
* @Description |
||||
* @Date 20:25 2023/2/19 |
||||
**/ |
||||
class HttpDStopController2(val filePath: Uri) { |
||||
|
||||
private suspend fun checkUri(): Boolean { |
||||
if (!FileUtils.uriEffective(filePath)) { |
||||
Timber.e("invalid uri: $filePath") |
||||
return false |
||||
} |
||||
return withContext(Dispatchers.IO) { |
||||
val entity = DuaContext.getServiceManager().getDbService().getDuaDb().getDEntityDao() |
||||
.getDEntityBySavePath(filePath.toString()) |
||||
if (entity == null) { |
||||
Timber.e("No found task, uri: $filePath") |
||||
return@withContext false |
||||
} |
||||
return@withContext true |
||||
} |
||||
} |
||||
|
||||
fun cancel() { |
||||
DuaContext.duaScope.launch { |
||||
if (checkUri()) { |
||||
var task = TaskCachePool.findTaskByPath(filePath) |
||||
if (task == null) { |
||||
Timber.i("task not exist, create new task") |
||||
task = DownloadTask(TaskOption()) |
||||
task.adapter = HttpDTaskAdapter() |
||||
} |
||||
TaskCachePool.putTask(task) |
||||
CancelCmd(task).executeCmd() |
||||
} |
||||
} |
||||
} |
||||
|
||||
fun stop() { |
||||
DuaContext.duaScope.launch { |
||||
if (checkUri()) { |
||||
TaskCachePool.findTaskByPath(filePath)?.let { |
||||
StopCmd(it).executeCmd() |
||||
return@launch |
||||
} |
||||
|
||||
Timber.e("not found task, uri: $filePath") |
||||
return@launch |
||||
} |
||||
Timber.e("stop fail, invalid uri: $filePath") |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue