optimize controller code

v4
laoyuyu 2 years ago
parent 1e98b835de
commit ef754f04cc
  1. 368
      Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java
  2. 3
      Http/src/main/java/com/arialyy/aria/http/download/HttpDBlockInterceptor.kt
  3. 12
      Http/src/main/java/com/arialyy/aria/http/download/HttpDCheckInterceptor.kt
  4. 7
      Http/src/main/java/com/arialyy/aria/http/download/HttpDHeaderInterceptor.kt
  5. 39
      Http/src/main/java/com/arialyy/aria/http/download/HttpDStartController.kt
  6. 13
      Http/src/main/java/com/arialyy/aria/http/download/HttpDStopController.kt
  7. 83
      Http/src/main/java/com/arialyy/aria/http/download/HttpDStopController2.kt
  8. 9
      Http/src/main/java/com/arialyy/aria/http/download/HttpDownloader.kt
  9. 4
      PublicComponent/src/main/java/com/arialyy/aria/core/command/StartCmd.java
  10. 3
      PublicComponent/src/main/java/com/arialyy/aria/core/inf/BaseEntity.kt
  11. 13
      PublicComponent/src/main/java/com/arialyy/aria/core/task/DownloadTask.java
  12. 2
      PublicComponent/src/main/java/com/arialyy/aria/core/task/ITask.java
  13. 27
      PublicComponent/src/main/java/com/arialyy/aria/core/task/TaskCachePool.kt
  14. 7
      PublicComponent/src/main/java/com/arialyy/aria/core/task/TaskState.kt
  15. 4
      PublicComponent/src/main/java/com/arialyy/aria/orm/entity/DEntity.kt

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

@ -18,14 +18,15 @@ package com.arialyy.aria.http.download
import com.arialyy.aria.core.DuaContext import com.arialyy.aria.core.DuaContext
import com.arialyy.aria.core.inf.IBlockManager import com.arialyy.aria.core.inf.IBlockManager
import com.arialyy.aria.core.inf.ITaskManager import com.arialyy.aria.core.inf.ITaskManager
import com.arialyy.aria.util.BlockUtil
import com.arialyy.aria.core.task.ITask import com.arialyy.aria.core.task.ITask
import com.arialyy.aria.core.task.ITaskInterceptor import com.arialyy.aria.core.task.ITaskInterceptor
import com.arialyy.aria.core.task.TaskCachePool
import com.arialyy.aria.core.task.TaskChain import com.arialyy.aria.core.task.TaskChain
import com.arialyy.aria.core.task.TaskResp import com.arialyy.aria.core.task.TaskResp
import com.arialyy.aria.http.HttpTaskOption import com.arialyy.aria.http.HttpTaskOption
import com.arialyy.aria.orm.entity.BlockRecord import com.arialyy.aria.orm.entity.BlockRecord
import com.arialyy.aria.orm.entity.TaskRecord import com.arialyy.aria.orm.entity.TaskRecord
import com.arialyy.aria.util.BlockUtil
import com.arialyy.aria.util.FileUri import com.arialyy.aria.util.FileUri
import com.arialyy.aria.util.FileUtils import com.arialyy.aria.util.FileUtils
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers

