Code optimization

v4
laoyuyu 2 years ago
parent 3ac7b0f211
commit 5d0f59f7e9
  1. 13
      Aria/src/main/java/com/arialyy/aria/core/common/RoomProvider.kt
  2. 79
      Aria/src/main/java/com/arialyy/aria/core/manager/DGTaskWrapperFactory.java
  3. 109
      Aria/src/main/java/com/arialyy/aria/core/manager/DTaskWrapperFactory.java
  4. 84
      Aria/src/main/java/com/arialyy/aria/core/manager/SubTaskManager.java
  5. 156
      Aria/src/main/java/com/arialyy/aria/core/manager/TaskWrapperManager.java
  6. 64
      Aria/src/main/java/com/arialyy/aria/core/manager/UTaskWrapperFactory.java
  7. 18
      Http/src/main/java/com/arialyy/aria/http/HttpTaskOption.kt
  8. 15
      Http/src/main/java/com/arialyy/aria/http/HttpUtil.kt
  9. 14
      Http/src/main/java/com/arialyy/aria/http/IHttpTaskOptionAdapter.kt
  10. 13
      Http/src/main/java/com/arialyy/aria/http/download/HttpBlockThreadInterceptor.kt
  11. 2
      Http/src/main/java/com/arialyy/aria/http/download/HttpDBTaskAdapter.kt
  12. 13
      Http/src/main/java/com/arialyy/aria/http/download/HttpDBlockInterceptor.kt
  13. 62
      Http/src/main/java/com/arialyy/aria/http/download/HttpDCheckInterceptor.kt
  14. 88
      Http/src/main/java/com/arialyy/aria/http/download/HttpDGLoader.java
  15. 24
      Http/src/main/java/com/arialyy/aria/http/download/HttpDHeaderInterceptor.kt
  16. 42
      Http/src/main/java/com/arialyy/aria/http/download/HttpDOptionAdapter.kt
  17. 29
      Http/src/main/java/com/arialyy/aria/http/download/HttpDStartController.kt
  18. 6
      Http/src/main/java/com/arialyy/aria/http/download/HttpDTaskAdapter.kt
  19. 6
      Http/src/main/java/com/arialyy/aria/http/download/TimerInterceptor.kt
  20. 4
      Http/src/main/java/com/arialyy/aria/http/upload/HttpUTaskAdapter.kt
  21. 47
      HttpGroup/src/main/java/com/arialyy/dua/group/HttpDGCheckInterceptor.kt
  22. 40
      HttpGroup/src/main/java/com/arialyy/dua/group/HttpDGComponentLoader.kt
  23. 24
      HttpGroup/src/main/java/com/arialyy/dua/group/HttpDGEventListener.kt
  24. 2
      HttpGroup/src/main/java/com/arialyy/dua/group/HttpDGInfoTask.java
  25. 30
      HttpGroup/src/main/java/com/arialyy/dua/group/HttpDGLoader.kt
  26. 19
      HttpGroup/src/main/java/com/arialyy/dua/group/HttpDGOptionAdapter.kt
  27. 83
      HttpGroup/src/main/java/com/arialyy/dua/group/HttpDGStartController.kt
  28. 84
      HttpGroup/src/main/java/com/arialyy/dua/group/HttpDGroupAdapter.kt
  29. 2
      HttpGroup/src/main/java/com/arialyy/dua/group/HttpSubDLoaderAdapter.java
  30. 4
      PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsGroupLoader.java
  31. 20
      PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSchedulers.java
  32. 78
      PublicComponent/src/main/java/com/arialyy/aria/core/inf/ITaskManager.kt
  33. 6
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsNormalLoader.java
  34. 10
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/GroupSubThreadStateManager.java
  35. 4
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/ILoaderVisitor.java
  36. 4
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/LoaderStructure.java
  37. 4
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/NormalLoader.java
  38. 6
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/NormalTTBuilder.java
  39. 22
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/SubLoader.java
  40. 6
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/TaskThreadStateManager.java
  41. 6
      PublicComponent/src/main/java/com/arialyy/aria/core/task/AbsTaskAdapter.kt
  42. 31
      PublicComponent/src/main/java/com/arialyy/aria/core/task/DBlockManager.kt
  43. 9
      PublicComponent/src/main/java/com/arialyy/aria/core/task/DownloadGroupTask.java
  44. 4
      PublicComponent/src/main/java/com/arialyy/aria/core/task/TaskChain.kt
  45. 34
      PublicComponent/src/main/java/com/arialyy/aria/core/task/ThreadTask.java
  46. 18
      PublicComponent/src/main/java/com/arialyy/aria/core/task/ThreadTask2.kt
  47. 2
      PublicComponent/src/main/java/com/arialyy/aria/orm/entity/DEntity.kt
  48. 155
      PublicComponent/src/main/java/com/arialyy/aria/util/DbDataHelper.java
  49. 129
      PublicComponent/src/main/java/com/arialyy/aria/util/DeleteDGRecord.java
  50. 131
      PublicComponent/src/main/java/com/arialyy/aria/util/DeleteDRecord.java
  51. 151
      PublicComponent/src/main/java/com/arialyy/aria/util/DeleteM3u8Record.java
  52. 99
      PublicComponent/src/main/java/com/arialyy/aria/util/DeleteURecord.java

@ -1,13 +0,0 @@
package com.arialyy.aria.core.common
import com.arialyy.aria.core.provider.IdbProvider
/**
* @Author laoyuyu
* @Description
* @Date 5:27 PM 2023/1/13
**/
class RoomProvider : IdbProvider {
override fun initDb() {
}
}

@ -1,79 +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.manager;
import com.arialyy.aria.core.download.DGEntityWrapper;
import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.util.DbDataHelper;
import java.util.List;
/**
* Created by Aria.Lao on 2017/11/1. 组合任务wrapper
*/
class DGTaskWrapperFactory implements IGroupWrapperFactory<DownloadGroupEntity, DGTaskWrapper> {
private final String TAG = CommonUtil.getClassName(this);
private static volatile DGTaskWrapperFactory INSTANCE = null;
private DGTaskWrapperFactory() {
}
public static DGTaskWrapperFactory getInstance() {
if (INSTANCE == null) {
synchronized (DGTaskWrapperFactory.class) {
INSTANCE = new DGTaskWrapperFactory();
}
}
return INSTANCE;
}
@Override public DGTaskWrapper getGroupWrapper(long taskId) {
DGTaskWrapper wrapper;
if (taskId == -1) {
wrapper = new DGTaskWrapper(new DownloadGroupEntity());
} else {
DownloadGroupEntity entity = getOrCreateHttpDGEntity(taskId);
wrapper = new DGTaskWrapper(entity);
if (entity.getSubEntities() != null && !entity.getSubEntities().isEmpty()) {
wrapper.setSubTaskWrapper(DbDataHelper.createDGSubTaskWrapper(entity));
}
}
wrapper.setRequestType(wrapper.getEntity().getTaskType());
return wrapper;
}
/**
* 获取组合任务实体 如果数据库不存在该实体则新创建一个新的任务组实体
*/
private DownloadGroupEntity getOrCreateHttpDGEntity(long taskId) {
List<DGEntityWrapper> wrapper =
DbEntity.findRelationData(DGEntityWrapper.class, "DownloadGroupEntity.rowid=?",
String.valueOf(taskId));
DownloadGroupEntity groupEntity;
if (wrapper != null && !wrapper.isEmpty()) {
groupEntity = wrapper.get(0).groupEntity;
if (groupEntity == null) {
groupEntity = new DownloadGroupEntity();
}
} else {
groupEntity = new DownloadGroupEntity();
}
return groupEntity;
}
}

@ -1,109 +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.manager;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import java.io.File;
/**
* 创建下载任务wrapper Created by Aria.Lao on 2017/11/1.
*/
class DTaskWrapperFactory implements INormalTEFactory<DownloadEntity, DTaskWrapper> {
private final String TAG = "DTaskWrapperFactory";
private static volatile DTaskWrapperFactory INSTANCE = null;
private DTaskWrapperFactory() {
}
public static DTaskWrapperFactory getInstance() {
if (INSTANCE == null) {
synchronized (DTaskWrapperFactory.class) {
INSTANCE = new DTaskWrapperFactory();
}
}
return INSTANCE;
}
/**
* 通过下载地址创建任务实体
*/
@Override public DTaskWrapper create(long taskId) {
DTaskWrapper wrapper;
if (taskId == -1) {
wrapper = new DTaskWrapper(new DownloadEntity());
} else {
wrapper = new DTaskWrapper(getEntity(taskId));
}
wrapper.setRequestType(wrapper.getEntity().getTaskType());
return wrapper;
}
/**
* 如果任务存在但是下载实体不存在则通过下载地址获取下载实体
*/
private DownloadEntity getEntity(long taskId) {
DownloadEntity entity =
DownloadEntity.findFirst(DownloadEntity.class, "rowid=? and isGroupChild='false'",
String.valueOf(taskId));
if (entity == null) {
entity = new DownloadEntity();
return entity;
}
File file = new File(entity.getFilePath());
if (!entity.isComplete()) {
TaskRecord record =
TaskRecord.findFirst(TaskRecord.class, "filePath=?", entity.getFilePath());
if (record == null) {
resetEntity(entity);
} else {
if (record.isBlock) {
int count = 0;
for (int i = 0, len = record.threadNum; i < len; i++) {
File temp = new File(String.format(IRecordHandler.SUB_PATH, record.filePath, i));
if (!temp.exists()) {
count++;
}
}
if (count == record.threadNum) {
resetEntity(entity);
}
} else if (!file.exists()
&& record.taskType != ITaskWrapper.M3U8_VOD) { // 非分块文件需要判断文件是否存在
resetEntity(entity);
}
}
}
return entity;
}
/**
* 初始化下载实体
*/
private void resetEntity(DownloadEntity entity) {
entity.setPercent(0);
entity.setCompleteTime(0);
entity.setComplete(false);
entity.setCurrentProgress(0);
entity.setState(IEntity.STATE_WAIT);
}
}

@ -1,84 +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.manager;
import android.text.TextUtils;
import com.arialyy.aria.core.command.GroupCmdFactory;
import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.aria.core.event.EventMsgUtil;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.core.command.CmdHelper;
import java.util.List;
/**
* Created by lyy on 2017/9/4.
* 子任务管理器
*/
public class SubTaskManager {
private final String TAG = getClass().getSimpleName();
private DGTaskWrapper mEntity;
public SubTaskManager(DGTaskWrapper entity) {
mEntity = entity;
}
/**
* 启动任务组中的子任务
*
* @param url 子任务下载地址
*/
public void startSubTask(String url) {
if (checkUrl(url)) {
EventMsgUtil.getDefault().post(
CmdHelper.createGroupCmd(mEntity, GroupCmdFactory.SUB_TASK_START, url));
}
}
/**
* 停止任务组中的子任务
*
* @param url 子任务下载地址
*/
public void stopSubTask(String url) {
if (checkUrl(url)) {
EventMsgUtil.getDefault().post(
CmdHelper.createGroupCmd(mEntity, GroupCmdFactory.SUB_TASK_STOP, url));
}
}
/**
* 检查任务地址
*
* @param url 子任务地址
* @return {@code false} 任务地址不合法
*/
private boolean checkUrl(String url) {
if (TextUtils.isEmpty(url)) {
ALog.e(TAG, "子任务地址不能为null");
return false;
}
List<String> urls = mEntity.getEntity().getUrls();
if (urls == null || urls.isEmpty()) {
ALog.e(TAG, "任务组任务链接为null");
return false;
}
if (!urls.contains(url)) {
ALog.e(TAG, "任务组中没有改Url【+ " + url + "】");
return false;
}
return true;
}
}

