From 6b8c051b30298424820f91b022cf005d9878b51a Mon Sep 17 00:00:00 2001 From: laoyuyu Date: Mon, 20 Mar 2023 20:37:14 +0800 Subject: [PATCH] Subtask Status Handling --- .../aria/http/download/HttpDEventListener.kt | 17 +------- .../arialyy/dua/group/HttpSubBlockManager.kt | 41 ++++++++++++++++++- .../aria/core/listener/AbsEventListener.java | 4 +- .../arialyy/aria/core/task/TaskCachePool.kt | 24 +++++------ .../java/com/arialyy/aria/util/BlockUtil.kt | 25 +++++++++++ 5 files changed, 81 insertions(+), 30 deletions(-) diff --git a/Http/src/main/java/com/arialyy/aria/http/download/HttpDEventListener.kt b/Http/src/main/java/com/arialyy/aria/http/download/HttpDEventListener.kt index d80b9223..e8dbbb71 100644 --- a/Http/src/main/java/com/arialyy/aria/http/download/HttpDEventListener.kt +++ b/Http/src/main/java/com/arialyy/aria/http/download/HttpDEventListener.kt @@ -49,22 +49,9 @@ class HttpDEventListener(task: SingleDownloadTask) : AbsEventListener(task) { saveData(IEntity.STATE_COMPLETE, task.taskState.fileSize) } - /** - * 1.remove all block - * 2.remove record - */ - override fun handleCancel() { - val file = FileUri.getPathByUri(task.taskState.taskRecord.filePath)?.let { File(it) } - file?.parentFile?.let { - FileUtils.deleteDir(it) - } - DuaContext.duaScope.launch(Dispatchers.IO) { - val entity = TaskCachePool.getEntity(taskId = task.taskId) - val db = DuaContext.getServiceManager().getDbService().getDuaDb() - db.getRecordDao().deleteTaskRecord(task.taskState.taskRecord) - db.getDEntityDao().delete(entity as DEntity) - } + override fun handleCancel() { + BlockUtil.removeTaskBlock(task) } } \ No newline at end of file diff --git a/HttpGroup/src/main/java/com/arialyy/dua/group/HttpSubBlockManager.kt b/HttpGroup/src/main/java/com/arialyy/dua/group/HttpSubBlockManager.kt index c8b30dc8..0d41ea71 100644 --- a/HttpGroup/src/main/java/com/arialyy/dua/group/HttpSubBlockManager.kt +++ b/HttpGroup/src/main/java/com/arialyy/dua/group/HttpSubBlockManager.kt @@ -18,10 +18,16 @@ package com.arialyy.dua.group import android.os.Handler import android.os.Looper import com.arialyy.aria.core.inf.IBlockManager +import com.arialyy.aria.core.inf.IEntity import com.arialyy.aria.core.inf.ITaskManager import com.arialyy.aria.core.task.ITask +import com.arialyy.aria.core.task.TaskCachePool.removeTask +import com.arialyy.aria.core.task.TaskCachePool.updateState +import com.arialyy.aria.core.task.TaskState +import com.arialyy.aria.exception.AriaException import com.arialyy.aria.http.HttpTaskOption import com.arialyy.aria.http.download.HttpDOptionAdapter +import com.arialyy.aria.util.BlockUtil import timber.log.Timber /** @@ -36,6 +42,7 @@ internal class HttpSubBlockManager(private val task: ITask, private val groupHan private var isStop = false private var isCancel = false + private var progress: Long = 0L /** * Pass the message to the group task after the subtask is stopped @@ -44,22 +51,55 @@ internal class HttpSubBlockManager(private val task: ITask, private val groupHan when (msg.what) { ITaskManager.STATE_STOP -> { isStop = true + saveData(IEntity.STATE_STOP) + quitLooper() } ITaskManager.STATE_CANCEL -> { isCancel = true + removeTask(task) + BlockUtil.removeTaskBlock(task) + quitLooper() } ITaskManager.STATE_FAIL -> { } ITaskManager.STATE_COMPLETE -> { + saveData(IEntity.STATE_COMPLETE) + val b = BlockUtil.mergeFile(task.taskState.taskRecord) + + if (!b) { + Timber.e("merge block fail") + onFail(false, AriaException("merge block fail")) + return + } + task.taskState.speed = 0 + saveData(IEntity.STATE_COMPLETE) } ITaskManager.STATE_RUNNING -> { } ITaskManager.STATE_UPDATE_PROGRESS -> { + val b = msg.data + if (b != null) { + val len = b.getLong(ITaskManager.DATA_ADD_LEN, 0) + progress += len + task.taskState.speed = len + task.taskState.curProgress = progress + } } } false } + private fun saveData(state: Int) { + val ts: TaskState = task.taskState + ts.state = state + ts.curProgress = progress + if (state == IEntity.STATE_COMPLETE) { + ts.curProgress = ts.fileSize + removeTask(task) + } + updateState(task.taskId, state, progress) + } + override fun getHandler() = handler /** @@ -95,5 +135,4 @@ internal class HttpSubBlockManager(private val task: ITask, private val groupHan override fun setBlockNum(blockNum: Int) { Timber.i("Subtasks do not support chunked downloads") } - } \ No newline at end of file diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/listener/AbsEventListener.java b/PublicComponent/src/main/java/com/arialyy/aria/core/listener/AbsEventListener.java index 9d8e42f7..af52586f 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/core/listener/AbsEventListener.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/core/listener/AbsEventListener.java @@ -141,11 +141,11 @@ public abstract class AbsEventListener implements IEventListener { if (state == IEntity.STATE_CANCEL) { handleCancel(); - TaskCachePool.INSTANCE.removeTask(getTask().getTaskId()); + TaskCachePool.INSTANCE.removeTask(getTask()); return; } if (state == IEntity.STATE_COMPLETE) { - TaskCachePool.INSTANCE.removeTask(getTask().getTaskId()); + TaskCachePool.INSTANCE.removeTask(getTask()); } TaskCachePool.INSTANCE.updateState(mTask.getTaskId(), state, location); diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/task/TaskCachePool.kt b/PublicComponent/src/main/java/com/arialyy/aria/core/task/TaskCachePool.kt index a6961cc8..94ed4621 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/core/task/TaskCachePool.kt +++ b/PublicComponent/src/main/java/com/arialyy/aria/core/task/TaskCachePool.kt @@ -32,21 +32,21 @@ object TaskCachePool { */ private val entityMap = ConcurrentHashMap() - /** - * task cache map; key: if task is [DownloadGroupTask], it's filePath else it's service url - */ private val taskMap = ConcurrentHashMap() - /** - * @param key if task is [DownloadGroupTask], it's filePath else it's service url - */ - fun removeTask(key: String) { - taskMap.remove(key) + fun removeTask(task: ITask) { + when { + task is SingleDownloadTask -> { + taskMap.remove(task.url) + } + task::javaClass.name == "com.arialyy.dua.group.HttpDGroupTask" -> { + taskMap.remove(task.filePath) + } + } } /** * if task is completed, stopped, canceled, return null - * @param key if task is [DownloadGroupTask], it's filePath else it's service url */ fun getTaskByKey(key: String) = taskMap[key] @@ -55,11 +55,11 @@ object TaskCachePool { } fun putTask(task: ITask) { - when (task) { - is SingleDownloadTask -> { + when { + task is SingleDownloadTask -> { taskMap[task.url] = task } - is com.arialyy.dua.group.DownloadGroupTask -> { + task::javaClass.name == "com.arialyy.dua.group.HttpDGroupTask" -> { taskMap[task.filePath] = task } } diff --git a/PublicComponent/src/main/java/com/arialyy/aria/util/BlockUtil.kt b/PublicComponent/src/main/java/com/arialyy/aria/util/BlockUtil.kt index 44bab4e2..b1ed24e0 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/util/BlockUtil.kt +++ b/PublicComponent/src/main/java/com/arialyy/aria/util/BlockUtil.kt @@ -1,8 +1,14 @@ package com.arialyy.aria.util import android.net.Uri +import com.arialyy.aria.core.DuaContext +import com.arialyy.aria.core.task.ITask +import com.arialyy.aria.core.task.TaskCachePool import com.arialyy.aria.orm.entity.BlockRecord +import com.arialyy.aria.orm.entity.DEntity import com.arialyy.aria.orm.entity.TaskRecord +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import timber.log.Timber import java.io.File import java.io.FileInputStream @@ -25,6 +31,25 @@ import java.io.FileOutputStream */ object BlockUtil { + + /** + * 1.remove all block + * 2.remove record + */ + fun removeTaskBlock(task: ITask) { + val file = FileUri.getPathByUri(task.taskState.taskRecord.filePath)?.let { File(it) } + file?.parentFile?.let { + FileUtils.deleteDir(it) + } + + DuaContext.duaScope.launch(Dispatchers.IO) { + val entity = TaskCachePool.getEntity(taskId = task.taskId) + val db = DuaContext.getServiceManager().getDbService().getDuaDb() + db.getRecordDao().deleteTaskRecord(task.taskState.taskRecord) + db.getDEntityDao().delete(entity as DEntity) + } + } + fun getBlockPathFormUri(fileSaveUri: Uri, blockId: Int): String { val filePath = FileUri.getPathByUri(fileSaveUri) ?: "/" val fileName = FileUtils.getFileNameFromPath(filePath)