@ -22,7 +22,6 @@ import com.arialyy.aria.core.task.TaskChain
import com.arialyy.aria.core.task.TaskResp import com.arialyy.aria.core.task.TaskResp
import com.arialyy.aria.http.HttpTaskOption import com.arialyy.aria.http.HttpTaskOption
import com.arialyy.aria.orm.entity.DEntity import com.arialyy.aria.orm.entity.DEntity
import timber.log.Timber
/** /**
* @Author laoyuyu * @Author laoyuyu
@ -34,12 +33,12 @@ class HttpDCheckInterceptor : ITaskInterceptor {
/** /**
* find DEntity, if that not exist, create and save it * find DEntity, if that not exist, create and save it
*/ */
private suspend fun findDEntityBySavePath(option: HttpTaskOption): DEntity? { private suspend fun findDEntityBySavePath(option: HttpTaskOption): DEntity {
val savePath = option.savePathUri val savePath = option.savePathUri
val dao = DuaContext.getServiceManager().getDbService().getDuaDb().getDEntityDao() val dao = DuaContext.getServiceManager().getDbService().getDuaDb().getDEntityDao()
val de = dao.getDEntityBySavePath(savePath.toString()) val de = dao.getDEntityBySavePath(savePath.toString())
if (de != null) { if (de != null) {
return null return de
} }
val newDe = DEntity( val newDe = DEntity(
sourceUrl = option.sourUrl!!, sourceUrl = option.sourUrl!!,
@ -52,11 +51,8 @@ class HttpDCheckInterceptor : ITaskInterceptor {
override suspend fun interceptor(chain: TaskChain): TaskResp { override suspend fun interceptor(chain: TaskChain): TaskResp {
val option = chain.getTask().getTaskOption(HttpTaskOption::class.java) val option = chain.getTask().getTaskOption(HttpTaskOption::class.java)
val dEntity = findDEntityBySavePath(option) val dEntity = findDEntityBySavePath(option)
if (dEntity == null) { chain.getTask().taskState.entity = dEntity
Timber.e("file already exists, ${option.savePathUri}")
return TaskResp(TaskResp.CODE_INTERRUPT)
}
TaskCachePool.putEntity(chain.getTask().taskId, dEntity) TaskCachePool.putEntity(chain.getTask().taskId, dEntity)
return TaskResp(TaskResp.CODE_SUCCESS) return chain.proceed(chain.getTask())
} }
} }

@ -63,13 +63,18 @@ internal class HttpDHeaderInterceptor : ITaskInterceptor {
} }
Timber.i("step 1. get file info") Timber.i("step 1. get file info")
task = chain.getTask() task = chain.getTask()
if (task.taskState.fileSize > 0L) {
Timber.d("not required repeat get file size: ${task.taskState.fileSize}")
return chain.proceed(task)
}
taskOption = task.getTaskOption(HttpTaskOption::class.java) taskOption = task.getTaskOption(HttpTaskOption::class.java)
try { try {
val fileSize = getFileSize() val fileSize = getFileSize()
if (fileSize >= 0) { if (fileSize >= 0) {
task.taskState.fileSize = fileSize task.taskState.fileSize = fileSize
getOptionAdapter().isSupportResume = fileSize != 0L getOptionAdapter().isSupportResume = fileSize != 0L
getOptionAdapter().isSupportBlock = getOptionAdapter().isSupportResume && fileSize > BlockRecord.BLOCK_SIZE getOptionAdapter().isSupportBlock =
getOptionAdapter().isSupportResume && fileSize > BlockRecord.BLOCK_SIZE
return chain.proceed(task) return chain.proceed(task)
} }
} catch (e: IOException) { } catch (e: IOException) {

@ -18,7 +18,9 @@ package com.arialyy.aria.http.download
import android.net.Uri import android.net.Uri
import com.arialyy.aria.core.DuaContext import com.arialyy.aria.core.DuaContext
import com.arialyy.aria.core.command.AddCmd import com.arialyy.aria.core.command.AddCmd
import com.arialyy.aria.core.command.CancelCmd
import com.arialyy.aria.core.command.StartCmd import com.arialyy.aria.core.command.StartCmd
import com.arialyy.aria.core.command.StopCmd
import com.arialyy.aria.core.processor.IHttpFileLenAdapter import com.arialyy.aria.core.processor.IHttpFileLenAdapter
import com.arialyy.aria.core.task.DownloadTask import com.arialyy.aria.core.task.DownloadTask
import com.arialyy.aria.core.task.ITaskInterceptor import com.arialyy.aria.core.task.ITaskInterceptor
@ -26,6 +28,7 @@ import com.arialyy.aria.core.task.TaskCachePool
import com.arialyy.aria.http.HttpBaseStartController import com.arialyy.aria.http.HttpBaseStartController
import com.arialyy.aria.http.HttpOption import com.arialyy.aria.http.HttpOption
import com.arialyy.aria.http.HttpUtil import com.arialyy.aria.http.HttpUtil
import timber.log.Timber
import java.net.HttpURLConnection import java.net.HttpURLConnection
/** /**
@ -77,10 +80,17 @@ class HttpDStartController(target: Any, val url: String) : HttpBaseStartControll
return this return this
} }
private fun createTask(): DownloadTask { private fun getTask(createNewTask: Boolean = true): DownloadTask? {
if (HttpUtil.checkHttpDParams(httpTaskOption)) { if (HttpUtil.checkHttpDParams(httpTaskOption)) {
throw IllegalArgumentException("invalid params") throw IllegalArgumentException("invalid params")
} }
val tempTask = TaskCachePool.getTaskByUrl(url)
if (tempTask != null) {
return tempTask as DownloadTask
}
if (!createNewTask) {
return null
}
val task = DownloadTask(httpTaskOption) val task = DownloadTask(httpTaskOption)
task.adapter = HttpDTaskAdapter() task.adapter = HttpDTaskAdapter()
TaskCachePool.putTask(task) TaskCachePool.putTask(task)
@ -91,22 +101,39 @@ class HttpDStartController(target: Any, val url: String) : HttpBaseStartControll
if (!HttpUtil.checkHttpDParams(httpTaskOption)) { if (!HttpUtil.checkHttpDParams(httpTaskOption)) {
return -1 return -1
} }
val task = createTask() val task = getTask()
val resp = AddCmd(task).executeCmd() val resp = AddCmd(task).executeCmd()
return if (resp.isInterrupt()) -1 else task.taskId return if (resp.isInterrupt()) -1 else task?.taskId ?: -1
} }
fun start(): Int { fun start(): Int {
if (!HttpUtil.checkHttpDParams(httpTaskOption)) { if (!HttpUtil.checkHttpDParams(httpTaskOption)) {
return -1 return -1
} }
val task = createTask() val task = getTask()
val resp = StartCmd(task).executeCmd() val resp = StartCmd(task).executeCmd()
return if (resp.isInterrupt()) -1 else task.taskId return if (resp.isInterrupt()) -1 else task?.taskId ?: -1
} }
fun resume(): Int { fun resume(): Int {
TaskCachePool.findTaskByPath(url)
return start() return start()
} }
fun cancel() {
val task = getTask(true)
if (task == null) {
Timber.e("not found task, url: $url")
return
}
CancelCmd(task).executeCmd()
}
fun stop() {
val task = getTask(false)
if (task == null) {
Timber.e("task not running, url: $url")
return
}
StopCmd(task).executeCmd()
}
} }

@ -16,8 +16,13 @@
package com.arialyy.aria.http.download package com.arialyy.aria.http.download
import android.net.Uri 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.command.StopCmd
import com.arialyy.aria.core.task.TaskCachePool import com.arialyy.aria.core.task.TaskCachePool
import com.arialyy.aria.util.FileUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import timber.log.Timber import timber.log.Timber
/** /**
@ -28,16 +33,16 @@ import timber.log.Timber
class HttpDStopController(val taskId: Int) { class HttpDStopController(val taskId: Int) {
fun cancel() { fun cancel() {
val task = TaskCachePool.getTask(taskId) val task = TaskCachePool.getTaskById(taskId)
if (task == null) { if (task == null) {
Timber.e("task not found, taskId: $taskId") Timber.e("task not found, taskId: $taskId")
return return
} }
HttpDStopController2(Uri.parse(task.filePath)).cancel() CancelCmd(task).executeCmd()
} }
fun stop() { fun stop() {
val task = TaskCachePool.getTask(taskId) val task = TaskCachePool.getTaskById(taskId)
if (task == null) { if (task == null) {
Timber.e("task not found, taskId: $taskId") Timber.e("task not found, taskId: $taskId")
return return
@ -46,7 +51,7 @@ class HttpDStopController(val taskId: Int) {
} }
fun resume() { fun resume() {
val task = TaskCachePool.getTask(taskId) val task = TaskCachePool.getTaskById(taskId)
if (task == null) { if (task == null) {
Timber.e("task not found, taskId: $taskId") Timber.e("task not found, taskId: $taskId")
return return

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

@ -15,7 +15,6 @@
*/ */
package com.arialyy.aria.http.download package com.arialyy.aria.http.download
import android.net.Uri
import com.arialyy.annotations.TaskEnum import com.arialyy.annotations.TaskEnum
import com.arialyy.annotations.TaskEnum.DOWNLOAD import com.arialyy.annotations.TaskEnum.DOWNLOAD
import com.arialyy.aria.core.inf.IDownloader import com.arialyy.aria.core.inf.IDownloader
@ -47,12 +46,4 @@ class HttpDownloader(val target: Any) : IDownloader {
return HttpDStopController(taskId) return HttpDStopController(taskId)
} }
/**
* stop, cancel a task
* @param filePath filePath
*/
fun load(filePath: Uri): HttpDStopController2 {
return HttpDStopController2(filePath)
}
} }

@ -34,6 +34,10 @@ final public class StartCmd extends AbsCmd {
Timber.w("interruption occurred, cancel cmd"); Timber.w("interruption occurred, cancel cmd");
return resp; return resp;
} }
if (mTask.isRunning()) {
Timber.w("task is running");
return resp;
}
getTaskQueue().startTask(mTask); getTaskQueue().startTask(mTask);
return resp; return resp;
} }