@ -1,156 +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.manager;
import android.util.LruCache;
import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Created by Aria.Lao on 2017/11/1. 任务实体管理器
*/
public class TaskWrapperManager {
private static final String TAG = "TaskWrapperManager";
private static volatile TaskWrapperManager INSTANCE = null;
private LruCache<String, AbsTaskWrapper> cache = new LruCache<>(1024);
private Lock lock;
public static TaskWrapperManager getInstance() {
if (INSTANCE == null) {
synchronized (TaskWrapperManager.class) {
if (INSTANCE == null) {
INSTANCE = new TaskWrapperManager();
}
}
}
return INSTANCE;
}
private TaskWrapperManager() {
lock = new ReentrantLock();
}
private IGroupWrapperFactory chooseGroupFactory(Class clazz) {
if (clazz == DGTaskWrapper.class) {
return DGTaskWrapperFactory.getInstance();
}
return null;
}
private INormalTEFactory chooseNormalFactory(Class clazz) {
if (clazz == DTaskWrapper.class) {
return DTaskWrapperFactory.getInstance();
} else if (clazz == UTaskWrapper.class) {
return UTaskWrapperFactory.getInstance();
}
return null;
}
/**
* 获取普通任务的Wrapper
*
* @return 创建失败返回null成功返回{@link DTaskWrapper}或者{@link UTaskWrapper}
*/
public <TW extends AbsTaskWrapper> TW getNormalTaskWrapper(Class<TW> clazz, long taskId) {
final Lock lock = this.lock;
lock.lock();
try {
AbsTaskWrapper wrapper = cache.get(convertKey(clazz, taskId));
if (wrapper == null || wrapper.getClass() != clazz) {
INormalTEFactory factory = chooseNormalFactory(clazz);
if (factory == null) {
ALog.e(TAG, "任务实体创建失败");
return null;
}
wrapper = factory.create(taskId);
putTaskWrapper(wrapper);
}
return (TW) wrapper;
} finally {
lock.unlock();
}
}
/**
* 从缓存中获取HTTP任务组的任务实体如果任务实体不存在则创建任务实体 获取{}
*
* @param taskId 任务ID
* @return 地址列表为null或创建实体失败返回null成功返回{@link DGTaskWrapper}
*/
public <TW extends AbsTaskWrapper> TW getGroupWrapper(Class<TW> clazz, long taskId) {
final Lock lock = this.lock;
lock.lock();
try {
AbsTaskWrapper tWrapper = cache.get(convertKey(clazz, taskId));
if (tWrapper == null || tWrapper.getClass() != clazz) {
IGroupWrapperFactory factory = chooseGroupFactory(clazz);
if (factory == null) {
ALog.e(TAG, "任务实体创建失败");
return null;
}
tWrapper = factory.getGroupWrapper(taskId);
putTaskWrapper(tWrapper);
}
return (TW) tWrapper;
} finally {
lock.unlock();
}
}
/**
* 更新任务Wrapper
*/
public void putTaskWrapper(AbsTaskWrapper wrapper) {
if (wrapper == null) {
ALog.e(TAG, "任务实体添加失败");
return;
}
if (wrapper.getEntity() == null || wrapper.getEntity().getId() == -1) {
return;
}
final Lock lock = this.lock;
lock.lock();
try {
cache.put(convertKey(wrapper.getClass(), wrapper.getEntity().getId()), wrapper);
} finally {
lock.unlock();
}
}
/**
* 通过key删除任务实体 当任务complete或删除记录时将删除缓存
*/
public void removeTaskWrapper(AbsTaskWrapper wrapper) {
final Lock lock = this.lock;
lock.lock();
try {
cache.remove(convertKey(wrapper.getClass(), wrapper.getEntity().getId()));
} finally {
lock.unlock();
}
}
private String convertKey(Class clazz, long taskId) {
return CommonUtil.keyToHashKey(clazz.getName() + taskId);
}
}

@ -1,64 +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.manager;
import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.util.ALog;
/**
* Created by Aria.Lao on 2017/11/1. 任务实体工厂
*/
class UTaskWrapperFactory implements INormalTEFactory<UploadEntity, UTaskWrapper> {
private static final String TAG = "UTaskWrapperFactory";
private static volatile UTaskWrapperFactory INSTANCE = null;
private UTaskWrapperFactory() {
}
public static UTaskWrapperFactory getInstance() {
if (INSTANCE == null) {
synchronized (UTaskWrapperFactory.class) {
INSTANCE = new UTaskWrapperFactory();
}
}
return INSTANCE;
}
@Override public UTaskWrapper create(long taskId) {
UTaskWrapper wrapper;
if (taskId == -1) {
wrapper = new UTaskWrapper(new UploadEntity());
} else {
wrapper = new UTaskWrapper(getUploadEntity(taskId));
}
wrapper.setRequestType(wrapper.getEntity().getTaskType());
return wrapper;
}
/**
* 从数据中读取上传实体如果数据库查不到则新创建一个上传实体
*/
private UploadEntity getUploadEntity(long taskId) {
UploadEntity entity =
UploadEntity.findFirst(UploadEntity.class, "rowid=?", String.valueOf(taskId));
if (entity == null) {
entity = new UploadEntity();
}
return entity;
}
}

@ -16,7 +16,6 @@
package com.arialyy.aria.http
import com.arialyy.aria.core.common.TaskOption
import com.arialyy.aria.core.processor.IHttpFileLenAdapter
import com.arialyy.aria.core.task.ITaskInterceptor
/**
@ -27,19 +26,10 @@ import com.arialyy.aria.core.task.ITaskInterceptor
class HttpTaskOption : TaskOption() {
var httpOption: HttpOption? = null
var fileSizeAdapter: IHttpFileLenAdapter? = null
var taskInterceptor = mutableListOf<ITaskInterceptor>()
var isChunkTask = false
lateinit var taskOptionAdapter: IHttpTaskOptionAdapter
/**
* whether block is supported, true: supported
*/
var isSupportResume = true
/**
* whether resume task is supported
* 1. in download task, if file length not obtained, isSupportResume = false
* 2. in upload task, if service not supported resume, isSupportResume = false
*/
var isSupportBlock = true
fun <T : IHttpTaskOptionAdapter> getOptionAdapter(clazz: Class<T>): T {
return taskOptionAdapter as T
}
}

@ -15,11 +15,7 @@
*/
package com.arialyy.aria.http
import android.net.Uri
import android.text.TextUtils
import com.arialyy.aria.core.inf.ITaskAdapter
import com.arialyy.aria.core.task.TaskCachePool
import com.arialyy.aria.http.download.HttpDTaskAdapter
import com.arialyy.aria.util.FileUtils
import com.arialyy.aria.util.Regular
import timber.log.Timber
@ -35,16 +31,7 @@ import java.util.zip.InflaterInputStream
* @Description
* @Date 12:40 PM 2023/1/22
**/
internal object HttpUtil {
fun getDTaskUtil(filePath: Uri): ITaskAdapter {
var util = TaskCachePool.getTaskAdapter(filePath)
if (util == null) {
util = HttpDTaskAdapter()
TaskCachePool.putTaskUtil(filePath, util)
}
return util
}
object HttpUtil {
/**
* 拦截window.location.replace数据

@ -13,11 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.inf;
package com.arialyy.aria.http
public interface Suggest {
String TASK_CONTROLLER = "after use #add()、#create()、#stop()、#cancel()、#resume()、#save()?";
String TO_CONTROLLER = "after use #controller()?";
}
/**
* @Author laoyuyu
* @Description
* @Date 8:03 PM 2023/3/6
**/
interface IHttpTaskOptionAdapter

@ -16,6 +16,8 @@
package com.arialyy.aria.http.download
import com.arialyy.aria.core.DuaContext
import com.arialyy.aria.core.inf.IBlockManager
import com.arialyy.aria.core.task.BlockManager
import com.arialyy.aria.core.task.ITaskInterceptor
import com.arialyy.aria.core.task.IThreadTask
import com.arialyy.aria.core.task.TaskChain
@ -31,9 +33,11 @@ import com.arialyy.aria.orm.entity.BlockRecord
* @Date 7:11 PM 2023/2/7
**/
class HttpBlockThreadInterceptor : ITaskInterceptor {
private lateinit var blockManager: IBlockManager
override suspend fun interceptor(chain: TaskChain): TaskResp {
val unfinishedBlockList = chain.blockManager.unfinishedBlockList
blockManager = chain.blockManager as IBlockManager
val unfinishedBlockList = blockManager.unfinishedBlockList
if (unfinishedBlockList.isEmpty()) {
return TaskResp(TaskResp.CODE_BLOCK_QUEUE_NULL)
}
@ -49,13 +53,16 @@ class HttpBlockThreadInterceptor : ITaskInterceptor {
val threadConfig = ThreadConfig(it, option, DuaContext.getDConfig().maxSpeed)
threadTaskList.add(
ThreadTask2(
adapter = if (option.isChunkTask) HttpDCTTaskAdapter(threadConfig) else HttpDBTaskAdapter(
adapter = if (option.getOptionAdapter(HttpDOptionAdapter::class.java).isChunkTask) HttpDCTTaskAdapter(
threadConfig
) else HttpDBTaskAdapter(
threadConfig
),
handler = chain.blockManager.handler,
handler = blockManager.getHandler(),
record = it
)
)
}
blockManager.start(threadTaskList)
}
}

@ -43,7 +43,7 @@ class HttpDBTaskAdapter(threadConfig: ThreadConfig) : AbsThreadTaskAdapter(threa
val taskOption = getTaskOption()
val option = taskOption.httpOption!!
val conn = getRequest(option).getDConnection(taskOption.sourUrl!!, option)
if (!taskOption.isSupportResume) {
if (!taskOption.getOptionAdapter(HttpDOptionAdapter::class.java).isSupportResume) {
Timber.w("this task not support resume, url: %s", taskOption.sourUrl)
} else {
conn.setRequestProperty(

@ -17,6 +17,7 @@ package com.arialyy.aria.http.download
import com.arialyy.aria.core.DuaContext
import com.arialyy.aria.core.inf.IBlockManager
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.ITaskInterceptor
@ -45,7 +46,7 @@ internal class HttpDBlockInterceptor : ITaskInterceptor {
override suspend fun interceptor(chain: TaskChain): TaskResp {
task = chain.getTask()
blockManager = chain.blockManager
blockManager = chain.blockManager as IBlockManager
option = task.getTaskOption(HttpTaskOption::class.java)
if (task.taskState.fileSize < 0) {
Timber.e("file size < 0")
@ -60,14 +61,14 @@ internal class HttpDBlockInterceptor : ITaskInterceptor {
// if task not support resume, don't save record
if (task.taskState.fileSize == 0L) {
chain.blockManager.setBlockNum(1)
blockManager.setBlockNum(1)
// if block exist, delete the existed block
removeBlock()
return chain.proceed(chain.getTask())
}
val blockNum = checkRecord()
task.taskState.taskRecord = taskRecord
chain.blockManager.setBlockNum(blockNum)
blockManager.setBlockNum(blockNum)
val result = checkBlock()
if (result != TaskResp.CODE_SUCCESS) {
return TaskResp(result)
@ -126,7 +127,7 @@ internal class HttpDBlockInterceptor : ITaskInterceptor {
* if block already exist, upload progress
*/
private suspend fun checkBlock(): Int {
val handler = blockManager.handler
val handler = blockManager.getHandler()
val needUpdateBlockRecord = mutableSetOf<BlockRecord>()
for (br in taskRecord.blockList) {
val blockF = File(br.blockPath)
@ -134,7 +135,7 @@ internal class HttpDBlockInterceptor : ITaskInterceptor {
if (br.curProgress == blockF.length() && !br.isComplete) {
br.isComplete = true
needUpdateBlockRecord.add(br)
handler.obtainMessage(IBlockManager.STATE_COMPLETE)
handler.obtainMessage(ITaskManager.STATE_COMPLETE)
}
if (br.curProgress != blockF.length()) {
br.curProgress = blockF.length()
@ -142,7 +143,7 @@ internal class HttpDBlockInterceptor : ITaskInterceptor {
blockManager.putUnfinishedBlock(br)
}
// update task progress
handler.obtainMessage(IBlockManager.STATE_UPDATE_PROGRESS, br.curProgress)
handler.obtainMessage(ITaskManager.STATE_UPDATE_PROGRESS, br.curProgress)
}
}

@ -0,0 +1,62 @@
/*
* 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 com.arialyy.aria.core.DuaContext
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.TaskResp
import com.arialyy.aria.http.HttpTaskOption
import com.arialyy.aria.orm.entity.DEntity
import timber.log.Timber
/**
* @Author laoyuyu
* @Description
* @Date 8:31 PM 2023/3/6
**/
class HttpDCheckInterceptor : ITaskInterceptor {
/**
* find DEntity, if that not exist, create and save it
*/
private suspend fun findDEntityBySavePath(option: HttpTaskOption): DEntity? {
val savePath = option.savePathUri
val dao = DuaContext.getServiceManager().getDbService().getDuaDb().getDEntityDao()
val de = dao.getDEntityBySavePath(savePath.toString())
if (de != null) {
return null
}
val newDe = DEntity(
sourceUrl = option.sourUrl!!,
savePath = savePath!!,
)
dao.insert(newDe)
return newDe
}
override suspend fun interceptor(chain: TaskChain): TaskResp {
val option = chain.getTask().getTaskOption(HttpTaskOption::class.java)
val dEntity = findDEntityBySavePath(option)
if (dEntity == null) {
Timber.e("file already exists, ${option.savePathUri}")
return TaskResp(TaskResp.CODE_INTERRUPT)
}
TaskCachePool.putEntity(chain.getTask().taskId, dEntity)
return TaskResp(TaskResp.CODE_SUCCESS)
}
}

@ -1,88 +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.os.Looper;
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.group.AbsGroupLoader;
import com.arialyy.aria.core.group.AbsSubDLoadAdapter;
import com.arialyy.aria.core.listener.DownloadGroupListener;
import com.arialyy.aria.core.loader.IInfoTask;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.exception.AriaException;
import com.arialyy.aria.exception.AriaHTTPException;
/**
* http 组合任务加载器
*/
final class HttpDGLoader extends AbsGroupLoader {
HttpDGLoader(AbsTaskWrapper groupWrapper, DownloadGroupListener listener) {
super(groupWrapper, listener);
}
@Override protected void handlerTask(Looper looper) {
if (isBreak()) {
return;
}
mInfoTask.run();
}
@Override
protected AbsSubDLoadAdapter createSubLoader(DTaskWrapper wrapper, boolean needGetFileInfo) {
HttpSubDLoaderAdapter
subUtil = new HttpSubDLoaderAdapter(getScheduler(), needGetFileInfo, getKey());
subUtil.setParams(wrapper, null);
return subUtil;
}
private void startSub() {
if (isBreak()) {
return;
}
onPostStart();
for (DTaskWrapper wrapper : getWrapper().getSubTaskWrapper()) {
DownloadEntity dEntity = wrapper.getEntity();
startSubLoader(createSubLoader(wrapper, dEntity.getFileSize() < 0));
}
}
@Override public void addComponent(IInfoTask infoTask) {
mInfoTask = infoTask;
mInfoTask.setCallback(new HttpDGInfoTask.DGInfoCallback() {
@Override
public void onSubFail(DownloadEntity subEntity, AriaHTTPException e, boolean needRetry) {
getState().countFailNum(subEntity.getKey());
}
@Override public void onStop(long len) {
getListener().onStop(len);
}
@Override public void onSucceed(String key, CompleteInfo info) {
startSub();
}
@Override public void onFail(AbsEntity entity, AriaException e, boolean needRetry) {
fail(e, needRetry);
}
});
}
}

@ -53,6 +53,10 @@ internal class HttpDHeaderInterceptor : ITaskInterceptor {
)
}
private fun getOptionAdapter(): HttpDOptionAdapter {
return taskOption.getOptionAdapter(HttpDOptionAdapter::class.java)
}
override suspend fun interceptor(chain: TaskChain): TaskResp {
if (Looper.myLooper() == Looper.getMainLooper()) {
throw IllegalThreadStateException("io operations cannot be in the main thread")
@ -64,8 +68,8 @@ internal class HttpDHeaderInterceptor : ITaskInterceptor {
val fileSize = getFileSize()
if (fileSize >= 0) {
task.taskState.fileSize = fileSize
taskOption.isSupportResume = fileSize != 0L
taskOption.isSupportBlock = taskOption.isSupportResume && fileSize > BlockRecord.BLOCK_SIZE
getOptionAdapter().isSupportResume = fileSize != 0L
getOptionAdapter().isSupportBlock = getOptionAdapter().isSupportResume && fileSize > BlockRecord.BLOCK_SIZE
return chain.proceed(task)
}
} catch (e: IOException) {
@ -98,12 +102,9 @@ internal class HttpDHeaderInterceptor : ITaskInterceptor {
val code = conn.responseCode
when {
code == HttpURLConnection.HTTP_PARTIAL -> return getFileSizeFromHeader(
conn.headerFields,
taskOption
)
code == HttpURLConnection.HTTP_PARTIAL -> return getFileSizeFromHeader(conn.headerFields)
code == HttpURLConnection.HTTP_OK -> {
val len = getFileSizeFromHeader(conn.headerFields, taskOption)
val len = getFileSizeFromHeader(conn.headerFields)
if (len > 0) {
return len
}
@ -127,7 +128,7 @@ internal class HttpDHeaderInterceptor : ITaskInterceptor {
return -1
}
code == 416 -> {
return getFileSizeFromHeader(conn.headerFields, taskOption)
return getFileSizeFromHeader(conn.headerFields)
}
code in CODE_30X -> {
Timber.d("handle 30x turn, code: $code")
@ -152,7 +153,7 @@ internal class HttpDHeaderInterceptor : ITaskInterceptor {
if (chunkHead.isNullOrEmpty()) {
return -1
}
taskOption.isChunkTask = true
getOptionAdapter().isChunkTask = true
return 0
}
@ -191,10 +192,9 @@ internal class HttpDHeaderInterceptor : ITaskInterceptor {
* get file size from header, if user not set [IHttpFileLenAdapter], use [FileLenAdapter]
*/
private fun getFileSizeFromHeader(
header: Map<String, List<String>>,
taskOption: HttpTaskOption
header: Map<String, List<String>>
): Long {
var lenAdapter = taskOption.fileSizeAdapter
var lenAdapter = getOptionAdapter().fileSizeAdapter
if (lenAdapter == null) {
lenAdapter = FileLenAdapter()
}

@ -0,0 +1,42 @@
/*
* 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 com.arialyy.aria.core.processor.IHttpFileLenAdapter
import com.arialyy.aria.http.IHttpTaskOptionAdapter
/**
* @Author laoyuyu
* @Description
* @Date 2:03 PM 2023/3/6
**/
class HttpDOptionAdapter : IHttpTaskOptionAdapter {
var fileSizeAdapter: IHttpFileLenAdapter? = null
var isChunkTask = false
/**
* whether block is supported, true: supported
*/
var isSupportResume = true
/**
* whether resume task is supported
* 1. in download task, if file length not obtained, isSupportResume = false
* 2. in upload task, if service not supported resume, isSupportResume = false
*/
var isSupportBlock = true
}

@ -26,10 +26,7 @@ import com.arialyy.aria.core.task.ITaskInterceptor
import com.arialyy.aria.core.task.TaskCachePool
import com.arialyy.aria.http.HttpBaseStartController
import com.arialyy.aria.http.HttpOption
import com.arialyy.aria.http.HttpTaskOption
import com.arialyy.aria.http.HttpUtil
import com.arialyy.aria.orm.entity.DEntity
import kotlinx.coroutines.launch
import java.net.HttpURLConnection
/**
@ -39,9 +36,11 @@ import java.net.HttpURLConnection
**/
class HttpDStartController(target: Any, val url: String) : HttpBaseStartController(target),
IStartController {
private val taskOptionSupport = HttpDOptionAdapter()
init {
httpTaskOption.sourUrl = url
httpTaskOption.taskOptionAdapter = taskOptionSupport
}
override fun setTaskInterceptor(taskInterceptor: ITaskInterceptor): HttpDStartController {
@ -60,7 +59,7 @@ class HttpDStartController(target: Any, val url: String) : HttpBaseStartControll
* Maybe the server has special rules, you need set [IHttpFileLenAdapter] to get the file length from [HttpURLConnection.getHeaderFields]
*/
fun setHttpFileLenAdapter(adapter: IHttpFileLenAdapter): HttpDStartController {
httpTaskOption.fileSizeAdapter = adapter
taskOptionSupport.fileSizeAdapter = adapter
return this
}
@ -86,32 +85,10 @@ class HttpDStartController(target: Any, val url: String) : HttpBaseStartControll
}
val task = DownloadTask(httpTaskOption)
task.adapter = HttpDTaskAdapter()
DuaContext.duaScope.launch {
val dEntity = findDEntityBySavePath(httpTaskOption)
TaskCachePool.putEntity(task.taskId, dEntity)
}
TaskCachePool.putTask(task)
return task
}
/**
* find DEntity, if that not exist, create and save it
*/
private suspend fun findDEntityBySavePath(option: HttpTaskOption): DEntity {
val savePath = option.savePathUri
val dao = DuaContext.getServiceManager().getDbService().getDuaDb().getDEntityDao()
val de = dao.getDEntityBySavePath(savePath.toString())
if (de != null) {
return de
}
val newDe = DEntity(
sourceUrl = option.sourUrl!!,
savePath = savePath!!,
)
dao.insert(newDe)
return newDe
}
override fun add(): Int {
if (!HttpUtil.checkHttpDParams(httpTaskOption)) {
return -1

@ -17,7 +17,6 @@ package com.arialyy.aria.http.download
import android.os.Looper
import com.arialyy.aria.core.DuaContext
import com.arialyy.aria.core.inf.IBlockManager
import com.arialyy.aria.core.task.AbsTaskAdapter
import com.arialyy.aria.core.task.BlockManager
import com.arialyy.aria.core.task.DownloadTask
@ -42,7 +41,7 @@ internal class HttpDTaskAdapter : AbsTaskAdapter() {
HttpDEventListener(getTask() as DownloadTask)
}
override fun getBlockManager(): IBlockManager {
override fun getTaskManager(): BlockManager {
if (blockManager == null) {
blockManager = BlockManager(getTask())
}
@ -50,7 +49,7 @@ internal class HttpDTaskAdapter : AbsTaskAdapter() {
}
override fun isRunning(): Boolean {
return blockManager?.isRunning ?: false
return getTaskManager().isRunning()
}
override fun cancel() {
@ -74,6 +73,7 @@ internal class HttpDTaskAdapter : AbsTaskAdapter() {
DuaContext.duaScope.launch(Dispatchers.IO) {
Looper.prepare()
blockManager?.setLooper()
addCoreInterceptor(HttpDCheckInterceptor())
addCoreInterceptor(TimerInterceptor())
addCoreInterceptor(HttpDHeaderInterceptor())
addCoreInterceptor(HttpDBlockInterceptor())

@ -56,8 +56,8 @@ open class TimerInterceptor : ITaskInterceptor {
override fun run() {
// 线程池中是不抛异常的,没有日志,很难定位问题,需要手动try-catch
try {
if (blockManager.isCompleted
|| blockManager.hasFailedBlock()
if (blockManager.isCompleted()
|| blockManager.hasFailedTask()
|| !isRunning(chain.getTask())
) {
ThreadTaskManager2.stopThreadTask(chain.getTask().taskId)
@ -66,7 +66,7 @@ open class TimerInterceptor : ITaskInterceptor {
}
if (chain.getTask().taskState.curProgress >= 0) {
chain.getTask().getTaskOption(ITaskOption::class.java).eventListener.onProgress(
blockManager.currentProgress
blockManager.getCurrentProgress()
)
return
}

@ -17,7 +17,7 @@ package com.arialyy.aria.http.upload
import android.os.Looper
import com.arialyy.aria.core.DuaContext
import com.arialyy.aria.core.inf.IBlockManager
import com.arialyy.aria.core.inf.ITaskManager
import com.arialyy.aria.core.task.AbsTaskAdapter
import com.arialyy.aria.core.task.BlockManager
import com.arialyy.aria.core.task.TaskResp
@ -36,7 +36,7 @@ import kotlinx.coroutines.launch
class HttpUTaskAdapter : AbsTaskAdapter() {
private var blockManager: BlockManager? = null
override fun getBlockManager(): IBlockManager {
override fun getTaskManager(): ITaskManager {
if (blockManager == null) {
blockManager = BlockManager(getTask())
}

@ -0,0 +1,47 @@
/*
* 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.dua.group
import com.arialyy.aria.core.task.ITaskInterceptor
import com.arialyy.aria.core.task.TaskChain
import com.arialyy.aria.core.task.TaskResp
import com.arialyy.aria.util.CheckUtil
import timber.log.Timber
/**
* 1. Check if the save path is valid
* 2. Check all sub-task download addresses
* @Author laoyuyu
* @Description
* @Date 8:56 PM 2023/3/6
**/
internal class HttpDGCheckInterceptor : ITaskInterceptor {
override suspend fun interceptor(chain: TaskChain): TaskResp {
// if (optionAdapter.subUrl.isEmpty()){
// Timber.e("sub-task list is empty")
// return -1
// }
//
// optionAdapter.subUrl.forEach {
// if (!CheckUtil.checkUrl(it)){
// Timber.e("invalid url: $it")
// return -1
// }
// }
}
}

@ -0,0 +1,40 @@
/*
* 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.dua.group
import com.arialyy.annotations.TaskEnum
import com.arialyy.aria.core.DuaContext
import com.arialyy.aria.core.inf.IComponentLoader
import com.arialyy.aria.core.inf.IDownloader
/**
* @Author laoyuyu
* @Description
* @Date 7:51 AM 2023/3/6
**/
class HttpDGComponentLoader : IComponentLoader {
private val downloader by lazy {
HttpDGLoader(DuaContext.getLifeManager().getTargetByLoader(this)!!)
}
override fun <T : IDownloader> download(): T {
return downloader as T
}
override fun getTaskEnum(): TaskEnum {
return TaskEnum.DOWNLOAD_GROUP
}
}

@ -15,32 +15,20 @@
*/
package com.arialyy.dua.group
import com.arialyy.aria.core.inf.IBlockManager
import com.arialyy.aria.core.task.AbsTaskAdapter
import com.arialyy.aria.core.listener.AbsEventListener
import com.arialyy.aria.core.task.DownloadGroupTask
/**
* @Author laoyuyu
* @Description
* @Date 21:58 2023/2/20
* @Date 9:15 PM 2023/3/6
**/
internal class DGroupAdapter : AbsTaskAdapter() {
override fun getBlockManager(): IBlockManager {
internal class HttpDGEventListener(task: DownloadGroupTask) : AbsEventListener(task) {
override fun onComplete() {
TODO("Not yet implemented")
}
override fun isRunning(): Boolean {
TODO("Not yet implemented")
}
override fun cancel() {
TODO("Not yet implemented")
}
override fun stop() {
TODO("Not yet implemented")
}
override fun start() {
override fun handleCancel() {
TODO("Not yet implemented")
}
}

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.http.download;
package com.arialyy.dua.group;
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.common.CompleteInfo;

@ -13,23 +13,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.manager;
package com.arialyy.dua.group
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import android.net.Uri
import com.arialyy.annotations.TaskEnum
import com.arialyy.aria.core.inf.IDownloader
/**
* 任务组通过组创建任务
* Created by Aria.Lao on 2017/11/1.
*/
interface IGroupWrapperFactory<ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskWrapper<ENTITY>> {
* @Author laoyuyu
* @Description
* @Date 7:53 AM 2023/3/6
**/
class HttpDGLoader(val target: Any) : IDownloader {
override fun getTaskEnum(): TaskEnum {
return TaskEnum.DOWNLOAD_GROUP
}
/**
* 获取任务组的任务实体
* 1创建实体和任务实体之间的关联
* 2如果在数据库中查找不到对应的数据则新创建任务实体
*
* @param taskId 组合任务任务Id
* start, create a task
* @param savePath download url
*/
TASK_ENTITY getGroupWrapper(long taskId);
fun load(savePath: Uri): HttpDGStartController {
return HttpDGStartController(target, savePath)
}
}

@ -13,18 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.manager;
package com.arialyy.dua.group
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.http.IHttpTaskOptionAdapter
/**
* Created by Aria.Lao on 2017/11/1.
*/
interface INormalTEFactory<ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskWrapper<ENTITY>> {
/**
* 通过key创建任务只适应于单任务
*/
TASK_ENTITY create(long taskId);
* @Author laoyuyu
* @Description
* @Date 8:14 PM 2023/3/6
**/
internal class HttpDGOptionAdapter : IHttpTaskOptionAdapter {
val subUrl = mutableSetOf<String>()
}

@ -0,0 +1,83 @@
/*
* 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.dua.group
import android.net.Uri
import com.arialyy.aria.core.task.DownloadGroupTask
import com.arialyy.aria.core.task.ITaskInterceptor
import com.arialyy.aria.core.task.TaskCachePool
import com.arialyy.aria.http.HttpBaseStartController
import com.arialyy.aria.http.HttpOption
import com.arialyy.aria.http.HttpUtil
import com.arialyy.aria.util.FileUtils
import timber.log.Timber
/**
* @Author laoyuyu
* @Description
* @Date 7:47 PM 2023/3/6
**/
class HttpDGStartController(target: Any, val savePath: Uri) : HttpBaseStartController(target) {
private val optionAdapter = HttpDGOptionAdapter()
init {
httpTaskOption.taskOptionAdapter = optionAdapter
httpTaskOption.savePathUri = savePath
}
override fun setTaskInterceptor(taskInterceptor: ITaskInterceptor): HttpDGStartController {
return super.setTaskInterceptor(taskInterceptor) as HttpDGStartController
}
override fun setThreadNum(threadNum: Int): HttpDGStartController {
return super.setThreadNum(threadNum) as HttpDGStartController
}
override fun setHttpOption(httpOption: HttpOption): HttpDGStartController {
return super.setHttpOption(httpOption) as HttpDGStartController
}
/**
* add sub task download uri
*/
fun addSubUriResource(subUrlList: List<String>): HttpDGStartController {
optionAdapter.subUrl.addAll(subUrlList)
return this
}
private fun createTask(): DownloadGroupTask {
if (HttpUtil.checkHttpDParams(httpTaskOption)) {
throw IllegalArgumentException("invalid params")
}
val task = DownloadGroupTask(httpTaskOption)
task.adapter = HttpDGroupAdapter()
TaskCachePool.putTask(task)
return task
}
/**
* Start task
* @return taskId
*/
fun start(): Int {
if (!FileUtils.uriEffective(savePath)) {
Timber.e("invalid savePath: $savePath")
return -1
}
return createTask().taskId
}
}

@ -0,0 +1,84 @@
/*
* 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.dua.group
import android.os.Looper
import com.arialyy.aria.core.DuaContext
import com.arialyy.aria.core.inf.ITaskManager
import com.arialyy.aria.core.task.AbsTaskAdapter
import com.arialyy.aria.core.task.DownloadGroupTask
import com.arialyy.aria.core.task.TaskResp
import com.arialyy.aria.exception.AriaException
import com.arialyy.aria.http.HttpTaskOption
import com.arialyy.aria.http.download.HttpBlockThreadInterceptor
import com.arialyy.aria.http.download.HttpDCheckInterceptor
import com.arialyy.aria.http.download.TimerInterceptor
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
/**
* @Author laoyuyu
* @Description
* @Date 21:58 2023/2/20
**/
internal class HttpDGroupAdapter : AbsTaskAdapter() {
init {
getTask().getTaskOption(HttpTaskOption::class.java).eventListener =
HttpDGEventListener(getTask() as DownloadGroupTask)
}
override fun getTaskManager(): ITaskManager {
TODO("Not yet implemented")
}
override fun isRunning(): Boolean {
TODO("Not yet implemented")
}
override fun cancel() {
TODO("Not yet implemented")
}
override fun stop() {
TODO("Not yet implemented")
}
override fun start() {
getTask().getTaskOption(HttpTaskOption::class.java).taskInterceptor.let {
if (it.isNotEmpty()) {
addInterceptors(it)
}
}
DuaContext.duaScope.launch(Dispatchers.IO) {
Looper.prepare()
blockManager?.setLooper()
addCoreInterceptor(HttpDCheckInterceptor())
addCoreInterceptor(TimerInterceptor())
addCoreInterceptor(HttpBlockThreadInterceptor())
val resp = interceptor()
if (resp == null || resp.code != TaskResp.CODE_SUCCESS) {
getTask().getTaskOption(HttpTaskOption::class.java).eventListener.onFail(
false,
AriaException("start task fail, task interrupt, code: ${resp?.code ?: TaskResp.CODE_INTERRUPT}")
)
blockManager?.stop()
return@launch
}
Looper.loop()
}
}
}

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.http.download;
package com.arialyy.dua.group;
import android.os.Handler;
import com.arialyy.aria.core.download.DTaskWrapper;

@ -21,7 +21,7 @@ import com.arialyy.aria.core.config.Configuration;
import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.IBlockManager;
import com.arialyy.aria.core.inf.ITaskManager;
import com.arialyy.aria.core.listener.IDGroupListener;
import com.arialyy.aria.core.listener.IEventListener;
import com.arialyy.aria.core.loader.IInfoTask;
@ -360,7 +360,7 @@ public abstract class AbsGroupLoader implements ILoaderVisitor, ILoader {
* @deprecated 组合任务不需要实现这个其内部是一个子任务调度器并不是线程状态管理器
*/
@Deprecated
@Override public void addComponent(IBlockManager threadState) {
@Override public void addComponent(ITaskManager threadState) {
}

@ -23,7 +23,7 @@ import android.util.Log;
import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.config.Configuration;
import com.arialyy.aria.core.inf.IBlockManager;
import com.arialyy.aria.core.inf.ITaskManager;
import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.manager.ThreadTaskManager;
import com.arialyy.aria.exception.ExceptionFactory;
@ -58,37 +58,37 @@ final class SimpleSchedulers implements Handler.Callback {
ALog.w(TAG, "组合任务子任务调度数据为空");
return true;
}
String threadName = b.getString(IBlockManager.DATA_THREAD_NAME);
String threadName = b.getString(ITaskManager.DATA_THREAD_NAME);
AbsSubDLoadAdapter loaderUtil = mQueue.getLoaderUtil(threadName);
if (loaderUtil == null) {
ALog.e(TAG, String.format("子任务loader不存在,state:%s,key:%s", msg.what, threadName));
return true;
}
long curLocation = b.getLong(IBlockManager.DATA_THREAD_LOCATION,
long curLocation = b.getLong(ITaskManager.DATA_THREAD_LOCATION,
loaderUtil.getLoader().getWrapper().getEntity().getCurrentProgress());
// 处理状态
switch (msg.what) {
case IBlockManager.STATE_RUNNING:
case ITaskManager.STATE_RUNNING:
long range = (long) msg.obj;
mGState.listener.onSubRunning(loaderUtil.getEntity(), range);
break;
case IBlockManager.STATE_PRE:
case ITaskManager.STATE_PRE:
mGState.listener.onSubPre(loaderUtil.getEntity());
mGState.updateCount(loaderUtil.getKey());
break;
case IBlockManager.STATE_START:
case ITaskManager.STATE_START:
mGState.listener.onSubStart(loaderUtil.getEntity());
break;
case IBlockManager.STATE_STOP:
case ITaskManager.STATE_STOP:
handleStop(loaderUtil, curLocation);
ThreadTaskManager.getInstance().removeSingleTaskThread(mKey, threadName);
break;
case IBlockManager.STATE_COMPLETE:
case ITaskManager.STATE_COMPLETE:
handleComplete(loaderUtil);
ThreadTaskManager.getInstance().removeSingleTaskThread(mKey, threadName);
break;
case IBlockManager.STATE_FAIL:
boolean needRetry = b.getBoolean(IBlockManager.DATA_RETRY, false);
case ITaskManager.STATE_FAIL:
boolean needRetry = b.getBoolean(ITaskManager.DATA_RETRY, false);
handleFail(loaderUtil, needRetry);
ThreadTaskManager.getInstance().removeSingleTaskThread(mKey, threadName);
break;

@ -0,0 +1,78 @@
/*
* 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.inf
import android.os.Handler
/**
* @Author laoyuyu
* @Description
* @Date 9:36 PM 2023/3/6
**/
interface ITaskManager {
companion object {
const val STATE_STOP = 0x01
const val STATE_FAIL = 0x02
const val STATE_CANCEL = 0x03
const val STATE_COMPLETE = 0x04
const val STATE_RUNNING = 0x05
const val STATE_UPDATE_PROGRESS = 0x06
const val STATE_PRE = 0x07
const val STATE_START = 0x08
const val DATA_RETRY = "DATA_RETRY"
const val DATA_ERROR_INFO = "DATA_ERROR_INFO"
const val DATA_THREAD_NAME = "DATA_THREAD_NAME"
const val DATA_THREAD_LOCATION = "DATA_THREAD_LOCATION"
const val DATA_ADD_LEN = "DATA_ADD_LEN" // 增加的长度
}
fun setLooper()
fun stop()
/**
* 任务是否已经完成
*
* @return true 任务已完成
*/
fun isCompleted(): Boolean
/**
* 获取当前任务进度
*
* @return 任务当前进度
*/
fun getCurrentProgress(): Long
fun isStopped(): Boolean
fun isCanceled(): Boolean
fun isRunning(): Boolean
/**
* 创建handler 回调
*/
fun getHandler(): Handler
/**
* 是否有失败的快
*
* @return true 有失败的快
*/
fun hasFailedTask(): Boolean
}

@ -18,7 +18,7 @@ package com.arialyy.aria.core.loader;
import android.os.Looper;
import android.util.Log;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.inf.IBlockManager;
import com.arialyy.aria.core.inf.ITaskManager;
import com.arialyy.aria.core.listener.IEventListener;
import com.arialyy.aria.core.manager.ThreadTaskManager;
import com.arialyy.aria.core.task.IThreadTask;
@ -58,7 +58,7 @@ public abstract class AbsNormalLoader<T extends AbsTaskWrapper> implements ILoad
private boolean isRuning = false;
protected IRecordHandler mRecordHandler;
protected IBlockManager mStateManager;
protected ITaskManager mStateManager;
protected IInfoTask mInfoTask;
protected IThreadTaskBuilder mTTBuilder;
@ -81,7 +81,7 @@ public abstract class AbsNormalLoader<T extends AbsTaskWrapper> implements ILoad
return mListener;
}
protected IBlockManager getStateManager() {
protected ITaskManager getStateManager() {
return mStateManager;
}

@ -21,7 +21,7 @@ import android.os.Looper;
import android.os.Message;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.inf.IBlockManager;
import com.arialyy.aria.core.inf.ITaskManager;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.util.FileUtil;
@ -34,7 +34,7 @@ import java.util.concurrent.atomic.AtomicInteger;
/**
* 线程任务管理器用于处理多线程下载时任务的状态回调
*/
public class GroupSubThreadStateManager implements IBlockManager {
public class GroupSubThreadStateManager implements ITaskManager {
private final String TAG = CommonUtil.getClassName(this);
/**
@ -120,7 +120,7 @@ public class GroupSubThreadStateManager implements IBlockManager {
}*/
if (!mergeFile()) {
Bundle b=msg.getData();
b.putBoolean(IBlockManager.DATA_RETRY, false);
b.putBoolean(ITaskManager.DATA_RETRY, false);
msg.setData(b);
msg.what = STATE_FAIL;
sendMessageFromMsg(msg);
@ -139,7 +139,7 @@ public class GroupSubThreadStateManager implements IBlockManager {
case STATE_RUNNING:
Bundle b = msg.getData();
if (b != null) {
long len = b.getLong(IBlockManager.DATA_ADD_LEN, 0);
long len = b.getLong(ITaskManager.DATA_ADD_LEN, 0);
mProgress += len;
}
msg.obj=mProgress;
@ -162,7 +162,7 @@ public class GroupSubThreadStateManager implements IBlockManager {
public void sendMessageFromMsg(Message msg){
Message mMsg=mHandler.obtainMessage();
Bundle b=mMsg.getData();
b.putString(IBlockManager.DATA_THREAD_NAME,mKey);
b.putString(ITaskManager.DATA_THREAD_NAME,mKey);
msg.setData(b);
mMsg.copyFrom(msg);
mHandler.sendMessage(mMsg);

@ -15,7 +15,7 @@
*/
package com.arialyy.aria.core.loader;
import com.arialyy.aria.core.inf.IBlockManager;
import com.arialyy.aria.core.inf.ITaskManager;
/**
* 加载器访问者
@ -35,7 +35,7 @@ public interface ILoaderVisitor {
/**
* 线程状态
*/
void addComponent(IBlockManager threadState);
void addComponent(ITaskManager threadState);
/**
* 构造线程任务

@ -15,7 +15,7 @@
*/
package com.arialyy.aria.core.loader;
import com.arialyy.aria.core.inf.IBlockManager;
import com.arialyy.aria.core.inf.ITaskManager;
import java.util.ArrayList;
import java.util.List;
@ -33,7 +33,7 @@ public class LoaderStructure {
* 将组件加入到集合必须添加以下集合
* 1 {@link IRecordHandler}
* 2 {@link IInfoTask}
* 3 {@link IBlockManager}
* 3 {@link ITaskManager}
* 4 {@link IThreadTaskBuilder}
*
* @param component 待添加的组件

@ -21,7 +21,7 @@ import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.common.AbsNormalEntity;
import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.event.EventMsgUtil;
import com.arialyy.aria.core.inf.IBlockManager;
import com.arialyy.aria.core.inf.ITaskManager;
import com.arialyy.aria.core.listener.IDLoadListener;
import com.arialyy.aria.core.listener.IEventListener;
import com.arialyy.aria.core.manager.ThreadTaskManager;
@ -159,7 +159,7 @@ public class NormalLoader<T extends AbsTaskWrapper> extends AbsNormalLoader<T> {
});
}
@Override public void addComponent(IBlockManager threadState) {
@Override public void addComponent(ITaskManager threadState) {
mStateManager = threadState;
}

@ -8,7 +8,7 @@ import com.arialyy.aria.core.ThreadRecord;
import com.arialyy.aria.core.common.AbsNormalEntity;
import com.arialyy.aria.core.common.SubThreadConfig;
import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.aria.core.inf.IBlockManager;
import com.arialyy.aria.core.inf.ITaskManager;
import com.arialyy.aria.core.task.IThreadTask;
import com.arialyy.aria.core.task.ThreadTask;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
@ -106,12 +106,12 @@ public final class NormalTTBuilder implements IThreadTaskBuilder {
currentProgress += endL - startL;
ALog.d(TAG, String.format("任务【%s】线程__%s__已完成", mWrapper.getKey(), i));
Message msg = mStateHandler.obtainMessage();
msg.what = IBlockManager.STATE_COMPLETE;
msg.what = ITaskManager.STATE_COMPLETE;
Bundle b = msg.getData();
if (b == null) {
b = new Bundle();
}
b.putString(IBlockManager.DATA_THREAD_NAME,
b.putString(ITaskManager.DATA_THREAD_NAME,
CommonUtil.getThreadName(getEntity().getKey(), tr.threadId));
msg.setData(b);
msg.sendToTarget();

@ -23,7 +23,7 @@ import android.text.TextUtils;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.inf.IBlockManager;
import com.arialyy.aria.core.inf.ITaskManager;
import com.arialyy.aria.core.manager.ThreadTaskManager;
import com.arialyy.aria.core.task.IThreadTask;
import com.arialyy.aria.core.task.ThreadTask;
@ -51,7 +51,7 @@ public final class SubLoader implements ILoader, ILoaderVisitor {
private List<IThreadTask> mTask = new ArrayList<>();
private String parentKey;
private TaskRecord record;
protected IBlockManager mStateManager;
protected ITaskManager mStateManager;
public SubLoader(AbsTaskWrapper wrapper, Handler schedulers) {
this.wrapper = wrapper;
@ -65,7 +65,7 @@ public final class SubLoader implements ILoader, ILoaderVisitor {
/**
* 发送状态到调度器
*
* @param state {@link IBlockManager}
* @param state {@link ITaskManager}
*/
private void sendNormalState(int state) {
Message msg = schedulers.obtainMessage();
@ -73,7 +73,7 @@ public final class SubLoader implements ILoader, ILoaderVisitor {
if (b == null) {
b = new Bundle();
}
b.putString(IBlockManager.DATA_THREAD_NAME, getKey());
b.putString(ITaskManager.DATA_THREAD_NAME, getKey());
msg.what = state;
msg.setData(b);
msg.sendToTarget();
@ -88,9 +88,9 @@ public final class SubLoader implements ILoader, ILoaderVisitor {
if (b == null) {
b = new Bundle();
}
b.putString(IBlockManager.DATA_THREAD_NAME, getKey());
b.putBoolean(IBlockManager.DATA_RETRY, needRetry);
msg.what = IBlockManager.STATE_FAIL;
b.putString(ITaskManager.DATA_THREAD_NAME, getKey());
b.putBoolean(ITaskManager.DATA_RETRY, needRetry);
msg.what = ITaskManager.STATE_FAIL;
msg.setData(b);
msg.sendToTarget();
}
@ -117,7 +117,7 @@ public final class SubLoader implements ILoader, ILoaderVisitor {
&& !record.threadRecords.isEmpty()
&& record.threadRecords.get(0).isComplete) {
ALog.d(TAG, "子任务已完成,key:" + wrapper.getKey());
sendNormalState(IBlockManager.STATE_COMPLETE);
sendNormalState(ITaskManager.STATE_COMPLETE);
return;
}
List<IThreadTask> task =
@ -134,14 +134,14 @@ public final class SubLoader implements ILoader, ILoaderVisitor {
return;
}
sendNormalState(IBlockManager.STATE_PRE);
sendNormalState(ITaskManager.STATE_PRE);
mTask.addAll(task);
try {
for (IThreadTask iThreadTask : mTask) {
ThreadTaskManager.getInstance().startThread(parentKey, iThreadTask);
}
sendNormalState(IBlockManager.STATE_START);
sendNormalState(ITaskManager.STATE_START);
mStateManager.updateCurrentProgress(getWrapper().getEntity().getCurrentProgress());
} catch (Exception e) {
@ -254,7 +254,7 @@ public final class SubLoader implements ILoader, ILoaderVisitor {
});
}
@Override public void addComponent(IBlockManager threadState) {
@Override public void addComponent(ITaskManager threadState) {
mStateManager = threadState;
}

@ -19,7 +19,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import com.arialyy.aria.core.inf.IBlockManager;
import com.arialyy.aria.core.inf.ITaskManager;
import com.arialyy.aria.core.listener.IEventListener;
import com.arialyy.aria.exception.AriaException;
import com.arialyy.aria.util.ALog;
@ -33,7 +33,7 @@ import timber.log.Timber;
/**
* 线程任务管理器用于处理多线程下载时任务的状态回调
*/
public class TaskThreadStateManager implements IBlockManager {
public class TaskThreadStateManager implements ITaskManager {
/**
* 分块文件路径: 文件路径.blockId.part
*/
@ -113,7 +113,7 @@ public class TaskThreadStateManager implements IBlockManager {
case STATE_RUNNING:
Bundle b = msg.getData();
if (b != null) {
long len = b.getLong(IBlockManager.DATA_ADD_LEN, 0);
long len = b.getLong(ITaskManager.DATA_ADD_LEN, 0);
mProgress += len;
}

@ -15,7 +15,7 @@
*/
package com.arialyy.aria.core.task
import com.arialyy.aria.core.inf.IBlockManager
import com.arialyy.aria.core.inf.ITaskManager
import com.arialyy.aria.core.inf.ITaskAdapter
import com.arialyy.aria.core.listener.IEventListener
import com.arialyy.aria.core.task.ITaskInterceptor.IChain
@ -39,7 +39,7 @@ abstract class AbsTaskAdapter : ITaskAdapter {
protected fun getTask() = mTask
abstract fun getBlockManager(): IBlockManager
abstract fun getTaskManager(): ITaskManager
/**
* add user interceptor
@ -62,7 +62,7 @@ abstract class AbsTaskAdapter : ITaskAdapter {
val interceptors: MutableList<ITaskInterceptor> = ArrayList()
interceptors.addAll(mUserInterceptor)
interceptors.addAll(mCoreInterceptor)
val chain: IChain = TaskChain(interceptors, 0, mTask, getBlockManager())
val chain: IChain = TaskChain(interceptors, 0, mTask, getTaskManager())
return chain.proceed(mTask)
}
}

@ -19,6 +19,7 @@ import android.os.Handler
import android.os.Handler.Callback
import android.os.Looper
import com.arialyy.aria.core.inf.IBlockManager
import com.arialyy.aria.core.inf.ITaskManager
import com.arialyy.aria.core.inf.ITaskOption
import com.arialyy.aria.core.listener.IEventListener
import com.arialyy.aria.exception.AriaException
@ -58,47 +59,47 @@ class BlockManager(task: ITask) : IBlockManager {
private val callback = Callback { msg ->
when (msg.what) {
IBlockManager.STATE_STOP -> {
ITaskManager.STATE_STOP -> {
stoppedNum.getAndIncrement()
if (isStopped) {
eventListener.onStop(currentProgress)
if (isStopped()) {
eventListener.onStop(getCurrentProgress())
quitLooper()
}
}
IBlockManager.STATE_CANCEL -> {
ITaskManager.STATE_CANCEL -> {
canceledNum.getAndIncrement()
if (isCanceled) {
if (isCanceled()) {
eventListener.onCancel()
quitLooper()
}
}
IBlockManager.STATE_FAIL -> {
ITaskManager.STATE_FAIL -> {
failedNum.getAndIncrement()
if (hasFailedBlock()) {
if (hasFailedTask()) {
val b = msg.data
eventListener.onFail(
b.getBoolean(IBlockManager.DATA_RETRY, false),
b.getSerializable(IBlockManager.DATA_ERROR_INFO) as AriaException?
b.getBoolean(ITaskManager.DATA_RETRY, false),
b.getSerializable(ITaskManager.DATA_ERROR_INFO) as AriaException?
)
quitLooper()
}
}
IBlockManager.STATE_COMPLETE -> {
ITaskManager.STATE_COMPLETE -> {
completedNum.getAndIncrement()
if (isCompleted) {
if (isCompleted()) {
Timber.d("isComplete, completeNum = %s", completedNum)
eventListener.onComplete()
quitLooper()
}
}
IBlockManager.STATE_RUNNING -> {
ITaskManager.STATE_RUNNING -> {
val b = msg.data
if (b != null) {
val len = b.getLong(IBlockManager.DATA_ADD_LEN, 0)
val len = b.getLong(ITaskManager.DATA_ADD_LEN, 0)
progress += len
}
}
IBlockManager.STATE_UPDATE_PROGRESS -> {
ITaskManager.STATE_UPDATE_PROGRESS -> {
progress += msg.obj as Long
}
}
@ -146,7 +147,7 @@ class BlockManager(task: ITask) : IBlockManager {
this.blockNum = blockNum
}
override fun hasFailedBlock(): Boolean {
override fun hasFailedTask(): Boolean {
Timber.d("isFailed, blockBum = ${blockNum}, completedNum = ${completedNum.get()}, ")
return failedNum.get() != 0
}

@ -15,9 +15,8 @@
*/
package com.arialyy.aria.core.task;
import com.arialyy.aria.core.download.DTaskOption;
import com.arialyy.aria.core.common.TaskOption;
import com.arialyy.aria.core.inf.ITaskOption;
import com.arialyy.aria.core.inf.ITaskAdapter;
import java.util.Objects;
/**
@ -26,8 +25,8 @@ import java.util.Objects;
*/
public class DownloadGroupTask extends AbsTask {
protected DownloadGroupTask(ITaskOption taskOption, ITaskAdapter util) {
super(taskOption, util);
public DownloadGroupTask(ITaskOption taskOption) {
super(taskOption);
}
@Override public int getTaskType() {
@ -35,6 +34,6 @@ public class DownloadGroupTask extends AbsTask {
}
@Override public String getFilePath() {
return Objects.requireNonNull(getTaskOption(DTaskOption.class).getSavePathUri()).toString();
return Objects.requireNonNull(getTaskOption(TaskOption.class).getSavePathUri()).toString();
}
}

@ -15,7 +15,7 @@
*/
package com.arialyy.aria.core.task
import com.arialyy.aria.core.inf.IBlockManager
import com.arialyy.aria.core.inf.ITaskManager
/**
* @Author laoyuyu
@ -26,7 +26,7 @@ class TaskChain(
private val interceptors: List<ITaskInterceptor>,
private val index: Int = 0,
private val task: ITask,
val blockManager: IBlockManager
val blockManager: ITaskManager
) : ITaskInterceptor.IChain {
override fun getTask(): ITask {

@ -24,7 +24,7 @@ import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.ThreadRecord;
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.common.SubThreadConfig;
import com.arialyy.aria.core.inf.IBlockManager;
import com.arialyy.aria.core.inf.ITaskManager;
import com.arialyy.aria.core.listener.ISchedulers;
import com.arialyy.aria.core.manager.ThreadTaskManager;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
@ -178,7 +178,7 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
taskBreak = true;
if (mTaskWrapper.isSupportBP()) {
final long currentTemp = mRangeProgress;
updateState(IBlockManager.STATE_STOP, null);
updateState(ITaskManager.STATE_STOP, null);
ALog.d(TAG, String.format("任务【%s】thread__%s__中断【停止位置:%s】", getFileName(),
mRecord.threadId, currentTemp));
writeConfig(false, currentTemp);
@ -254,7 +254,7 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
public void stop() {
isStop = true;
final long stopLocation = mRangeProgress;
updateState(IBlockManager.STATE_STOP, null);
updateState(ITaskManager.STATE_STOP, null);
if (mTaskWrapper.getRequestType() == ITaskWrapper.M3U8_VOD) {
writeConfig(false, getConfig().tempFile.length());
ALog.i(TAG, String.format("任务【%s】已停止", getFileName()));
@ -272,7 +272,7 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
/**
* 发送状态给状态处理器
*
* @param state {@link IBlockManager#STATE_STOP}..
* @param state {@link ITaskManager#STATE_STOP}..
* @param bundle 而外数据
*/
@Override
@ -282,8 +282,8 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
bundle = new Bundle();
}
msg.setData(bundle);
bundle.putString(IBlockManager.DATA_THREAD_NAME, getThreadName());
bundle.putLong(IBlockManager.DATA_THREAD_LOCATION, mRangeProgress);
bundle.putString(ITaskManager.DATA_THREAD_NAME, getThreadName());
bundle.putLong(ITaskManager.DATA_THREAD_LOCATION, mRangeProgress);
msg.what = state;
int reqType = getConfig().threadType;
if (reqType == SubThreadConfig.TYPE_M3U8_PEER) {
@ -299,10 +299,10 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
private void sendM3U8Info(int state, Message msg) {
Bundle bundle = msg.getData();
if (state != IBlockManager.STATE_UPDATE_PROGRESS) {
if (state != ITaskManager.STATE_UPDATE_PROGRESS) {
msg.obj = this;
}
if ((state == IBlockManager.STATE_COMPLETE || state == IBlockManager.STATE_FAIL)) {
if ((state == ITaskManager.STATE_COMPLETE || state == ITaskManager.STATE_FAIL)) {
bundle.putString(ISchedulers.DATA_M3U8_URL, getConfig().url);
bundle.putString(ISchedulers.DATA_M3U8_PEER_PATH, getConfig().tempFile.getPath());
bundle.putInt(ISchedulers.DATA_M3U8_PEER_INDEX, getConfig().peerIndex);
@ -315,7 +315,7 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
writeConfig(true, mRecord.endLocation);
// 进度发送不是实时的,发送完成任务前,需要更新一次进度
sendRunningState();
updateState(IBlockManager.STATE_COMPLETE, null);
updateState(ITaskManager.STATE_COMPLETE, null);
}
/**
@ -363,9 +363,9 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
b = new Bundle();
msg.setData(b);
}
b.putString(IBlockManager.DATA_THREAD_NAME, getThreadName());
b.putLong(IBlockManager.DATA_ADD_LEN, mRangeProgress - mLastRangeProgress);
msg.what = IBlockManager.STATE_RUNNING;
b.putString(ITaskManager.DATA_THREAD_NAME, getThreadName());
b.putLong(ITaskManager.DATA_ADD_LEN, mRangeProgress - mLastRangeProgress);
msg.what = ITaskManager.STATE_RUNNING;
msg.obj = mRangeProgress;
Thread loopThread = mStateHandler.getLooper().getThread();
@ -386,7 +386,7 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
@Override
public void cancel() {
isCancel = true;
updateState(IBlockManager.STATE_CANCEL, null);
updateState(ITaskManager.STATE_CANCEL, null);
ALog.d(TAG,
String.format("任务【%s】thread__%s__取消", getFileName(), mRecord.threadId));
}
@ -501,7 +501,7 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
} else if (blockFileLen < mRecord.blockLen) {
mRecord.startLocation = mRecord.endLocation - mRecord.blockLen + blockFileLen;
mRecord.isComplete = false;
updateState(IBlockManager.STATE_UPDATE_PROGRESS, null);
updateState(ITaskManager.STATE_UPDATE_PROGRESS, null);
ALog.i(TAG,
String.format("修正分块【%s】记录,开始位置:%s,结束位置:%s", temp.getName(), mRecord.startLocation,
mRecord.endLocation));
@ -519,11 +519,11 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
*/
private void sendFailMsg(AriaException e, boolean needRetry) {
Bundle b = new Bundle();
b.putBoolean(IBlockManager.DATA_RETRY, needRetry);
b.putBoolean(ITaskManager.DATA_RETRY, needRetry);
if (e != null) {
b.putSerializable(IBlockManager.DATA_ERROR_INFO, e);
b.putSerializable(ITaskManager.DATA_ERROR_INFO, e);
}
updateState(IBlockManager.STATE_FAIL, b);
updateState(ITaskManager.STATE_FAIL, b);
}
/**

@ -18,7 +18,7 @@ package com.arialyy.aria.core.task
import android.os.Bundle
import android.os.Handler
import com.arialyy.aria.core.DuaContext
import com.arialyy.aria.core.inf.IBlockManager
import com.arialyy.aria.core.inf.ITaskManager
import com.arialyy.aria.orm.entity.BlockRecord
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
@ -53,13 +53,13 @@ class ThreadTask2(
override fun cancel() {
adapter.breakTask()
isCanceled = true
handler.obtainMessage(IBlockManager.STATE_CANCEL)
handler.obtainMessage(ITaskManager.STATE_CANCEL)
}
override fun stop() {
adapter.breakTask()
isStopped = true
handler.obtainMessage(IBlockManager.STATE_STOP)
handler.obtainMessage(ITaskManager.STATE_STOP)
}
override fun setMaxSpeed(speed: Int) {
@ -85,9 +85,9 @@ class ThreadTask2(
return
}
val b = Bundle()
b.putBoolean(IBlockManager.DATA_RETRY, false)
b.putSerializable(IBlockManager.DATA_ERROR_INFO, e)
handler.obtainMessage(IBlockManager.STATE_FAIL, b)
b.putBoolean(ITaskManager.DATA_RETRY, false)
b.putSerializable(ITaskManager.DATA_ERROR_INFO, e)
handler.obtainMessage(ITaskManager.STATE_FAIL, b)
}
override fun onComplete() {
@ -101,10 +101,10 @@ class ThreadTask2(
// update progress once a second, we need to check the progress difference.
val diff = kotlin.math.abs(record.curProgress - blockF.length())
if (diff != 0L) {
handler.obtainMessage(IBlockManager.STATE_RUNNING, diff)
handler.obtainMessage(ITaskManager.STATE_RUNNING, diff)
}
updateRecord()
handler.obtainMessage(IBlockManager.STATE_COMPLETE)
handler.obtainMessage(ITaskManager.STATE_COMPLETE)
}
private fun updateRecord() {
@ -121,7 +121,7 @@ class ThreadTask2(
record.curProgress += len
if (System.currentTimeMillis() - lastUpdateTime > 1000) {
lastUpdateTime = System.currentTimeMillis()
handler.obtainMessage(IBlockManager.STATE_RUNNING, len)
handler.obtainMessage(ITaskManager.STATE_RUNNING, len)
}
}

@ -41,10 +41,12 @@ data class DEntity(
* file source url
*/
val sourceUrl: String,
/**
* file save path, it's uri
*/
val savePath: Uri,
/**
* extended Information
*/

@ -1,155 +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.util;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.ThreadRecord;
import com.arialyy.aria.core.download.DGEntityWrapper;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.orm.DbEntity;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* 数据库帮助类
*/
public class DbDataHelper {
/**
* 获取任务记录
*
* @param filePath 文件地址
* @param taskType 任务类型{@link ITaskWrapper}
* @return 没有记录返回null有记录则返回任务记录
*/
public static TaskRecord getTaskRecord(String filePath, int taskType) {
TaskRecord taskRecord =
DbEntity.findFirst(TaskRecord.class, "filePath=? AND taskType=?", filePath,
String.valueOf(taskType));
if (taskRecord != null) {
taskRecord.threadRecords =
DbEntity.findDatas(ThreadRecord.class, "taskKey=? AND threadType=?", filePath,
String.valueOf(taskType));
}
return taskRecord;
}
/**
* 获取组合任务实体ftpDir任务实体
*
* @param groupHash 组合任务Hash
* @return 实体不存在返回null
*/
public static DownloadGroupEntity getDGEntityByHash(String groupHash) {
List<DGEntityWrapper> wrapper =
DbEntity.findRelationData(DGEntityWrapper.class, "DownloadGroupEntity.groupHash=?",
groupHash);
return wrapper == null || wrapper.size() == 0 ? null : wrapper.get(0).groupEntity;
}
/**
* 获取组合任务实体ftpDir任务实体
*
* @param dirPath 组合任务Hash
* @return 实体不存在返回null
*/
public static DownloadGroupEntity getDGEntityByPath(String dirPath) {
List<DGEntityWrapper> wrapper =
DbEntity.findRelationData(DGEntityWrapper.class, "DownloadGroupEntity.dirPath=?",
dirPath);
return wrapper == null || wrapper.size() == 0 ? null : wrapper.get(0).groupEntity;
}
/**
* 获取组合任务实体ftpDir任务实体
*
* @param taskId 组合任务id
* @return 实体不存在返回null
*/
public static DownloadGroupEntity getDGEntity(long taskId) {
List<DGEntityWrapper> wrapper =
DbEntity.findRelationData(DGEntityWrapper.class, "DownloadGroupEntity.rowid=?",
String.valueOf(taskId));
return wrapper == null || wrapper.size() == 0 ? null : wrapper.get(0).groupEntity;
}
/**
* 创建HTTP子任务实体
*/
public static List<DownloadEntity> createHttpSubTask(String groupHash, List<String> urls) {
List<DownloadEntity> list = new ArrayList<>();
for (int i = 0, len = urls.size(); i < len; i++) {
String url = urls.get(i);
DownloadEntity entity = new DownloadEntity();
entity.setUrl(url);
entity.setFilePath(groupHash + "_" + i);
int lastIndex = url.lastIndexOf(File.separator);
//去除url末尾携带的的参数
int endIndex = url.lastIndexOf("?");
if(endIndex<0||endIndex<lastIndex)endIndex=url.length();
entity.setFileName(url.substring(lastIndex + 1,endIndex));
entity.setGroupHash(groupHash);
entity.setGroupChild(true);
list.add(entity);
}
return list;
}
/**
* 通过Ftp下载地址获取组合任务实体
*
* @param ftpUrl ftp下载地址
*/
public static DownloadGroupEntity getOrCreateFtpDGEntity(String ftpUrl) {
List<DGEntityWrapper> wrapper =
DbEntity.findRelationData(DGEntityWrapper.class, "DownloadGroupEntity.groupHash=?",
ftpUrl);
DownloadGroupEntity groupEntity;
if (wrapper != null && !wrapper.isEmpty()) {
groupEntity = wrapper.get(0).groupEntity;
if (groupEntity == null) {
groupEntity = new DownloadGroupEntity();
}
} else {
groupEntity = new DownloadGroupEntity();
}
groupEntity.setGroupHash(ftpUrl);
return groupEntity;
}
/**
* 创建任务组子任务的任务实体
*/
public static List<DTaskWrapper> createDGSubTaskWrapper(DownloadGroupEntity dge) {
List<DTaskWrapper> list = new ArrayList<>();
for (DownloadEntity entity : dge.getSubEntities()) {
DTaskWrapper taskEntity = new DTaskWrapper(entity);
taskEntity.setGroupHash(dge.getKey());
taskEntity.setGroupTask(true);
list.add(taskEntity);
}
return list;
}
}

@ -1,129 +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.util;
import android.text.TextUtils;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.ThreadRecord;
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.wrapper.RecordWrapper;
import com.arialyy.aria.orm.DbEntity;
import java.util.List;
/**
* 删除组合任务记录
*/
public class DeleteDGRecord implements IDeleteRecord {
private String TAG = CommonUtil.getClassName(this);
private static volatile DeleteDGRecord INSTANCE = null;
private DeleteDGRecord() {
}
public static DeleteDGRecord getInstance() {
if (INSTANCE == null) {
synchronized (DeleteDGRecord.class) {
if (INSTANCE == null) {
INSTANCE = new DeleteDGRecord();
}
}
}
return INSTANCE;
}
/**
* @param dirPath 组合任务保存路径
* @param needRemoveFile true无论下载成功以否都将删除下载下来的文件false只会删除下载任务没有完成的文件
* @param needRemoveEntity 是否需要删除实体true 删除实体
*/
@Override
public void deleteRecord(String dirPath, boolean needRemoveFile, boolean needRemoveEntity) {
if (TextUtils.isEmpty(dirPath)) {
ALog.e(TAG, "删除下载任务组记录失败,组合任务路径为空");
return;
}
deleteRecord(DbDataHelper.getDGEntityByPath(dirPath), needRemoveFile, needRemoveEntity);
}
@Override
public void deleteRecord(AbsEntity absEntity, boolean needRemoveFile, boolean needRemoveEntity) {
if (absEntity == null) {
ALog.e(TAG, "删除组合任务记录失败,组合任务实体为空");
return;
}
DownloadGroupEntity groupEntity = (DownloadGroupEntity) absEntity;
List<RecordWrapper> records =
DbEntity.findRelationData(RecordWrapper.class, "dGroupHash=?", groupEntity.getGroupHash());
// 删除子任务记录
if (records == null || records.isEmpty()) {
ALog.w(TAG, "组任务记录已删除");
} else {
for (RecordWrapper record : records) {
if (record == null || record.taskRecord == null) {
continue;
}
// 删除分块文件
if (record.taskRecord.isBlock) {
removeBlockFile(record.taskRecord);
}
DbEntity.deleteData(ThreadRecord.class, "taskKey=?", record.taskRecord.filePath);
record.taskRecord.deleteData();
}
}
// 删除组合任务子任务的文件
List<DownloadEntity> subs = groupEntity.getSubEntities();
if (subs != null) {
for (DownloadEntity sub : subs) {
if (needRemoveFile || !groupEntity.isComplete()) {
FileUtil.deleteFile(sub.getFilePath());
}
}
}
// 删除文件夹
if (!TextUtils.isEmpty(groupEntity.getDirPath())) {
if (needRemoveFile || !groupEntity.isComplete()) {
FileUtil.deleteFile(groupEntity.getDirPath());
}
}
deleteEntity(needRemoveEntity, groupEntity.getGroupHash());
}
private void deleteEntity(boolean needRemoveEntity, String groupHash) {
if (needRemoveEntity) {
DbEntity.deleteData(DownloadEntity.class, "groupHash=?", groupHash);
DbEntity.deleteData(DownloadGroupEntity.class, "groupHash=?", groupHash);
}
}
/**
* 删除多线程分块下载的分块文件
*/
private void removeBlockFile(TaskRecord record) {
for (int i = 0, len = record.threadNum; i < len; i++) {
FileUtil.deleteFile(String.format(IRecordHandler.SUB_PATH, record.filePath, i));
}
}
}

@ -1,131 +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.util;
import android.text.TextUtils;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.ThreadRecord;
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.orm.DbEntity;
import java.io.File;
/**
* 删除下载记录
*/
public class DeleteDRecord implements IDeleteRecord {
private String TAG = CommonUtil.getClassName(this);
private static volatile DeleteDRecord INSTANCE = null;
private DeleteDRecord() {
}
public static DeleteDRecord getInstance() {
if (INSTANCE == null) {
synchronized (DeleteDRecord.class) {
if (INSTANCE == null) {
INSTANCE = new DeleteDRecord();
}
}
}
return INSTANCE;
}
/**
* @param filePath 文件保存路径
* @param removeTarget true无论下载成功以否都将删除下载下来的文件false只会删除下载任务没有完成的文件
* @param needRemoveEntity 是否需要删除实体
*/
@Override public void deleteRecord(String filePath, boolean removeTarget,
boolean needRemoveEntity) {
if (TextUtils.isEmpty(filePath)) {
throw new NullPointerException("删除记录失败,文件路径为空");
}
if (!filePath.startsWith("/")) {
throw new IllegalArgumentException(String.format("文件路径错误,filePath:%s", filePath));
}
DownloadEntity entity = DbEntity.findFirst(DownloadEntity.class, "downloadPath=?", filePath);
if (entity == null) {
ALog.e(TAG, "删除下载记录失败,没有在数据库中找到对应的实体文件,filePath:" + filePath);
return;
}
deleteRecord(entity, removeTarget, needRemoveEntity);
}
/**
* @param absEntity 记录关联的实体
* @param needRemoveFile true无论下载成功以否都将删除下载下来的文件false只会删除下载任务没有完成的文件
* @param needRemoveEntity 是否需要删除实体
*/
@Override
public void deleteRecord(AbsEntity absEntity, boolean needRemoveFile, boolean needRemoveEntity) {
if (absEntity == null) {
ALog.e(TAG, "删除下载记录失败,实体为空");
return;
}
DownloadEntity entity = (DownloadEntity) absEntity;
final String filePath = entity.getFilePath();
File targetFile = new File(filePath);
// 兼容以前版本
if (entity.getTaskType() == ITaskWrapper.M3U8_VOD
|| entity.getTaskType() == ITaskWrapper.M3U8_LIVE) {
DeleteM3u8Record.getInstance().deleteRecord(entity, needRemoveFile, needRemoveEntity);
return;
}
TaskRecord record = DbDataHelper.getTaskRecord(entity.getFilePath(), entity.getTaskType());
if (record == null) {
ALog.e(TAG, "删除下载记录失败,记录为空,将删除实体记录,filePath:" + entity.getFilePath());
FileUtil.deleteFile(targetFile);
deleteEntity(needRemoveEntity, filePath);
return;
}
// 删除下载的线程记录和任务记录
DbEntity.deleteData(ThreadRecord.class, "taskKey=? AND threadType=?", filePath,
String.valueOf(entity.getTaskType()));
DbEntity.deleteData(TaskRecord.class, "filePath=? AND taskType=?", filePath,
String.valueOf(entity.getTaskType()));
if (needRemoveFile || !entity.isComplete()) {
FileUtil.deleteFile(targetFile);
if (record.isBlock) {
removeBlockFile(record);
}
}
deleteEntity(needRemoveEntity, filePath);
}
private void deleteEntity(boolean needRemoveEntity, String filePath){
if (needRemoveEntity) {
DbEntity.deleteData(DownloadEntity.class, "downloadPath=?", filePath);
}
}
/**
* 删除多线程分块下载的分块文件
*/
private void removeBlockFile(TaskRecord record) {
for (int i = 0, len = record.threadNum; i < len; i++) {
FileUtil.deleteFile(String.format(IRecordHandler.SUB_PATH, record.filePath, i));
}
}
}

@ -1,151 +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.util;
import android.text.TextUtils;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.ThreadRecord;
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.common.M3U8Entity;
import com.arialyy.aria.orm.DbEntity;
import java.io.File;
/**
* 删除m3u8记录
*/
public class DeleteM3u8Record implements IDeleteRecord {
private String TAG = CommonUtil.getClassName(this);
private static volatile DeleteM3u8Record INSTANCE = null;
private DeleteM3u8Record() {
}
public static DeleteM3u8Record getInstance() {
if (INSTANCE == null) {
synchronized (DeleteM3u8Record.class) {
if (INSTANCE == null) {
INSTANCE = new DeleteM3u8Record();
}
}
}
return INSTANCE;
}
/**
* @param filePath 文件保存路径
* @param removeTarget true无论下载成功以否都将删除下载下来的文件false只会删除下载任务没有完成的文件
* @param needRemoveEntity 是否需要删除实体
*/
@Override public void deleteRecord(String filePath, boolean removeTarget,
boolean needRemoveEntity) {
if (TextUtils.isEmpty(filePath)) {
throw new NullPointerException("删除记录失败,文件路径为空");
}
if (!filePath.startsWith("/")) {
throw new IllegalArgumentException(String.format("文件路径错误,filePath:%s", filePath));
}
DownloadEntity entity = DbEntity.findFirst(DownloadEntity.class, "downloadPath=?", filePath);
if (entity == null) {
ALog.e(TAG, "删除下载记录失败,没有在数据库中找到对应的实体文件,filePath:" + filePath);
return;
}
deleteRecord(entity, removeTarget, needRemoveEntity);
}
@Override
public void deleteRecord(AbsEntity absEntity, boolean needRemoveFile, boolean needRemoveEntity) {
if (absEntity == null) {
ALog.e(TAG, "删除下载记录失败,实体为空");
return;
}
DownloadEntity entity = (DownloadEntity) absEntity;
final String filePath = entity.getFilePath();
TaskRecord record = DbDataHelper.getTaskRecord(filePath, entity.getTaskType());
if (record == null) {
ALog.e(TAG, "删除下载记录失败,记录为空,将删除实体记录,filePath:" + entity.getFilePath());
deleteEntity(entity.getTaskType(), needRemoveEntity, filePath);
return;
}
if (needRemoveFile || !entity.isComplete()) {
removeTsCache(new File(filePath), record.bandWidth);
FileUtil.deleteFile(filePath);
}
deleteEntity(entity.getTaskType(), needRemoveEntity, filePath);
}
private void deleteEntity(int taskType, boolean needRemoveEntity, String filePath){
// 删除下载的线程记录和任务记录
DbEntity.deleteData(ThreadRecord.class, "taskKey=? AND threadType=?", filePath,
String.valueOf(taskType));
DbEntity.deleteData(TaskRecord.class, "filePath=? AND taskType=?", filePath,
String.valueOf(taskType));
DbEntity.deleteData(M3U8Entity.class, "filePath=?", filePath);
if (needRemoveEntity) {
DbEntity.deleteData(DownloadEntity.class, "downloadPath=?", filePath);
}
}
/**
* 删除ts文件和索引文件如果有的话
*/
private static void removeTsCache(File targetFile, long bandWidth) {
// 删除key
M3U8Entity entity = DbEntity.findFirst(M3U8Entity.class, "filePath=?", targetFile.getPath());
if (entity != null && !TextUtils.isEmpty(entity.keyPath)){
File keyFile = new File(entity.keyPath);
FileUtil.deleteFile(keyFile);
}
// 删除ts
String cacheDir = null;
if (!targetFile.isDirectory()) {
cacheDir =
String.format("%s/.%s_%s", targetFile.getParent(), targetFile.getName(), bandWidth);
}
if (!TextUtils.isEmpty(cacheDir)) {
File cacheDirF = new File(cacheDir);
if (!cacheDirF.exists()) {
return;
}
File[] files = cacheDirF.listFiles();
for (File f : files) {
if (f.exists()) {
f.delete();
}
}
File cDir = new File(cacheDir);
if (cDir.exists()) {
cDir.delete();
}
}
File indexFile = new File(String.format("%s.index", targetFile.getPath()));
if (indexFile.exists()) {
indexFile.delete();
}
}
}

@ -1,99 +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.util;
import android.text.TextUtils;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.ThreadRecord;
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.orm.DbEntity;
/**
* 删除上传记录
*/
public class DeleteURecord implements IDeleteRecord {
private String TAG = CommonUtil.getClassName(this);
private static volatile DeleteURecord INSTANCE = null;
private DeleteURecord() {
}
public static DeleteURecord getInstance() {
if (INSTANCE == null) {
synchronized (DeleteURecord.class) {
if (INSTANCE == null) {
INSTANCE = new DeleteURecord();
}
}
}
return INSTANCE;
}
/**
* 删除上传记录
*
* @param filePath 上传文件的地址
* @param needRemoveFile 上传完成后是否需要删除本地文件true上传完成后删除本地文件
* @param needRemoveEntity 是否需要删除实体true 删除实体
*/
@Override public void deleteRecord(String filePath, boolean needRemoveFile,
boolean needRemoveEntity) {
if (TextUtils.isEmpty(filePath)) {
throw new NullPointerException("删除记录失败,文件路径为空");
}
if (!filePath.startsWith("/")) {
throw new IllegalArgumentException(String.format("文件路径错误,filePath:%s", filePath));
}
UploadEntity entity = DbEntity.findFirst(UploadEntity.class, "filePath=?", filePath);
if (entity == null) {
ALog.e(TAG, "删除上传记录失败,没有在数据库中找到对应的实体文件,filePath:" + filePath);
return;
}
deleteRecord(entity, needRemoveFile, needRemoveEntity);
}
@Override
public void deleteRecord(AbsEntity absEntity, boolean needRemoveFile, boolean needRemoveEntity) {
if (absEntity == null) {
ALog.e(TAG, "删除上传记录失败,实体为空");
return;
}
UploadEntity entity = (UploadEntity) absEntity;
// 删除下载的线程记录和任务记录
DbEntity.deleteData(ThreadRecord.class, "taskKey=? AND threadType=?", entity.getFilePath(),
String.valueOf(entity.getTaskType()));
DbEntity.deleteData(TaskRecord.class, "filePath=? AND taskType=?", entity.getFilePath(),
String.valueOf(entity.getTaskType()));
if (needRemoveFile) {
FileUtil.deleteFile(entity.getFilePath());
}
deleteEntity(needRemoveEntity, entity.getFilePath());
}
private void deleteEntity(boolean needRemoveEntity, String filePath) {
if (needRemoveEntity) {
DbEntity.deleteData(UploadEntity.class, "filePath=?", filePath);
}
}
}
Loading…
Cancel
Save