@ -15,7 +15,6 @@
*/ */
package com.arialyy.aria.core.inf package com.arialyy.aria.core.inf
/** /**
* @Author laoyuyu * @Author laoyuyu
* @Description * @Description
@ -40,4 +39,6 @@ abstract class BaseEntity : IEntity {
* extended Information * extended Information
*/ */
var ext: String? = null var ext: String? = null
val fileSize: Long = 0
} }

@ -16,7 +16,6 @@
package com.arialyy.aria.core.task; package com.arialyy.aria.core.task;
import android.net.Uri;
import com.arialyy.aria.core.common.TaskOption; import com.arialyy.aria.core.common.TaskOption;
import java.util.Objects; import java.util.Objects;
@ -30,14 +29,6 @@ public class DownloadTask extends AbsTask {
super(taskOption); super(taskOption);
} }
public Uri getSavePath() {
return getTaskOption(TaskOption.class).getSavePathUri();
}
public String getSourceUrl() {
return getTaskOption(TaskOption.class).getSourUrl();
}
/** /**
* 获取当前下载任务的下载地址 * 获取当前下载任务的下载地址
*/ */
@ -45,6 +36,10 @@ public class DownloadTask extends AbsTask {
return ITask.DOWNLOAD; return ITask.DOWNLOAD;
} }
@Override public String getUrl() {
return getTaskOption(TaskOption.class).getSourUrl();
}
@Override public String getFilePath() { @Override public String getFilePath() {
return Objects.requireNonNull(getTaskOption(TaskOption.class).getSavePathUri()).toString(); return Objects.requireNonNull(getTaskOption(TaskOption.class).getSavePathUri()).toString();
} }

@ -119,6 +119,8 @@ public interface ITask {
int getTaskId(); int getTaskId();
String getUrl();
/** /**
* @return task unique identifier, like: savePath * @return task unique identifier, like: savePath
*/ */

@ -33,29 +33,28 @@ object TaskCachePool {
*/ */
private val entityMap = ConcurrentHashMap<Int, BaseEntity>() private val entityMap = ConcurrentHashMap<Int, BaseEntity>()
private val taskAdapterMap = ConcurrentHashMap<Uri, ITaskAdapter>() private val taskAdapterMap = ConcurrentHashMap<Uri, ITaskAdapter>()
private val taskMap = ConcurrentHashMap<Int, ITask>()
fun removeTask(taskId: Int) { /**
taskMap.remove(taskId) * task cache map; key: url
*/
private val taskMap = ConcurrentHashMap<String, ITask>()
fun removeTask(url: String) {
taskMap.remove(url)
} }
/** /**
* if task is completed, stopped, canceled, return null * if task is completed, stopped, canceled, return null
*/ */
fun getTask(taskId: Int) = taskMap[taskId] fun getTaskByUrl(url: String) = taskMap[url]
fun putTask(task: ITask) { fun getTaskById(taskId: Int): ITask? {
taskMap[task.taskId] = task return taskMap.values.find { it.taskId == taskId }
taskAdapterMap[Uri.parse(task.filePath)] = task.adapter
} }
/** fun putTask(task: ITask) {
* find task by url taskMap[task.url] = task
*/ taskAdapterMap[Uri.parse(task.filePath)] = task.adapter
fun findTaskByUrl(url:String):ITask?{
taskMap.values.forEach {
if (it.getTaskOption().)
}
} }
/** /**

@ -16,6 +16,7 @@
package com.arialyy.aria.core.task package com.arialyy.aria.core.task
import com.arialyy.aria.core.config.Configuration import com.arialyy.aria.core.config.Configuration
import com.arialyy.aria.core.inf.BaseEntity
import com.arialyy.aria.core.inf.IEntity import com.arialyy.aria.core.inf.IEntity
import com.arialyy.aria.orm.entity.BlockRecord import com.arialyy.aria.orm.entity.BlockRecord
import com.arialyy.aria.orm.entity.TaskRecord import com.arialyy.aria.orm.entity.TaskRecord
@ -30,6 +31,12 @@ class TaskState {
lateinit var taskRecord: TaskRecord lateinit var taskRecord: TaskRecord
var entity: BaseEntity? = null
set(value) {
fileSize = value?.fileSize ?: 0
field = value
}
/** /**
* need to try again?default: false * need to try again?default: false
*/ */

@ -47,9 +47,7 @@ data class DEntity(
*/ */
val savePath: Uri, val savePath: Uri,
val isSub: Boolean = false, val isSub: Boolean = false
val fileSize: Long = 0,
) : BaseEntity() { ) : BaseEntity() {
override fun update() { override fun update() {

Loading…
Cancel
Save