From 1e237d795d3a2563fdcf5956b652327c443a49fc Mon Sep 17 00:00:00 2001
From: laoyuyu <511455842@qq.com>
Date: Sat, 28 Dec 2019 13:18:20 +0800
Subject: [PATCH] =?UTF-8?q?loader=20=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../com/arialyy/aria/core/AriaManager.java | 2 +-
.../core/manager/DTaskWrapperFactory.java | 2 +-
.../aria/apache/commons/net/ftp/FTPFile.java | 2 +-
.../net/ftp/parser/NetwareFTPEntryParser.java | 2 +-
.../net/ftp/parser/VMSFTPEntryParser.java | 2 +-
...cordAdapter.java => FtpRecordHandler.java} | 8 +-
.../aria/ftp/download/FtpDLoaderAdapter.java | 6 +-
.../aria/ftp/download/FtpDirDLoaderUtil.java | 4 +-
.../aria/ftp/upload/FtpULoaferAdapter.java | 6 +-
...eInfoThread.java => HttpFileInfoTask.java} | 30 ++-
.../arialyy/aria/http/HttpGroupInfoTask.java | 167 +++++++++++++++
...ordAdapter.java => HttpRecordHandler.java} | 14 +-
.../aria/http/download/DGroupLoaderUtil.java | 8 +-
.../http/download/HttpDLoaderAdapter.java | 200 +++++++++---------
.../aria/http/download/HttpDLoaderUtil.java | 36 ++--
.../aria/http/download/HttpDTTBuilder.java | 62 ++++++
.../http/download/HttpSubDLoaderUtil.java | 4 +-
.../aria/http/upload/HttpULoaderAdapter.java | 6 +-
.../com/arialyy/aria/m3u8/BaseM3U8Loader.java | 4 +-
...ordAdapter.java => M3U8RecordHandler.java} | 8 +-
.../core/common/AbsRecordHandlerAdapter.java | 44 ----
.../aria/core/common/RecordHandler.java | 56 +++--
.../aria/core/common/RecordHelper.java | 2 +-
.../arialyy/aria/core/config/XMLReader.java | 4 +-
...GroupUtil.java => AbsGroupLoaderUtil.java} | 4 +-
.../aria/core/group/SimpleSchedulers.java | 2 +-
.../aria/core/group/SimpleSubQueue.java | 2 +-
.../arialyy/aria/core/inf/IThreadState.java | 15 +-
.../aria/core/listener/BaseDListener.java | 2 +-
.../aria/core/listener/BaseUListener.java | 2 +-
.../core/listener/DownloadGroupListener.java | 2 +-
.../arialyy/aria/core/loader/AbsLoader.java | 97 +++++----
.../aria/core/loader/AbsNormalLoaderUtil.java | 36 ++--
.../aria/core/loader/AbsNormalTTBuilder.java | 185 ++++++++++++++++
.../IInfoTask.java} | 40 ++--
.../com/arialyy/aria/core/loader/ILoader.java | 15 +-
.../aria/core/loader/ILoaderAdapter.java | 1 -
...erIntercept.java => ILoaderComponent.java} | 32 +--
...erInterceptor.java => ILoaderVisitor.java} | 43 ++--
.../IRecordHandler.java} | 37 +++-
.../IThreadTaskBuilder.java} | 31 +--
.../arialyy/aria/core/loader/LoaderChain.java | 75 -------
...dInterceptor.java => LoaderStructure.java} | 38 ++--
.../aria/core/loader/NormalLoader.java | 186 +++++-----------
.../aria/core/loader/ThreadStateManager.java | 140 ++++++------
.../arialyy/aria/core/task/AbsGroupTask.java | 6 +-
.../arialyy/aria/core/task/IThreadTask.java | 6 +
.../arialyy/aria/core/task/ThreadTask.java | 4 +
.../java/com/arialyy/aria/util/CheckUtil.java | 2 +-
.../com/arialyy/aria/util/RecordUtil.java | 2 +-
app/gradle.properties | 4 +-
build.gradle | 4 +-
52 files changed, 1003 insertions(+), 689 deletions(-)
rename FtpComponent/src/main/java/com/arialyy/aria/ftp/{FtpRecordAdapter.java => FtpRecordHandler.java} (93%)
rename HttpComponent/src/main/java/com/arialyy/aria/http/{HttpFileInfoThread.java => HttpFileInfoTask.java} (94%)
create mode 100644 HttpComponent/src/main/java/com/arialyy/aria/http/HttpGroupInfoTask.java
rename HttpComponent/src/main/java/com/arialyy/aria/http/{HttpRecordAdapter.java => HttpRecordHandler.java} (90%)
create mode 100644 HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDTTBuilder.java
rename M3U8Component/src/main/java/com/arialyy/aria/m3u8/{M3U8RecordAdapter.java => M3U8RecordHandler.java} (95%)
delete mode 100644 PublicComponent/src/main/java/com/arialyy/aria/core/common/AbsRecordHandlerAdapter.java
rename PublicComponent/src/main/java/com/arialyy/aria/core/group/{AbsGroupUtil.java => AbsGroupLoaderUtil.java} (98%)
create mode 100644 PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsNormalTTBuilder.java
rename PublicComponent/src/main/java/com/arialyy/aria/core/{inf/OnFileInfoCallback.java => loader/IInfoTask.java} (60%)
rename PublicComponent/src/main/java/com/arialyy/aria/core/loader/{LoaderIntercept.java => ILoaderComponent.java} (63%)
rename PublicComponent/src/main/java/com/arialyy/aria/core/loader/{ILoaderInterceptor.java => ILoaderVisitor.java} (60%)
rename PublicComponent/src/main/java/com/arialyy/aria/core/{inf/IRecordHandlerAdapter.java => loader/IRecordHandler.java} (69%)
rename PublicComponent/src/main/java/com/arialyy/aria/core/{inf/IRecordHandler.java => loader/IThreadTaskBuilder.java} (55%)
delete mode 100644 PublicComponent/src/main/java/com/arialyy/aria/core/loader/LoaderChain.java
rename PublicComponent/src/main/java/com/arialyy/aria/core/loader/{RecordInterceptor.java => LoaderStructure.java} (50%)
diff --git a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
index a562e53b..c7483c7c 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
@@ -35,7 +35,7 @@ import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.download.DownloadReceiver;
import com.arialyy.aria.core.inf.AbsReceiver;
import com.arialyy.aria.core.inf.IReceiver;
-import com.arialyy.aria.core.inf.IRecordHandler;
+import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.inf.ReceiverType;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadReceiver;
diff --git a/Aria/src/main/java/com/arialyy/aria/core/manager/DTaskWrapperFactory.java b/Aria/src/main/java/com/arialyy/aria/core/manager/DTaskWrapperFactory.java
index 16e6592d..6f08c620 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/manager/DTaskWrapperFactory.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/manager/DTaskWrapperFactory.java
@@ -19,7 +19,7 @@ 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.inf.IRecordHandler;
+import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import java.io.File;
diff --git a/FtpComponent/src/main/java/aria/apache/commons/net/ftp/FTPFile.java b/FtpComponent/src/main/java/aria/apache/commons/net/ftp/FTPFile.java
index 5edcc119..3a9dd625 100644
--- a/FtpComponent/src/main/java/aria/apache/commons/net/ftp/FTPFile.java
+++ b/FtpComponent/src/main/java/aria/apache/commons/net/ftp/FTPFile.java
@@ -55,7 +55,7 @@ public class FTPFile implements Serializable {
/** A constant indicating file/directory write permission. ***/
public static final int WRITE_PERMISSION = 1;
/**
- * A constant indicating file execute permission or directory listing
+ * A constant indicating file accept permission or directory listing
* permission.
***/
public static final int EXECUTE_PERMISSION = 2;
diff --git a/FtpComponent/src/main/java/aria/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java b/FtpComponent/src/main/java/aria/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java
index 7585ebbe..212198b3 100644
--- a/FtpComponent/src/main/java/aria/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java
+++ b/FtpComponent/src/main/java/aria/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java
@@ -95,7 +95,7 @@ public class NetwareFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
* Netware file permissions are in the following format: RWCEAFMS, and are explained as follows:
*
* - S - Supervisor; All rights.
- *
- R - Read; Right to open and read or execute.
+ *
- R - Read; Right to open and read or accept.
*
- W - Write; Right to open and modify.
*
- C - Create; Right to create; when assigned to a file, allows a deleted file to be
* recovered.
diff --git a/FtpComponent/src/main/java/aria/apache/commons/net/ftp/parser/VMSFTPEntryParser.java b/FtpComponent/src/main/java/aria/apache/commons/net/ftp/parser/VMSFTPEntryParser.java
index b2578cd0..6c23179c 100644
--- a/FtpComponent/src/main/java/aria/apache/commons/net/ftp/parser/VMSFTPEntryParser.java
+++ b/FtpComponent/src/main/java/aria/apache/commons/net/ftp/parser/VMSFTPEntryParser.java
@@ -164,7 +164,7 @@ public class VMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
//Set file permission.
//VMS has (SYSTEM,OWNER,GROUP,WORLD) users that can contain
- //R (read) W (write) E (execute) D (delete)
+ //R (read) W (write) E (accept) D (delete)
//iterate for OWNER GROUP WORLD permissions
for (int access = 0; access < 3; access++) {
diff --git a/FtpComponent/src/main/java/com/arialyy/aria/ftp/FtpRecordAdapter.java b/FtpComponent/src/main/java/com/arialyy/aria/ftp/FtpRecordHandler.java
similarity index 93%
rename from FtpComponent/src/main/java/com/arialyy/aria/ftp/FtpRecordAdapter.java
rename to FtpComponent/src/main/java/com/arialyy/aria/ftp/FtpRecordHandler.java
index 8a3bd02a..79a3e0ea 100644
--- a/FtpComponent/src/main/java/com/arialyy/aria/ftp/FtpRecordAdapter.java
+++ b/FtpComponent/src/main/java/com/arialyy/aria/ftp/FtpRecordHandler.java
@@ -17,11 +17,11 @@ package com.arialyy.aria.ftp;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.ThreadRecord;
-import com.arialyy.aria.core.common.AbsRecordHandlerAdapter;
+import com.arialyy.aria.core.common.RecordHandler;
import com.arialyy.aria.core.common.RecordHelper;
import com.arialyy.aria.core.config.Configuration;
import com.arialyy.aria.core.download.DownloadEntity;
-import com.arialyy.aria.core.inf.IRecordHandler;
+import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.util.RecordUtil;
@@ -31,9 +31,9 @@ import java.util.ArrayList;
* @Author lyy
* @Date 2019-09-19
*/
-public class FtpRecordAdapter extends AbsRecordHandlerAdapter {
+public class FtpRecordHandler extends RecordHandler {
- public FtpRecordAdapter(AbsTaskWrapper wrapper) {
+ public FtpRecordHandler(AbsTaskWrapper wrapper) {
super(wrapper);
}
diff --git a/FtpComponent/src/main/java/com/arialyy/aria/ftp/download/FtpDLoaderAdapter.java b/FtpComponent/src/main/java/com/arialyy/aria/ftp/download/FtpDLoaderAdapter.java
index b063972e..6e81ef70 100644
--- a/FtpComponent/src/main/java/com/arialyy/aria/ftp/download/FtpDLoaderAdapter.java
+++ b/FtpComponent/src/main/java/com/arialyy/aria/ftp/download/FtpDLoaderAdapter.java
@@ -18,13 +18,13 @@ package com.arialyy.aria.ftp.download;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.common.RecordHandler;
import com.arialyy.aria.core.common.SubThreadConfig;
-import com.arialyy.aria.core.inf.IRecordHandler;
+import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.task.AbsNormalLoaderAdapter;
import com.arialyy.aria.core.task.IThreadTask;
import com.arialyy.aria.core.task.ThreadTask;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
-import com.arialyy.aria.ftp.FtpRecordAdapter;
+import com.arialyy.aria.ftp.FtpRecordHandler;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.FileUtil;
import java.io.File;
@@ -66,7 +66,7 @@ public class FtpDLoaderAdapter extends AbsNormalLoaderAdapter {
}
@Override public IRecordHandler recordHandler(AbsTaskWrapper wrapper) {
- FtpRecordAdapter adapter = new FtpRecordAdapter(wrapper);
+ FtpRecordHandler adapter = new FtpRecordHandler(wrapper);
RecordHandler handler = new RecordHandler(wrapper);
handler.setAdapter(adapter);
return handler;
diff --git a/FtpComponent/src/main/java/com/arialyy/aria/ftp/download/FtpDirDLoaderUtil.java b/FtpComponent/src/main/java/com/arialyy/aria/ftp/download/FtpDirDLoaderUtil.java
index 9344f982..e58a665b 100644
--- a/FtpComponent/src/main/java/com/arialyy/aria/ftp/download/FtpDirDLoaderUtil.java
+++ b/FtpComponent/src/main/java/com/arialyy/aria/ftp/download/FtpDirDLoaderUtil.java
@@ -21,7 +21,7 @@ import com.arialyy.aria.core.FtpUrlEntity;
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.group.AbsGroupUtil;
+import com.arialyy.aria.core.group.AbsGroupLoaderUtil;
import com.arialyy.aria.core.group.AbsSubDLoadUtil;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.OnFileInfoCallback;
@@ -37,7 +37,7 @@ import java.util.concurrent.locks.ReentrantLock;
* Created by Aria.Lao on 2017/7/27.
* ftp文件夹下载工具
*/
-public class FtpDirDLoaderUtil extends AbsGroupUtil {
+public class FtpDirDLoaderUtil extends AbsGroupLoaderUtil {
private ReentrantLock LOCK = new ReentrantLock();
private Condition condition = LOCK.newCondition();
diff --git a/FtpComponent/src/main/java/com/arialyy/aria/ftp/upload/FtpULoaferAdapter.java b/FtpComponent/src/main/java/com/arialyy/aria/ftp/upload/FtpULoaferAdapter.java
index f3a44b2b..3ec3312f 100644
--- a/FtpComponent/src/main/java/com/arialyy/aria/ftp/upload/FtpULoaferAdapter.java
+++ b/FtpComponent/src/main/java/com/arialyy/aria/ftp/upload/FtpULoaferAdapter.java
@@ -21,10 +21,10 @@ import com.arialyy.aria.core.common.RecordHandler;
import com.arialyy.aria.core.common.SubThreadConfig;
import com.arialyy.aria.core.task.ThreadTask;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
-import com.arialyy.aria.core.inf.IRecordHandler;
+import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.task.IThreadTask;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
-import com.arialyy.aria.ftp.FtpRecordAdapter;
+import com.arialyy.aria.ftp.FtpRecordHandler;
/**
* @Author lyy
@@ -48,7 +48,7 @@ class FtpULoaferAdapter extends AbsNormalLoaderAdapter {
}
@Override public IRecordHandler recordHandler(AbsTaskWrapper wrapper) {
- FtpRecordAdapter adapter = new FtpRecordAdapter(wrapper);
+ FtpRecordHandler adapter = new FtpRecordHandler(wrapper);
RecordHandler handler = new RecordHandler(wrapper);
handler.setAdapter(adapter);
return handler;
diff --git a/HttpComponent/src/main/java/com/arialyy/aria/http/HttpFileInfoThread.java b/HttpComponent/src/main/java/com/arialyy/aria/http/HttpFileInfoTask.java
similarity index 94%
rename from HttpComponent/src/main/java/com/arialyy/aria/http/HttpFileInfoThread.java
rename to HttpComponent/src/main/java/com/arialyy/aria/http/HttpFileInfoTask.java
index e484c5cc..7d877bc7 100644
--- a/HttpComponent/src/main/java/com/arialyy/aria/http/HttpFileInfoThread.java
+++ b/HttpComponent/src/main/java/com/arialyy/aria/http/HttpFileInfoTask.java
@@ -24,7 +24,8 @@ import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
-import com.arialyy.aria.core.inf.OnFileInfoCallback;
+import com.arialyy.aria.core.loader.IInfoTask;
+import com.arialyy.aria.core.loader.ILoaderVisitor;
import com.arialyy.aria.core.processor.IHttpFileLenAdapter;
import com.arialyy.aria.exception.AriaIOException;
import com.arialyy.aria.exception.BaseException;
@@ -54,19 +55,18 @@ import java.util.UUID;
/**
* 下载文件信息获取
*/
-public class HttpFileInfoThread implements Runnable {
+public class HttpFileInfoTask implements IInfoTask, Runnable {
private static final String TAG = "HttpFileInfoThread";
private DownloadEntity mEntity;
private DTaskWrapper mTaskWrapper;
private int mConnectTimeOut;
- private OnFileInfoCallback onFileInfoCallback;
+ private Callback callback;
private HttpTaskOption taskOption;
- public HttpFileInfoThread(DTaskWrapper taskWrapper, OnFileInfoCallback callback) {
+ public HttpFileInfoTask(DTaskWrapper taskWrapper) {
this.mTaskWrapper = taskWrapper;
mEntity = taskWrapper.getEntity();
mConnectTimeOut = AriaConfig.getInstance().getDConfig().getConnectTimeOut();
- onFileInfoCallback = callback;
taskOption = (HttpTaskOption) taskWrapper.getTaskOption();
}
@@ -99,6 +99,10 @@ public class HttpFileInfoThread implements Runnable {
}
}
+ @Override public void setCallback(Callback callback) {
+ this.callback = callback;
+ }
+
private void handleConnect(HttpURLConnection conn) throws IOException {
if (taskOption.getRequestEnum() == RequestEnum.POST) {
Map params = taskOption.getParams();
@@ -223,9 +227,9 @@ public class HttpFileInfoThread implements Runnable {
}
if (end) {
taskOption.setChunked(isChunked);
- if (onFileInfoCallback != null) {
+ if (callback != null) {
CompleteInfo info = new CompleteInfo(code, mTaskWrapper);
- onFileInfoCallback.onComplete(mEntity.getUrl(), info);
+ callback.onSucceed(mEntity.getUrl(), info);
}
mEntity.update();
}
@@ -291,8 +295,8 @@ public class HttpFileInfoThread implements Runnable {
private void handleUrlReTurn(HttpURLConnection conn, String newUrl) throws IOException {
ALog.d(TAG, "30x跳转,新url为【" + newUrl + "】");
if (TextUtils.isEmpty(newUrl) || newUrl.equalsIgnoreCase("null")) {
- if (onFileInfoCallback != null) {
- onFileInfoCallback.onFail(mEntity, new TaskException(TAG, "获取重定向链接失败"), false);
+ if (callback != null) {
+ callback.onFail(mEntity, new TaskException(TAG, "获取重定向链接失败"), false);
}
return;
}
@@ -336,11 +340,15 @@ public class HttpFileInfoThread implements Runnable {
}
private void failDownload(BaseException e, boolean needRetry) {
- if (onFileInfoCallback != null) {
- onFileInfoCallback.onFail(mEntity, e, needRetry);
+ if (callback != null) {
+ callback.onFail(mEntity, e, needRetry);
}
}
+ @Override public void accept(ILoaderVisitor visitor) {
+ visitor.addComponent(this);
+ }
+
private static class FileLenAdapter implements IHttpFileLenAdapter {
@Override public long handleFileLen(Map> headers) {
diff --git a/HttpComponent/src/main/java/com/arialyy/aria/http/HttpGroupInfoTask.java b/HttpComponent/src/main/java/com/arialyy/aria/http/HttpGroupInfoTask.java
new file mode 100644
index 00000000..e7ecacf5
--- /dev/null
+++ b/HttpComponent/src/main/java/com/arialyy/aria/http/HttpGroupInfoTask.java
@@ -0,0 +1,167 @@
+/*
+ * 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;
+
+import com.arialyy.aria.core.common.AbsEntity;
+import com.arialyy.aria.core.common.CompleteInfo;
+import com.arialyy.aria.core.download.DGTaskWrapper;
+import com.arialyy.aria.core.download.DTaskWrapper;
+import com.arialyy.aria.core.download.DownloadEntity;
+import com.arialyy.aria.core.listener.DownloadGroupListener;
+import com.arialyy.aria.core.loader.IInfoTask;
+import com.arialyy.aria.core.loader.ILoaderVisitor;
+import com.arialyy.aria.exception.AriaIOException;
+import com.arialyy.aria.exception.BaseException;
+import com.arialyy.aria.util.ALog;
+import com.arialyy.aria.util.CommonUtil;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * 组合任务文件信息,用于获取长度未知时,组合任务的长度
+ */
+public class HttpGroupInfoTask implements IInfoTask {
+ private String TAG = CommonUtil.getClassName(this);
+ private Callback callback;
+ private DGTaskWrapper wrapper;
+ private final Object LOCK = new Object();
+ private ExecutorService mPool = null;
+ private boolean getLenComplete = false;
+ private int count;
+ private int failCount;
+ private DownloadGroupListener listener;
+
+ /**
+ * 子任务回调
+ */
+ private Callback subCallback = new Callback() {
+ @Override public void onSucceed(String url, CompleteInfo info) {
+ count++;
+ checkGetSizeComplete(count, failCount);
+ ALog.d(TAG, "获取子任务信息完成");
+ }
+
+ @Override public void onFail(AbsEntity entity, BaseException e, boolean needRetry) {
+ ALog.e(TAG, String.format("获取文件信息失败,url:%s", ((DownloadEntity) entity).getUrl()));
+ count++;
+ failCount++;
+ listener.onSubFail((DownloadEntity) entity, new AriaIOException(TAG,
+ String.format("子任务获取文件长度失败,url:%s", ((DownloadEntity) entity).getUrl())));
+ checkGetSizeComplete(count, failCount);
+ }
+ };
+
+ public HttpGroupInfoTask(DGTaskWrapper wrapper, DownloadGroupListener listener) {
+ this.wrapper = wrapper;
+ this.listener = listener;
+ }
+
+ @Override public void run() {
+ // 如果是isUnknownSize()标志,并且获取大小没有完成,则直接回调onStop
+ if (mPool != null && !getLenComplete) {
+ ALog.d(TAG, "获取长度未完成的情况下,停止组合任务");
+ mPool.shutdown();
+ //mListener.onStop(0);
+ return;
+ }
+ // 处理组合任务大小未知的情况
+ if (wrapper.isUnknownSize() && wrapper.getEntity().getFileSize() < 1) {
+ mPool = Executors.newCachedThreadPool();
+ getGroupSize();
+ try {
+ synchronized (LOCK) {
+ LOCK.wait();
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ } else {
+ for (DTaskWrapper wrapper : wrapper.getSubTaskWrapper()) {
+ cloneHeader(wrapper);
+ }
+ callback.onSucceed(wrapper.getKey(), new CompleteInfo());
+ }
+ }
+
+ /**
+ * 获取组合任务大小,使用该方式获取到的组合任务大小,子任务不需要再重新获取文件大小
+ */
+ private void getGroupSize() {
+ new Thread(new Runnable() {
+ @Override public void run() {
+ for (DTaskWrapper dTaskWrapper : wrapper.getSubTaskWrapper()) {
+ cloneHeader(dTaskWrapper);
+ HttpFileInfoTask infoTask = new HttpFileInfoTask(dTaskWrapper);
+ infoTask.setCallback(subCallback);
+ }
+ }
+ }).start();
+ }
+
+ /**
+ * 检查组合任务大小是否获取完成,获取完成后取消阻塞,并设置组合任务大小
+ */
+ private void checkGetSizeComplete(int count, int failCount) {
+ if (failCount == wrapper.getSubTaskWrapper().size()) {
+ callback.onFail(wrapper.getEntity(), new AriaIOException(TAG, "获取子任务长度失败"), false);
+ notifyLock();
+ return;
+ }
+ if (count == wrapper.getSubTaskWrapper().size()) {
+ long size = 0;
+ for (DTaskWrapper wrapper : wrapper.getSubTaskWrapper()) {
+ size += wrapper.getEntity().getFileSize();
+ }
+ wrapper.getEntity().setConvertFileSize(CommonUtil.formatFileSize(size));
+ wrapper.getEntity().setFileSize(size);
+ wrapper.getEntity().update();
+ getLenComplete = true;
+ ALog.d(TAG, String.format("获取组合任务长度完成,组合任务总长度:%s,失败的只任务数:%s", size, failCount));
+ callback.onSucceed(wrapper.getKey(), new CompleteInfo());
+ notifyLock();
+ }
+ }
+
+ private void notifyLock() {
+ synchronized (LOCK) {
+ LOCK.notifyAll();
+ }
+ }
+
+ /**
+ * 子任务使用父包裹器的属性
+ */
+ private void cloneHeader(DTaskWrapper taskWrapper) {
+ HttpTaskOption groupOption = (HttpTaskOption) wrapper.getTaskOption();
+ HttpTaskOption subOption = new HttpTaskOption();
+
+ // 设置属性
+ subOption.setFileLenAdapter(groupOption.getFileLenAdapter());
+ subOption.setRequestEnum(groupOption.getRequestEnum());
+ subOption.setHeaders(groupOption.getHeaders());
+ subOption.setProxy(groupOption.getProxy());
+ subOption.setParams(groupOption.getParams());
+ taskWrapper.setTaskOption(subOption);
+ }
+
+ @Override public void setCallback(Callback callback) {
+ this.callback = callback;
+ }
+
+ @Override public void accept(ILoaderVisitor visitor) {
+ visitor.addComponent(this);
+ }
+}
diff --git a/HttpComponent/src/main/java/com/arialyy/aria/http/HttpRecordAdapter.java b/HttpComponent/src/main/java/com/arialyy/aria/http/HttpRecordHandler.java
similarity index 90%
rename from HttpComponent/src/main/java/com/arialyy/aria/http/HttpRecordAdapter.java
rename to HttpComponent/src/main/java/com/arialyy/aria/http/HttpRecordHandler.java
index 1dbba97b..ecdbbe0f 100644
--- a/HttpComponent/src/main/java/com/arialyy/aria/http/HttpRecordAdapter.java
+++ b/HttpComponent/src/main/java/com/arialyy/aria/http/HttpRecordHandler.java
@@ -17,11 +17,11 @@ package com.arialyy.aria.http;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.ThreadRecord;
-import com.arialyy.aria.core.common.AbsRecordHandlerAdapter;
+import com.arialyy.aria.core.common.RecordHandler;
import com.arialyy.aria.core.common.RecordHelper;
import com.arialyy.aria.core.config.Configuration;
import com.arialyy.aria.core.download.DownloadEntity;
-import com.arialyy.aria.core.inf.IRecordHandler;
+import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.util.RecordUtil;
@@ -31,16 +31,16 @@ import java.util.ArrayList;
* @Author lyy
* @Date 2019-09-23
*/
-public class HttpRecordAdapter extends AbsRecordHandlerAdapter {
- public HttpRecordAdapter(AbsTaskWrapper wrapper) {
+public class HttpRecordHandler extends RecordHandler {
+ public HttpRecordHandler(AbsTaskWrapper wrapper) {
super(wrapper);
}
@Override public void onPre() {
super.onPre();
- if (getWrapper().getRequestType() == ITaskWrapper.U_HTTP) {
- RecordUtil.delTaskRecord(getEntity().getFilePath(), IRecordHandler.TYPE_UPLOAD);
- }
+ //if (getWrapper().getRequestType() == ITaskWrapper.U_HTTP) {
+ // RecordUtil.delTaskRecord(getEntity().getFilePath(), IRecordHandler.TYPE_UPLOAD);
+ //}
}
@Override public void handlerTaskRecord(TaskRecord record) {
diff --git a/HttpComponent/src/main/java/com/arialyy/aria/http/download/DGroupLoaderUtil.java b/HttpComponent/src/main/java/com/arialyy/aria/http/download/DGroupLoaderUtil.java
index 016576c7..f2e457e4 100644
--- a/HttpComponent/src/main/java/com/arialyy/aria/http/download/DGroupLoaderUtil.java
+++ b/HttpComponent/src/main/java/com/arialyy/aria/http/download/DGroupLoaderUtil.java
@@ -25,9 +25,9 @@ import com.arialyy.aria.core.listener.IEventListener;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.exception.AriaIOException;
import com.arialyy.aria.exception.BaseException;
-import com.arialyy.aria.core.group.AbsGroupUtil;
+import com.arialyy.aria.core.group.AbsGroupLoaderUtil;
import com.arialyy.aria.core.group.AbsSubDLoadUtil;
-import com.arialyy.aria.http.HttpFileInfoThread;
+import com.arialyy.aria.http.HttpFileInfoTask;
import com.arialyy.aria.http.HttpTaskOption;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
@@ -40,7 +40,7 @@ import java.util.concurrent.Executors;
* Created by AriaL on 2017/6/30.
* 任务组下载工具
*/
-public class DGroupLoaderUtil extends AbsGroupUtil {
+public class DGroupLoaderUtil extends AbsGroupLoaderUtil {
private final Object LOCK = new Object();
private ExecutorService mPool = null;
private boolean getLenComplete = false;
@@ -113,7 +113,7 @@ public class DGroupLoaderUtil extends AbsGroupUtil {
@Override public void run() {
for (DTaskWrapper dTaskWrapper : getWrapper().getSubTaskWrapper()) {
cloneHeader(dTaskWrapper);
- mPool.submit(new HttpFileInfoThread(dTaskWrapper, new OnFileInfoCallback() {
+ mPool.submit(new HttpFileInfoTask(dTaskWrapper, new OnFileInfoCallback() {
@Override public void onComplete(String url, CompleteInfo info) {
if (!getWrapper().isUnknownSize()) {
startSubLoader(createSubLoader((DTaskWrapper) info.wrapper, false));
diff --git a/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDLoaderAdapter.java b/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDLoaderAdapter.java
index 0b5ed415..2510958a 100644
--- a/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDLoaderAdapter.java
+++ b/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDLoaderAdapter.java
@@ -1,100 +1,100 @@
-/*
- * 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.TaskRecord;
-import com.arialyy.aria.core.common.RecordHandler;
-import com.arialyy.aria.core.common.SubThreadConfig;
-import com.arialyy.aria.core.download.DownloadEntity;
-import com.arialyy.aria.core.inf.IRecordHandler;
-import com.arialyy.aria.core.task.AbsNormalLoaderAdapter;
-import com.arialyy.aria.core.task.IThreadTask;
-import com.arialyy.aria.core.task.ThreadTask;
-import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
-import com.arialyy.aria.core.wrapper.ITaskWrapper;
-import com.arialyy.aria.http.HttpRecordAdapter;
-import com.arialyy.aria.util.ALog;
-import com.arialyy.aria.util.BufferedRandomAccessFile;
-import com.arialyy.aria.util.FileUtil;
-import java.io.File;
-import java.io.IOException;
-
-/**
- * @Author lyy
- * @Date 2019-09-21
- */
-final class HttpDLoaderAdapter extends AbsNormalLoaderAdapter {
- HttpDLoaderAdapter(ITaskWrapper wrapper) {
- super(wrapper);
- }
-
- @Override public boolean handleNewTask(TaskRecord record, int totalThreadNum) {
- if (!record.isBlock) {
- if (getTempFile().exists()) {
- FileUtil.deleteFile(getTempFile());
- }
- } else {
- for (int i = 0; i < totalThreadNum; i++) {
- File blockFile =
- new File(String.format(IRecordHandler.SUB_PATH, getTempFile().getPath(), i));
- if (blockFile.exists()) {
- ALog.d(TAG, String.format("分块【%s】已经存在,将删除该分块", i));
- FileUtil.deleteFile(blockFile);
- }
- }
- }
- BufferedRandomAccessFile file = null;
- try {
- if (totalThreadNum > 1 && !record.isBlock) {
- file = new BufferedRandomAccessFile(new File(getTempFile().getPath()), "rwd", 8192);
- //设置文件长度
- file.setLength(getEntity().getFileSize());
- }
- return true;
- } catch (IOException e) {
- e.printStackTrace();
- ALog.e(TAG, String.format("下载失败,filePath: %s, url: %s", getEntity().getFilePath(),
- getEntity().getUrl()));
- } finally {
- if (file != null) {
- try {
- file.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- return false;
- }
-
- @Override public IThreadTask createThreadTask(SubThreadConfig config) {
- ThreadTask task = new ThreadTask(config);
- HttpDThreadTaskAdapter adapter = new HttpDThreadTaskAdapter(config);
- task.setAdapter(adapter);
- return task;
- }
-
- @Override public IRecordHandler recordHandler(AbsTaskWrapper wrapper) {
- RecordHandler recordHandler = new RecordHandler(wrapper);
- HttpRecordAdapter adapter = new HttpRecordAdapter(wrapper);
- recordHandler.setAdapter(adapter);
- return recordHandler;
- }
-
- private DownloadEntity getEntity() {
- return (DownloadEntity) getWrapper().getEntity();
- }
-}
+///*
+// * 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.TaskRecord;
+//import com.arialyy.aria.core.common.RecordHandler;
+//import com.arialyy.aria.core.common.SubThreadConfig;
+//import com.arialyy.aria.core.download.DownloadEntity;
+//import com.arialyy.aria.core.loader.IRecordHandler;
+//import com.arialyy.aria.core.task.AbsNormalLoaderAdapter;
+//import com.arialyy.aria.core.task.IThreadTask;
+//import com.arialyy.aria.core.task.ThreadTask;
+//import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
+//import com.arialyy.aria.core.wrapper.ITaskWrapper;
+//import com.arialyy.aria.http.HttpRecordHandler;
+//import com.arialyy.aria.util.ALog;
+//import com.arialyy.aria.util.BufferedRandomAccessFile;
+//import com.arialyy.aria.util.FileUtil;
+//import java.io.File;
+//import java.io.IOException;
+//
+///**
+// * @Author lyy
+// * @Date 2019-09-21
+// */
+//final class HttpDLoaderAdapter extends AbsNormalLoaderAdapter {
+// HttpDLoaderAdapter(ITaskWrapper wrapper) {
+// super(wrapper);
+// }
+//
+// @Override public boolean handleNewTask(TaskRecord record, int totalThreadNum) {
+// if (!record.isBlock) {
+// if (getTempFile().exists()) {
+// FileUtil.deleteFile(getTempFile());
+// }
+// } else {
+// for (int i = 0; i < totalThreadNum; i++) {
+// File blockFile =
+// new File(String.format(IRecordHandler.SUB_PATH, getTempFile().getPath(), i));
+// if (blockFile.exists()) {
+// ALog.d(TAG, String.format("分块【%s】已经存在,将删除该分块", i));
+// FileUtil.deleteFile(blockFile);
+// }
+// }
+// }
+// BufferedRandomAccessFile file = null;
+// try {
+// if (totalThreadNum > 1 && !record.isBlock) {
+// file = new BufferedRandomAccessFile(new File(getTempFile().getPath()), "rwd", 8192);
+// //设置文件长度
+// file.setLength(getEntity().getFileSize());
+// }
+// return true;
+// } catch (IOException e) {
+// e.printStackTrace();
+// ALog.e(TAG, String.format("下载失败,filePath: %s, url: %s", getEntity().getFilePath(),
+// getEntity().getUrl()));
+// } finally {
+// if (file != null) {
+// try {
+// file.close();
+// } catch (IOException e) {
+// e.printStackTrace();
+// }
+// }
+// }
+// return false;
+// }
+//
+// @Override public IThreadTask createThreadTask(SubThreadConfig config) {
+// ThreadTask task = new ThreadTask(config);
+// HttpDThreadTaskAdapter adapter = new HttpDThreadTaskAdapter(config);
+// task.setAdapter(adapter);
+// return task;
+// }
+//
+// @Override public IRecordHandler recordHandler(AbsTaskWrapper wrapper) {
+// RecordHandler recordHandler = new RecordHandler(wrapper);
+// HttpRecordHandler adapter = new HttpRecordHandler(wrapper);
+// recordHandler.setAdapter(adapter);
+// return recordHandler;
+// }
+//
+// private DownloadEntity getEntity() {
+// return (DownloadEntity) getWrapper().getEntity();
+// }
+//}
diff --git a/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDLoaderUtil.java b/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDLoaderUtil.java
index d66025e1..846ebedd 100644
--- a/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDLoaderUtil.java
+++ b/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDLoaderUtil.java
@@ -15,17 +15,16 @@
*/
package com.arialyy.aria.http.download;
-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.inf.OnFileInfoCallback;
import com.arialyy.aria.core.listener.IEventListener;
import com.arialyy.aria.core.loader.AbsLoader;
import com.arialyy.aria.core.loader.AbsNormalLoaderUtil;
+import com.arialyy.aria.core.loader.LoaderStructure;
import com.arialyy.aria.core.loader.NormalLoader;
+import com.arialyy.aria.core.loader.ThreadStateManager;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
-import com.arialyy.aria.exception.BaseException;
-import com.arialyy.aria.http.HttpFileInfoThread;
+import com.arialyy.aria.http.HttpFileInfoTask;
+import com.arialyy.aria.http.HttpRecordHandler;
import com.arialyy.aria.http.HttpTaskOption;
/**
@@ -38,24 +37,17 @@ public class HttpDLoaderUtil extends AbsNormalLoaderUtil {
wrapper.generateTaskOption(HttpTaskOption.class);
}
- @Override protected AbsLoader createLoader() {
- NormalLoader loader = new NormalLoader(getListener(), getTaskWrapper());
- HttpDLoaderAdapter adapter = new HttpDLoaderAdapter(getTaskWrapper());
- loader.setAdapter(adapter);
- return loader;
+ @Override public AbsLoader getLoader() {
+ return mLoader == null ? new NormalLoader(getTaskWrapper(), getListener()) : mLoader;
}
- @Override protected Runnable createInfoThread() {
- return new HttpFileInfoThread((DTaskWrapper) getTaskWrapper(), new OnFileInfoCallback() {
- @Override public void onComplete(String url, CompleteInfo info) {
- ((NormalLoader) getLoader()).updateTempFile();
- getLoader().start();
- }
-
- @Override public void onFail(AbsEntity entity, BaseException e, boolean needRetry) {
- fail(e, needRetry);
- getLoader().closeTimer();
- }
- });
+ public LoaderStructure getLoaderStructure() {
+ LoaderStructure structure = new LoaderStructure();
+ structure.addComponent(new HttpRecordHandler(getTaskWrapper()))
+ .addComponent(new ThreadStateManager(getListener()))
+ .addComponent(new HttpFileInfoTask((DTaskWrapper) getTaskWrapper()))
+ .addComponent(new HttpDTTBuilder(getTaskWrapper()));
+ structure.accept(getLoader());
+ return structure;
}
}
diff --git a/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDTTBuilder.java b/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDTTBuilder.java
new file mode 100644
index 00000000..eb22a80c
--- /dev/null
+++ b/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDTTBuilder.java
@@ -0,0 +1,62 @@
+package com.arialyy.aria.http.download;
+
+import com.arialyy.aria.core.TaskRecord;
+import com.arialyy.aria.core.common.SubThreadConfig;
+import com.arialyy.aria.core.loader.AbsNormalTTBuilder;
+import com.arialyy.aria.core.loader.IRecordHandler;
+import com.arialyy.aria.core.task.IThreadTaskAdapter;
+import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
+import com.arialyy.aria.util.ALog;
+import com.arialyy.aria.util.BufferedRandomAccessFile;
+import com.arialyy.aria.util.FileUtil;
+import java.io.File;
+import java.io.IOException;
+
+final class HttpDTTBuilder extends AbsNormalTTBuilder {
+ HttpDTTBuilder(AbsTaskWrapper wrapper) {
+ super(wrapper);
+ }
+
+ @Override public IThreadTaskAdapter getAdapter(SubThreadConfig config) {
+ return new HttpDThreadTaskAdapter(config);
+ }
+
+ @Override public boolean handleNewTask(TaskRecord record, int totalThreadNum) {
+ if (!record.isBlock) {
+ if (getTempFile().exists()) {
+ FileUtil.deleteFile(getTempFile());
+ }
+ } else {
+ for (int i = 0; i < totalThreadNum; i++) {
+ File blockFile =
+ new File(String.format(IRecordHandler.SUB_PATH, getTempFile().getPath(), i));
+ if (blockFile.exists()) {
+ ALog.d(TAG, String.format("分块【%s】已经存在,将删除该分块", i));
+ FileUtil.deleteFile(blockFile);
+ }
+ }
+ }
+ BufferedRandomAccessFile file = null;
+ try {
+ if (totalThreadNum > 1 && !record.isBlock) {
+ file = new BufferedRandomAccessFile(new File(getTempFile().getPath()), "rwd", 8192);
+ //设置文件长度
+ file.setLength(getEntity().getFileSize());
+ }
+ return true;
+ } catch (IOException e) {
+ e.printStackTrace();
+ ALog.e(TAG, String.format("下载失败,filePath: %s, url: %s", getEntity().getFilePath(),
+ getEntity().getUrl()));
+ } finally {
+ if (file != null) {
+ try {
+ file.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpSubDLoaderUtil.java b/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpSubDLoaderUtil.java
index cb19d22e..03c5117e 100644
--- a/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpSubDLoaderUtil.java
+++ b/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpSubDLoaderUtil.java
@@ -25,7 +25,7 @@ import com.arialyy.aria.core.inf.OnFileInfoCallback;
import com.arialyy.aria.core.listener.ISchedulers;
import com.arialyy.aria.core.loader.NormalLoader;
import com.arialyy.aria.exception.BaseException;
-import com.arialyy.aria.http.HttpFileInfoThread;
+import com.arialyy.aria.http.HttpFileInfoTask;
/**
* @Author lyy
@@ -49,7 +49,7 @@ class HttpSubDLoaderUtil extends AbsSubDLoadUtil {
@Override public void start() {
if (isNeedGetInfo()) {
- new Thread(new HttpFileInfoThread(getWrapper(), new OnFileInfoCallback() {
+ new Thread(new HttpFileInfoTask(getWrapper(), new OnFileInfoCallback() {
@Override public void onComplete(String url, CompleteInfo info) {
getDownloader().start();
diff --git a/HttpComponent/src/main/java/com/arialyy/aria/http/upload/HttpULoaderAdapter.java b/HttpComponent/src/main/java/com/arialyy/aria/http/upload/HttpULoaderAdapter.java
index e8899840..d22a0d28 100644
--- a/HttpComponent/src/main/java/com/arialyy/aria/http/upload/HttpULoaderAdapter.java
+++ b/HttpComponent/src/main/java/com/arialyy/aria/http/upload/HttpULoaderAdapter.java
@@ -18,13 +18,13 @@ package com.arialyy.aria.http.upload;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.common.RecordHandler;
import com.arialyy.aria.core.common.SubThreadConfig;
-import com.arialyy.aria.core.inf.IRecordHandler;
+import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.task.AbsNormalLoaderAdapter;
import com.arialyy.aria.core.task.IThreadTask;
import com.arialyy.aria.core.task.ThreadTask;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
-import com.arialyy.aria.http.HttpRecordAdapter;
+import com.arialyy.aria.http.HttpRecordHandler;
/**
* @Author lyy
@@ -48,7 +48,7 @@ final class HttpULoaderAdapter extends AbsNormalLoaderAdapter {
@Override public IRecordHandler recordHandler(AbsTaskWrapper wrapper) {
RecordHandler recordHandler = new RecordHandler(wrapper);
- HttpRecordAdapter adapter = new HttpRecordAdapter(wrapper);
+ HttpRecordHandler adapter = new HttpRecordHandler(wrapper);
recordHandler.setAdapter(adapter);
return recordHandler;
}
diff --git a/M3U8Component/src/main/java/com/arialyy/aria/m3u8/BaseM3U8Loader.java b/M3U8Component/src/main/java/com/arialyy/aria/m3u8/BaseM3U8Loader.java
index 5fd2acd0..8ef1e78e 100644
--- a/M3U8Component/src/main/java/com/arialyy/aria/m3u8/BaseM3U8Loader.java
+++ b/M3U8Component/src/main/java/com/arialyy/aria/m3u8/BaseM3U8Loader.java
@@ -20,7 +20,7 @@ import com.arialyy.aria.core.common.RecordHandler;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.M3U8Entity;
-import com.arialyy.aria.core.inf.IRecordHandler;
+import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.listener.IEventListener;
import com.arialyy.aria.core.loader.AbsLoader;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
@@ -142,7 +142,7 @@ public abstract class BaseM3U8Loader extends AbsLoader {
@Override protected IRecordHandler getRecordHandler(AbsTaskWrapper wrapper) {
RecordHandler handler = new RecordHandler(wrapper);
- M3U8RecordAdapter adapter = new M3U8RecordAdapter((DTaskWrapper) wrapper);
+ M3U8RecordHandler adapter = new M3U8RecordHandler((DTaskWrapper) wrapper);
handler.setAdapter(adapter);
return handler;
}
diff --git a/M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8RecordAdapter.java b/M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8RecordHandler.java
similarity index 95%
rename from M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8RecordAdapter.java
rename to M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8RecordHandler.java
index 17cc04e3..4eb15411 100644
--- a/M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8RecordAdapter.java
+++ b/M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8RecordHandler.java
@@ -17,11 +17,11 @@ package com.arialyy.aria.m3u8;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.ThreadRecord;
-import com.arialyy.aria.core.common.AbsRecordHandlerAdapter;
+import com.arialyy.aria.core.common.RecordHandler;
import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.M3U8Entity;
-import com.arialyy.aria.core.inf.IRecordHandler;
+import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.FileUtil;
@@ -33,10 +33,10 @@ import java.util.ArrayList;
* @Author lyy
* @Date 2019-09-24
*/
-public class M3U8RecordAdapter extends AbsRecordHandlerAdapter {
+public class M3U8RecordHandler extends RecordHandler {
private M3U8TaskOption mOption;
- M3U8RecordAdapter(DTaskWrapper wrapper) {
+ M3U8RecordHandler(DTaskWrapper wrapper) {
super(wrapper);
mOption = (M3U8TaskOption) wrapper.getM3u8Option();
}
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/common/AbsRecordHandlerAdapter.java b/PublicComponent/src/main/java/com/arialyy/aria/core/common/AbsRecordHandlerAdapter.java
deleted file mode 100644
index ee74b0e4..00000000
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/common/AbsRecordHandlerAdapter.java
+++ /dev/null
@@ -1,44 +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.common;
-
-import com.arialyy.aria.core.inf.IRecordHandlerAdapter;
-import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
-import com.arialyy.aria.util.CommonUtil;
-
-/**
- * @Author lyy
- * @Date 2019-09-19
- */
-public abstract class AbsRecordHandlerAdapter implements IRecordHandlerAdapter {
- private AbsTaskWrapper mWrapper;
- protected String TAG = CommonUtil.getClassName(getClass());
-
- @Override public void onPre() {
- }
-
- public AbsRecordHandlerAdapter(AbsTaskWrapper wrapper) {
- mWrapper = wrapper;
- }
-
- public AbsTaskWrapper getWrapper() {
- return mWrapper;
- }
-
- protected AbsNormalEntity getEntity() {
- return (AbsNormalEntity) getWrapper().getEntity();
- }
-}
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHandler.java b/PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHandler.java
index dfe8f2d7..7f8eac62 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHandler.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHandler.java
@@ -18,8 +18,8 @@ package com.arialyy.aria.core.common;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.ThreadRecord;
import com.arialyy.aria.core.download.DownloadEntity;
-import com.arialyy.aria.core.inf.IRecordHandler;
-import com.arialyy.aria.core.inf.IRecordHandlerAdapter;
+import com.arialyy.aria.core.loader.ILoaderVisitor;
+import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
@@ -38,22 +38,29 @@ import java.util.Set;
/**
* 处理任务记录,分配线程区间
*/
-public class RecordHandler implements IRecordHandler {
- private final String TAG = "RecordHandler";
+public abstract class RecordHandler implements IRecordHandler {
+ protected final String TAG = CommonUtil.getClassName(this);
@Deprecated private File mConfigFile;
private TaskRecord mTaskRecord;
private AbsTaskWrapper mTaskWrapper;
private AbsNormalEntity mEntity;
- private IRecordHandlerAdapter mAdapter;
public RecordHandler(AbsTaskWrapper wrapper) {
mTaskWrapper = wrapper;
mEntity = (AbsNormalEntity) mTaskWrapper.getEntity();
}
- public void setAdapter(IRecordHandlerAdapter mAdapter) {
- this.mAdapter = mAdapter;
+ public AbsTaskWrapper getWrapper() {
+ return mTaskWrapper;
+ }
+
+ public AbsNormalEntity getEntity() {
+ return mEntity;
+ }
+
+ @Override public void onPre() {
+
}
/**
@@ -70,10 +77,10 @@ public class RecordHandler implements IRecordHandler {
if (mConfigFile.exists()) {
convertDb();
} else {
- mAdapter.onPre();
+ onPre();
mTaskRecord = DbDataHelper.getTaskRecord(getFilePath(), mEntity.getTaskType());
if (mTaskRecord == null) {
- if (!new File(getFilePath()).exists()){
+ if (!new File(getFilePath()).exists()) {
FileUtil.createFile(getFilePath());
}
initRecord(true);
@@ -83,14 +90,14 @@ public class RecordHandler implements IRecordHandler {
ALog.w(TAG, String.format("文件【%s】不存在,重新分配线程区间", mTaskRecord.filePath));
DbEntity.deleteData(ThreadRecord.class, "taskKey=?", mTaskRecord.filePath);
mTaskRecord.threadRecords.clear();
- mTaskRecord.threadNum = mAdapter.initTaskThreadNum();
+ mTaskRecord.threadNum = initTaskThreadNum();
initRecord(false);
} else if (mTaskRecord.threadRecords == null || mTaskRecord.threadRecords.isEmpty()) {
- mTaskRecord.threadNum = mAdapter.initTaskThreadNum();
+ mTaskRecord.threadNum = initTaskThreadNum();
initRecord(false);
}
}
- mAdapter.handlerTaskRecord(mTaskRecord);
+ handlerTaskRecord(mTaskRecord);
}
saveRecord();
return mTaskRecord;
@@ -127,7 +134,7 @@ public class RecordHandler implements IRecordHandler {
return;
}
mTaskWrapper.setNewTask(false);
- mTaskRecord = mAdapter.createTaskRecord(threadNum);
+ mTaskRecord = createTaskRecord(threadNum);
mTaskRecord.isBlock = false;
File tempFile = new File(getFilePath());
for (int i = 0; i < threadNum; i++) {
@@ -158,7 +165,7 @@ public class RecordHandler implements IRecordHandler {
*/
private void initRecord(boolean newRecord) {
if (newRecord) {
- mTaskRecord = mAdapter.createTaskRecord(mAdapter.initTaskThreadNum());
+ mTaskRecord = createTaskRecord(initTaskThreadNum());
}
mTaskWrapper.setNewTask(true);
int requestType = mTaskWrapper.getRequestType();
@@ -169,7 +176,7 @@ public class RecordHandler implements IRecordHandler {
// 处理线程区间记录
for (int i = 0; i < mTaskRecord.threadNum; i++) {
long startL = i * blockSize, endL = (i + 1) * blockSize;
- ThreadRecord tr = mAdapter.createThreadRecord(mTaskRecord, i, startL, endL);
+ ThreadRecord tr = createThreadRecord(mTaskRecord, i, startL, endL);
mTaskRecord.threadRecords.add(tr);
}
}
@@ -198,4 +205,23 @@ public class RecordHandler implements IRecordHandler {
return ((UploadEntity) mTaskWrapper.getEntity()).getFilePath();
}
}
+
+ @Override public void accept(ILoaderVisitor visitor) {
+ visitor.addComponent(this);
+ }
+
+ @Override public boolean checkTaskCompleted() {
+ if (mTaskRecord == null
+ || mTaskRecord.threadRecords == null
+ || mTaskRecord.threadRecords.isEmpty()) {
+ return false;
+ }
+ int completeNum = 0;
+ for (ThreadRecord tr : mTaskRecord.threadRecords) {
+ if (tr.isComplete) {
+ completeNum++;
+ }
+ }
+ return completeNum != 0 && completeNum == mTaskRecord.threadNum;
+ }
}
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHelper.java b/PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHelper.java
index 2975dc29..9b1ee2ef 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHelper.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHelper.java
@@ -17,7 +17,7 @@ package com.arialyy.aria.core.common;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.ThreadRecord;
-import com.arialyy.aria.core.inf.IRecordHandler;
+import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.BufferedRandomAccessFile;
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/config/XMLReader.java b/PublicComponent/src/main/java/com/arialyy/aria/core/config/XMLReader.java
index 4b17fea4..49fcbba8 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/config/XMLReader.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/config/XMLReader.java
@@ -62,13 +62,13 @@ public class XMLReader extends DefaultHandler {
String value = attributes.getValue("value");
switch (qName) {
- case "threadNum": // 线程数
+ case "getCreatedThreadNum": // 线程数
int threadNum = checkInt(value) ? Integer.parseInt(value) : 3;
if (threadNum < 1) {
ALog.w(TAG, "下载线程数不能小于 1");
threadNum = 1;
}
- setField("threadNum", threadNum, ConfigType.DOWNLOAD);
+ setField("getCreatedThreadNum", threadNum, ConfigType.DOWNLOAD);
break;
case "maxTaskNum": //最大任务书
int maxTaskNum = checkInt(value) ? Integer.parseInt(value) : 2;
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsGroupUtil.java b/PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsGroupLoaderUtil.java
similarity index 98%
rename from PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsGroupUtil.java
rename to PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsGroupLoaderUtil.java
index b216b003..1f0ba27e 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsGroupUtil.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsGroupLoaderUtil.java
@@ -37,7 +37,7 @@ import java.util.concurrent.TimeUnit;
* Created by AriaL on 2017/6/30.
* 任务组核心逻辑
*/
-public abstract class AbsGroupUtil implements IUtil, Runnable {
+public abstract class AbsGroupLoaderUtil implements IUtil, Runnable {
protected final String TAG = CommonUtil.getClassName(getClass());
private long mCurrentLocation = 0;
@@ -52,7 +52,7 @@ public abstract class AbsGroupUtil implements IUtil, Runnable {
private DGTaskWrapper mGTWrapper;
private GroupRunState mState;
- protected AbsGroupUtil(AbsTaskWrapper groupWrapper, IEventListener listener) {
+ protected AbsGroupLoaderUtil(AbsTaskWrapper groupWrapper, IEventListener listener) {
mListener = (IDGroupListener) listener;
mGTWrapper = (DGTaskWrapper) groupWrapper;
mUpdateInterval = Configuration.getInstance().downloadCfg.getUpdateInterval();
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSchedulers.java b/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSchedulers.java
index f4bbf9df..0f8beecb 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSchedulers.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSchedulers.java
@@ -30,7 +30,7 @@ import java.util.concurrent.TimeUnit;
/**
* 组合任务子任务调度器,用于调度任务的开始、停止、失败、完成等情况
- * 该调度器生命周期和{@link AbsGroupUtil}生命周期一致
+ * 该调度器生命周期和{@link AbsGroupLoaderUtil}生命周期一致
*/
class SimpleSchedulers implements ISchedulers {
private static final String TAG = "SimpleSchedulers";
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSubQueue.java b/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSubQueue.java
index c4f87b70..65bec3af 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSubQueue.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSubQueue.java
@@ -26,7 +26,7 @@ import java.util.Map;
import java.util.Set;
/**
- * 组合任务队列,该队列生命周期和{@link AbsGroupUtil}生命周期一致
+ * 组合任务队列,该队列生命周期和{@link AbsGroupLoaderUtil}生命周期一致
*/
class SimpleSubQueue implements ISubQueue {
private static final String TAG = "SimpleSubQueue";
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/inf/IThreadState.java b/PublicComponent/src/main/java/com/arialyy/aria/core/inf/IThreadState.java
index b48bbc47..f0af12ce 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/inf/IThreadState.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/inf/IThreadState.java
@@ -16,11 +16,14 @@
package com.arialyy.aria.core.inf;
import android.os.Handler;
+import android.os.Looper;
+import com.arialyy.aria.core.TaskRecord;
+import com.arialyy.aria.core.loader.ILoaderComponent;
/**
* 线程任务状态
*/
-public interface IThreadState extends Handler.Callback {
+public interface IThreadState extends ILoaderComponent {
int STATE_STOP = 0x01;
int STATE_FAIL = 0x02;
int STATE_CANCEL = 0x03;
@@ -50,4 +53,14 @@ public interface IThreadState extends Handler.Callback {
* @return 任务当前进度
*/
long getCurrentProgress();
+
+ /**
+ * 设置消息循环体
+ */
+ void setLooper(TaskRecord taskRecord, Looper looper);
+
+ /**
+ * 创建handler 回调
+ */
+ Handler.Callback getHandlerCallback();
}
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/listener/BaseDListener.java b/PublicComponent/src/main/java/com/arialyy/aria/core/listener/BaseDListener.java
index fa9b6a51..1df88fd8 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/listener/BaseDListener.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/listener/BaseDListener.java
@@ -19,7 +19,7 @@ import android.os.Handler;
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.inf.IRecordHandler;
+import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.inf.TaskSchedulerType;
import com.arialyy.aria.core.task.AbsTask;
import com.arialyy.aria.util.CommonUtil;
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/listener/BaseUListener.java b/PublicComponent/src/main/java/com/arialyy/aria/core/listener/BaseUListener.java
index b7ea9108..104003fd 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/listener/BaseUListener.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/listener/BaseUListener.java
@@ -17,7 +17,7 @@ package com.arialyy.aria.core.listener;
import android.os.Handler;
import com.arialyy.aria.core.inf.IEntity;
-import com.arialyy.aria.core.inf.IRecordHandler;
+import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.inf.TaskSchedulerType;
import com.arialyy.aria.core.task.AbsTask;
import com.arialyy.aria.core.upload.UTaskWrapper;
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/listener/DownloadGroupListener.java b/PublicComponent/src/main/java/com/arialyy/aria/core/listener/DownloadGroupListener.java
index 77db34a3..f15167c2 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/listener/DownloadGroupListener.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/listener/DownloadGroupListener.java
@@ -21,7 +21,7 @@ import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.group.GroupSendParams;
import com.arialyy.aria.core.inf.IEntity;
-import com.arialyy.aria.core.inf.IRecordHandler;
+import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.inf.TaskSchedulerType;
import com.arialyy.aria.core.task.AbsTask;
import com.arialyy.aria.core.task.DownloadGroupTask;
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsLoader.java b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsLoader.java
index c74e8c58..28618e32 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsLoader.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsLoader.java
@@ -16,9 +16,7 @@
package com.arialyy.aria.core.loader;
import android.os.Looper;
-import android.util.SparseArray;
import com.arialyy.aria.core.TaskRecord;
-import com.arialyy.aria.core.inf.IRecordHandler;
import com.arialyy.aria.core.inf.IThreadState;
import com.arialyy.aria.core.listener.IEventListener;
import com.arialyy.aria.core.manager.ThreadTaskManager;
@@ -27,20 +25,27 @@ import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Created by AriaL on 2017/7/1.
- * 控制线程任务状态,如:开始,停止,取消,重试
+ * 任务执行器,用于处理任务的开始,停止
+ * 流程:
+ * 1、获取任务记录
+ * 2、创建任务状态管理器,用于管理任务的状态
+ * 3、创建文件信息获取器,获取文件信息,根据文件信息执行任务
+ * 4、创建线程任务执行下载、上传操作
*/
-public abstract class AbsLoader implements Runnable {
+public abstract class AbsLoader implements ILoaderVisitor, ILoader {
protected final String TAG;
protected IEventListener mListener;
protected AbsTaskWrapper mTaskWrapper;
protected File mTempFile;
- private SparseArray mTask = new SparseArray<>();
+ private List mTask = new ArrayList<>();
private ScheduledThreadPoolExecutor mTimer;
/**
@@ -48,20 +53,23 @@ public abstract class AbsLoader implements Runnable {
*/
private long mUpdateInterval = 1000;
protected TaskRecord mRecord;
- private IThreadState mStateManager;
private boolean isCancel = false, isStop = false;
private boolean isRuning = false;
+ private Looper mLooper;
- protected AbsLoader(IEventListener listener, AbsTaskWrapper wrapper) {
+ protected IRecordHandler mRecordHandler;
+ protected IThreadState mStateManager;
+ protected IInfoTask mInfoTask;
+ protected IThreadTaskBuilder mTTBuilder;
+
+ protected AbsLoader(AbsTaskWrapper wrapper, IEventListener listener) {
mListener = listener;
mTaskWrapper = wrapper;
TAG = CommonUtil.getClassName(getClass());
}
- protected abstract IThreadState createStateManager(Looper looper);
-
/**
- * 处理任务
+ * 启动线程任务
*/
protected abstract void handleTask();
@@ -70,11 +78,6 @@ public abstract class AbsLoader implements Runnable {
*/
public abstract long getFileSize();
- /**
- * 获取当前任务位置
- */
- public abstract long getCurrentLocation();
-
public IThreadState getStateManager() {
return mStateManager;
}
@@ -83,7 +86,7 @@ public abstract class AbsLoader implements Runnable {
return mTaskWrapper.getKey();
}
- public SparseArray getTaskList() {
+ public List getTaskList() {
return mTask;
}
@@ -94,16 +97,20 @@ public abstract class AbsLoader implements Runnable {
closeTimer();
if (mTask != null && mTask.size() != 0) {
for (int i = 0; i < mTask.size(); i++) {
- mTask.valueAt(i).breakTask();
+ mTask.get(i).breakTask();
}
mTask.clear();
}
}
- /**
- * 任务记录工具
- */
- protected abstract IRecordHandler getRecordHandler(AbsTaskWrapper wrapper);
+ @Override public void run() {
+ checkComponent();
+ if (isRunning()) {
+ ALog.d(TAG, String.format("任务【%s】正在执行,启动任务失败", mTaskWrapper.getKey()));
+ return;
+ }
+ startFlow();
+ }
/**
* 开始流程
@@ -114,21 +121,18 @@ public abstract class AbsLoader implements Runnable {
}
isRuning = true;
resetState();
- mRecord = getRecordHandler(mTaskWrapper).getRecord();
- Looper.prepare();
- Looper looper = Looper.myLooper();
- mStateManager = createStateManager(looper);
onPostPre();
handleTask();
startTimer();
Looper.loop();
}
- @Override public void run() {
- if (isRunning()) {
- return;
+ @Override public Looper getLooper() {
+ if (mLooper == null) {
+ Looper.prepare();
+ mLooper = Looper.myLooper();
}
- startFlow();
+ return mLooper;
}
/**
@@ -212,7 +216,7 @@ public abstract class AbsLoader implements Runnable {
isCancel = true;
onCancel();
for (int i = 0; i < mTask.size(); i++) {
- IThreadTask task = mTask.valueAt(i);
+ IThreadTask task = mTask.get(i);
if (task != null && !task.isThreadComplete()) {
task.cancel();
}
@@ -245,7 +249,7 @@ public abstract class AbsLoader implements Runnable {
isStop = true;
onStop();
for (int i = 0; i < mTask.size(); i++) {
- IThreadTask task = mTask.valueAt(i);
+ IThreadTask task = mTask.get(i);
if (task != null && !task.isThreadComplete()) {
task.stop();
}
@@ -253,7 +257,7 @@ public abstract class AbsLoader implements Runnable {
ThreadTaskManager.getInstance().removeTaskThread(mTaskWrapper.getKey());
onPostStop();
onDestroy();
- mListener.onStop(getCurrentLocation());
+ mListener.onStop(getCurrentProgress());
}
/**
@@ -270,17 +274,6 @@ public abstract class AbsLoader implements Runnable {
}
- /**
- * 直接调用的时候会自动启动线程执行
- */
- public synchronized void start() {
- if (isRunning()) {
- ALog.d(TAG, String.format("任务【%s】正在执行,启动任务失败", mTaskWrapper.getKey()));
- return;
- }
- new Thread(this).start();
- }
-
/**
* 重试任务
*/
@@ -303,4 +296,22 @@ public abstract class AbsLoader implements Runnable {
}
return false;
}
+
+ /**
+ * 检查组件: {@link #mRecordHandler}、{@link #mInfoTask}、{@link #mStateManager}、{@link #mTTBuilder}
+ */
+ private void checkComponent() {
+ if (mRecordHandler == null) {
+ throw new NullPointerException("任务记录组件为空");
+ }
+ if (mInfoTask == null) {
+ throw new NullPointerException(("文件信息组件为空"));
+ }
+ if (mStateManager == null) {
+ throw new NullPointerException("任务状态管理组件为空");
+ }
+ if (mTTBuilder == null) {
+ throw new NullPointerException("线程任务组件为空");
+ }
+ }
}
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsNormalLoaderUtil.java b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsNormalLoaderUtil.java
index 1ca1ec5b..e31b0c81 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsNormalLoaderUtil.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsNormalLoaderUtil.java
@@ -29,19 +29,25 @@ import com.arialyy.aria.util.CommonUtil;
public abstract class AbsNormalLoaderUtil implements IUtil {
protected String TAG = CommonUtil.getClassName(getClass());
private IEventListener mListener;
- private AbsLoader mLoader;
+ protected AbsLoader mLoader;
private AbsTaskWrapper mTaskWrapper;
private boolean isStop = false, isCancel = false;
protected AbsNormalLoaderUtil(AbsTaskWrapper wrapper, IEventListener listener) {
mTaskWrapper = wrapper;
mListener = listener;
- mLoader = createLoader();
+ mLoader = getLoader();
}
- public AbsLoader getLoader() {
- return mLoader;
- }
+ /**
+ * 获取加载器
+ */
+ public abstract AbsLoader getLoader();
+
+ /**
+ * 获取构造器
+ */
+ public abstract LoaderStructure getLoaderStructure();
@Override public String getKey() {
return mTaskWrapper.getKey();
@@ -55,7 +61,7 @@ public abstract class AbsNormalLoaderUtil implements IUtil {
* 获取当前下载位置
*/
@Override public long getCurrentLocation() {
- return mLoader.getCurrentLocation();
+ return mLoader.getCurrentProgress();
}
@Override public boolean isRunning() {
@@ -105,10 +111,10 @@ public abstract class AbsNormalLoaderUtil implements IUtil {
//} else {
// mDownloader.create();
//}
- Runnable runnable = createInfoThread();
- if (runnable != null) {
- new Thread(runnable).start();
- }
+
+ getLoaderStructure();
+ new Thread(mLoader).start();
+
onStart();
}
@@ -139,14 +145,4 @@ public abstract class AbsNormalLoaderUtil implements IUtil {
public AbsTaskWrapper getTaskWrapper() {
return mTaskWrapper;
}
-
- /**
- * 创建加载器的适配器
- */
- protected abstract AbsLoader createLoader();
-
- /**
- * 通过链接类型创建不同的获取文件信息的线程
- */
- protected abstract Runnable createInfoThread();
}
\ No newline at end of file
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsNormalTTBuilder.java b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsNormalTTBuilder.java
new file mode 100644
index 00000000..a483ecd3
--- /dev/null
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsNormalTTBuilder.java
@@ -0,0 +1,185 @@
+package com.arialyy.aria.core.loader;
+
+import android.os.Handler;
+import android.os.Looper;
+import com.arialyy.aria.core.TaskRecord;
+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.IThreadState;
+import com.arialyy.aria.core.task.IThreadTask;
+import com.arialyy.aria.core.task.IThreadTaskAdapter;
+import com.arialyy.aria.core.task.ThreadTask;
+import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
+import com.arialyy.aria.util.ALog;
+import com.arialyy.aria.util.CommonUtil;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class AbsNormalTTBuilder implements IThreadTaskBuilder {
+ protected String TAG = CommonUtil.getClassName(this);
+
+ private Handler mStateHandler;
+ private AbsTaskWrapper mWrapper;
+ private TaskRecord mRecord;
+ private int mTotalThreadNum;
+ private File mTempFile;
+ private int mStartThreadNum;
+
+ public AbsNormalTTBuilder(AbsTaskWrapper wrapper) {
+ if (wrapper instanceof DGTaskWrapper) {
+ throw new AssertionError("NormalTTBuilder 不适用于组合任务");
+ }
+ mWrapper = wrapper;
+ mTempFile = new File(((AbsNormalEntity) wrapper.getEntity()).getFilePath());
+ }
+
+ protected File getTempFile(){
+ return mTempFile;
+ }
+
+ protected AbsNormalEntity getEntity() {
+ return (AbsNormalEntity) mWrapper.getEntity();
+ }
+
+ /**
+ * 创建线程任务适配器
+ */
+ public abstract IThreadTaskAdapter getAdapter(SubThreadConfig config);
+
+ /**
+ * 处理新任务
+ *
+ * @param record 任务记录
+ * @param totalThreadNum 任务的线程总数
+ * @return {@code true}创建新任务成功
+ */
+ public abstract boolean handleNewTask(TaskRecord record, int totalThreadNum);
+
+ /**
+ * 创建线程任务
+ */
+ private IThreadTask createThreadTask(SubThreadConfig config) {
+ ThreadTask task = new ThreadTask(config);
+ task.setAdapter(getAdapter(config));
+ return task;
+ }
+
+ /**
+ * 启动断点任务时,创建单线程任务
+ *
+ * @param record 线程记录
+ * @param startNum 启动的线程数
+ */
+ private IThreadTask createSingThreadTask(ThreadRecord record, int startNum) {
+ SubThreadConfig config = new SubThreadConfig();
+ config.url = getEntity().isRedirect() ? getEntity().getRedirectUrl() : getEntity().getUrl();
+ config.tempFile =
+ mRecord.isBlock ? new File(
+ String.format(IRecordHandler.SUB_PATH, mTempFile.getPath(), record.threadId))
+ : mTempFile;
+ config.isBlock = mRecord.isBlock;
+ config.startThreadNum = startNum;
+ config.taskWrapper = mWrapper;
+ config.record = record;
+ config.stateHandler = mStateHandler;
+ return createThreadTask(config);
+ }
+
+ /**
+ * 处理不支持断点的任务
+ */
+ private List handleNoSupportBP() {
+ List list = new ArrayList<>();
+ mStartThreadNum = 1;
+
+ IThreadTask task = createSingThreadTask(mRecord.threadRecords.get(0), 1);
+ if (task == null) {
+ ALog.e(TAG, "创建线程任务失败");
+ return null;
+ }
+ list.add(task);
+ return list;
+ }
+
+ /**
+ * 处理支持断点的任务
+ */
+ private List handleBreakpoint() {
+ long fileLength = getEntity().getFileSize();
+ long blockSize = fileLength / mTotalThreadNum;
+ long currentProgress = 0;
+ List threadTasks = new ArrayList<>();
+
+ mRecord.fileLength = fileLength;
+ if (mWrapper.isNewTask() && !handleNewTask(mRecord, mTotalThreadNum)) {
+ ALog.e(TAG, "初始化线程任务失败");
+ return null;
+ }
+
+ for (ThreadRecord tr : mRecord.threadRecords) {
+ if (!tr.isComplete) {
+ mStartThreadNum++;
+ }
+ }
+
+ for (int i = 0; i < mTotalThreadNum; i++) {
+ long startL = i * blockSize, endL = (i + 1) * blockSize;
+ ThreadRecord tr = mRecord.threadRecords.get(i);
+
+ if (tr.isComplete) {//该线程已经完成
+ currentProgress += endL - startL;
+ ALog.d(TAG, String.format("任务【%s】线程__%s__已完成", mWrapper.getKey(), i));
+ mStateHandler.obtainMessage(IThreadState.STATE_COMPLETE).sendToTarget();
+ continue;
+ }
+
+ //如果有记录,则恢复任务
+ long r = tr.startLocation;
+ //记录的位置需要在线程区间中
+ if (startL < r && r <= (i == (mTotalThreadNum - 1) ? fileLength : endL)) {
+ currentProgress += r - startL;
+ }
+ ALog.d(TAG, String.format("任务【%s】线程__%s__恢复任务", getEntity().getFileName(), i));
+
+ IThreadTask task = createSingThreadTask(tr, mStartThreadNum);
+ if (task == null) {
+ ALog.e(TAG, "创建线程任务失败");
+ return null;
+ }
+ threadTasks.add(task);
+ }
+ if (currentProgress != 0 && currentProgress != getEntity().getCurrentProgress()) {
+ ALog.d(TAG, String.format("进度修正,当前进度:%s", currentProgress));
+ getEntity().setCurrentProgress(currentProgress);
+ }
+ //mStateManager.updateProgress(currentProgress);
+ return threadTasks;
+ }
+
+ private List handleTask() {
+ if (mWrapper.isSupportBP()) {
+ return handleBreakpoint();
+ }else {
+ return handleNoSupportBP();
+ }
+ }
+
+ @Override public List buildThreadTask(TaskRecord record, Looper looper,
+ IThreadState stateManager) {
+ mRecord = record;
+ mStateHandler = new Handler(looper, stateManager.getHandlerCallback());
+ mTotalThreadNum = mRecord.threadNum;
+ return handleTask();
+ }
+
+ @Override public int getCreatedThreadNum() {
+ return mStartThreadNum;
+ }
+
+ @Override public void accept(ILoaderVisitor visitor) {
+ visitor.addComponent(this);
+ }
+}
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/inf/OnFileInfoCallback.java b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/IInfoTask.java
similarity index 60%
rename from PublicComponent/src/main/java/com/arialyy/aria/core/inf/OnFileInfoCallback.java
rename to PublicComponent/src/main/java/com/arialyy/aria/core/loader/IInfoTask.java
index 71eccce9..0e90fb97 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/inf/OnFileInfoCallback.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/IInfoTask.java
@@ -13,24 +13,40 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.arialyy.aria.core.inf;
+package com.arialyy.aria.core.loader;
-import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.common.AbsEntity;
+import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.exception.BaseException;
-public interface OnFileInfoCallback {
+/**
+ * 任务信息采集
+ */
+public interface IInfoTask extends ILoaderComponent {
+
/**
- * 处理完成
- *
- * @param info 一些回调的信息
+ * 执行任务
*/
- void onComplete(String key, CompleteInfo info);
+ void run();
/**
- * 请求失败
- *
- * @param e 错误信息
+ * 设置回调
*/
- void onFail(AbsEntity entity, BaseException e, boolean needRetry);
-}
\ No newline at end of file
+ void setCallback(Callback callback);
+
+ interface Callback {
+ /**
+ * 处理完成
+ *
+ * @param info 一些回调的信息
+ */
+ void onSucceed(String key, CompleteInfo info);
+
+ /**
+ * 请求失败
+ *
+ * @param e 错误信息
+ */
+ void onFail(AbsEntity entity, BaseException e, boolean needRetry);
+ }
+}
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/ILoader.java b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/ILoader.java
index d6bfda0f..356cdc08 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/ILoader.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/ILoader.java
@@ -15,15 +15,24 @@
*/
package com.arialyy.aria.core.loader;
-public interface ILoader {
+import android.os.Looper;
- void start();
+public interface ILoader extends Runnable{
+
+ //void start();
void stop();
- void isBreak();
+ /**
+ * 任务是否被中断(停止,取消)
+ *
+ * @return true 任务中断,false 任务没有中断
+ */
+ boolean isBreak();
String getKey();
long getCurrentProgress();
+
+ Looper getLooper();
}
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/ILoaderAdapter.java b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/ILoaderAdapter.java
index bc865e0e..4408dbd8 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/ILoaderAdapter.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/ILoaderAdapter.java
@@ -16,7 +16,6 @@
package com.arialyy.aria.core.loader;
import com.arialyy.aria.core.TaskRecord;
-import com.arialyy.aria.core.inf.IRecordHandler;
import com.arialyy.aria.core.task.IThreadTask;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.common.SubThreadConfig;
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/LoaderIntercept.java b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/ILoaderComponent.java
similarity index 63%
rename from PublicComponent/src/main/java/com/arialyy/aria/core/loader/LoaderIntercept.java
rename to PublicComponent/src/main/java/com/arialyy/aria/core/loader/ILoaderComponent.java
index dc8582e4..465d4dab 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/LoaderIntercept.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/ILoaderComponent.java
@@ -15,33 +15,11 @@
*/
package com.arialyy.aria.core.loader;
-public class LoaderIntercept implements ILoaderInterceptor, ILoader {
-
-
-
- @Override public ILoader intercept(Chain chain) {
-
-
- return this;
- }
-
- @Override public void start() {
-
- }
-
- @Override public void stop() {
-
- }
-
- @Override public void isBreak() {
-
- }
+/**
+ * 加载器部件
+ */
+public interface ILoaderComponent {
- @Override public String getKey() {
- return null;
- }
+ void accept(ILoaderVisitor visitor);
- @Override public long getCurrentProgress() {
- return 0;
- }
}
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/ILoaderInterceptor.java b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/ILoaderVisitor.java
similarity index 60%
rename from PublicComponent/src/main/java/com/arialyy/aria/core/loader/ILoaderInterceptor.java
rename to PublicComponent/src/main/java/com/arialyy/aria/core/loader/ILoaderVisitor.java
index a6a4adfc..e4d0b84c 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/ILoaderInterceptor.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/ILoaderVisitor.java
@@ -15,27 +15,30 @@
*/
package com.arialyy.aria.core.loader;
-import com.arialyy.aria.core.TaskRecord;
-import com.arialyy.aria.core.listener.IEventListener;
-import com.arialyy.aria.core.wrapper.ITaskWrapper;
+import com.arialyy.aria.core.inf.IThreadState;
/**
- * 拦截器
+ * 加载器访问者
*/
-public interface ILoaderInterceptor {
-
- ILoader intercept(Chain chain);
-
- interface Chain {
-
- void updateRecord(TaskRecord record);
-
- TaskRecord getRecord();
-
- IEventListener getListener();
-
- ITaskWrapper getWrapper();
-
- ILoader proceed();
- }
+public interface ILoaderVisitor {
+
+ /**
+ * 处理任务记录
+ */
+ void addComponent(IRecordHandler recordHandler);
+
+ /**
+ * 处理任务的文件信息
+ */
+ void addComponent(IInfoTask infoTask);
+
+ /**
+ * 线程状态
+ */
+ void addComponent(IThreadState threadState);
+
+ /**
+ * 构造线程任务
+ */
+ void addComponent(IThreadTaskBuilder builder);
}
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/inf/IRecordHandlerAdapter.java b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/IRecordHandler.java
similarity index 69%
rename from PublicComponent/src/main/java/com/arialyy/aria/core/inf/IRecordHandlerAdapter.java
rename to PublicComponent/src/main/java/com/arialyy/aria/core/loader/IRecordHandler.java
index e2a2992b..b27b7249 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/inf/IRecordHandlerAdapter.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/IRecordHandler.java
@@ -13,18 +13,38 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.arialyy.aria.core.inf;
+package com.arialyy.aria.core.loader;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.ThreadRecord;
/**
- * 任务记录处理适配器
- *
* @Author lyy
- * @Date 2019-09-19
+ * @Date 2019-09-18
*/
-public interface IRecordHandlerAdapter {
+public interface IRecordHandler extends ILoaderComponent {
+
+ int TYPE_DOWNLOAD = 1;
+ int TYPE_UPLOAD = 2;
+ int TYPE_M3U8_VOD = 3;
+ int TYPE_M3U8_LIVE = 4;
+
+ String STATE = "_state_";
+ String RECORD = "_record_";
+ /**
+ * 小于1m的文件不启用多线程
+ */
+ long SUB_LEN = 1024 * 1024;
+
+ /**
+ * 分块文件路径
+ */
+ String SUB_PATH = "%s.%s.part";
+
+ /**
+ * 获取任务记录
+ */
+ TaskRecord getRecord();
/**
* 记录处理前的操作,可用来删除任务记录
@@ -57,4 +77,11 @@ public interface IRecordHandlerAdapter {
* @return 新任务的线程数
*/
int initTaskThreadNum();
+
+ /**
+ * 检查任务是否已完成
+ *
+ * @return true 任务已完成
+ */
+ boolean checkTaskCompleted();
}
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/inf/IRecordHandler.java b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/IThreadTaskBuilder.java
similarity index 55%
rename from PublicComponent/src/main/java/com/arialyy/aria/core/inf/IRecordHandler.java
rename to PublicComponent/src/main/java/com/arialyy/aria/core/loader/IThreadTaskBuilder.java
index 17e75de3..bb2a8aa6 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/inf/IRecordHandler.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/IThreadTaskBuilder.java
@@ -13,35 +13,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.arialyy.aria.core.inf;
+package com.arialyy.aria.core.loader;
+import android.os.Looper;
import com.arialyy.aria.core.TaskRecord;
+import com.arialyy.aria.core.inf.IThreadState;
+import com.arialyy.aria.core.task.IThreadTask;
+import java.util.List;
/**
- * @Author lyy
- * @Date 2019-09-18
+ * 线程任务构造器
*/
-public interface IRecordHandler {
-
- int TYPE_DOWNLOAD = 1;
- int TYPE_UPLOAD = 2;
- int TYPE_M3U8_VOD = 3;
- int TYPE_M3U8_LIVE = 4;
-
- String STATE = "_state_";
- String RECORD = "_record_";
- /**
- * 小于1m的文件不启用多线程
- */
- long SUB_LEN = 1024 * 1024;
+public interface IThreadTaskBuilder extends ILoaderComponent {
/**
- * 分块文件路径
+ * 构造线程任务
*/
- String SUB_PATH = "%s.%s.part";
+ List buildThreadTask(TaskRecord record, Looper looper, IThreadState stateManager);
/**
- * 获取任务记录
+ * 获取创建的线程任务数,需要先调用{@link #buildThreadTask(TaskRecord, Looper, IThreadState)}方法才能获取创建的线程任务数
*/
- TaskRecord getRecord();
+ int getCreatedThreadNum();
}
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/LoaderChain.java b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/LoaderChain.java
deleted file mode 100644
index 5956e73e..00000000
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/LoaderChain.java
+++ /dev/null
@@ -1,75 +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.loader;
-
-import com.arialyy.aria.core.TaskRecord;
-import com.arialyy.aria.core.listener.IEventListener;
-import com.arialyy.aria.core.wrapper.ITaskWrapper;
-import java.util.List;
-
-/**
- * 责任链
- */
-public final class LoaderChain implements ILoaderInterceptor.Chain {
- private ITaskWrapper wrapper;
- private IEventListener listener;
- private TaskRecord taskRecord;
- private int index;
- private List interceptors;
-
- public LoaderChain(List interceptors, ITaskWrapper wrapper,
- IEventListener listener, TaskRecord taskRecord,
- int index) {
- this.interceptors = interceptors;
- this.wrapper = wrapper;
- this.listener = listener;
- this.taskRecord = taskRecord;
- this.index = index;
- }
-
- @Override public void updateRecord(TaskRecord record) {
- this.taskRecord = record;
- }
-
- @Override public TaskRecord getRecord() {
- return taskRecord;
- }
-
- @Override public IEventListener getListener() {
- return listener;
- }
-
- @Override public ITaskWrapper getWrapper() {
- return wrapper;
- }
-
- @Override public ILoader proceed() {
- int index = this.index + 1;
- if (index >= interceptors.size()) {
- throw new AssertionError();
- }
-
- LoaderChain next = new LoaderChain(interceptors, wrapper, listener, taskRecord, index);
- ILoaderInterceptor interceptor = interceptors.get(index);
- ILoader loader = interceptor.intercept(next);
-
- if (loader == null) {
- throw new NullPointerException("Loader为空");
- }
-
- return loader;
- }
-}
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/RecordInterceptor.java b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/LoaderStructure.java
similarity index 50%
rename from PublicComponent/src/main/java/com/arialyy/aria/core/loader/RecordInterceptor.java
rename to PublicComponent/src/main/java/com/arialyy/aria/core/loader/LoaderStructure.java
index 98c0f0bd..5454f294 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/RecordInterceptor.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/LoaderStructure.java
@@ -15,25 +15,31 @@
*/
package com.arialyy.aria.core.loader;
-import com.arialyy.aria.core.common.RecordHandler;
-import com.arialyy.aria.core.inf.IRecordHandlerAdapter;
-import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
+import com.arialyy.aria.core.inf.IThreadState;
+import java.util.ArrayList;
+import java.util.List;
-/**
- * 任务记录拦截器,用于处理任务记录
- */
-public final class RecordInterceptor implements ILoaderInterceptor {
- private IRecordHandlerAdapter adapter;
+public class LoaderStructure {
+ private List parts = new ArrayList<>();
- public RecordInterceptor(IRecordHandlerAdapter adapter) {
- this.adapter = adapter;
- }
+ public void accept(ILoaderVisitor visitor) {
- @Override public ILoader intercept(Chain chain) {
- RecordHandler recordHandler = new RecordHandler((AbsTaskWrapper) chain.getWrapper());
- recordHandler.setAdapter(adapter);
- chain.updateRecord(recordHandler.getRecord());
+ for (ILoaderComponent part : parts) {
+ part.accept(visitor);
+ }
+ }
- return chain.proceed();
+ /**
+ * 将组件加入到集合,必须添加以下集合:
+ * 1 {@link IRecordHandler}
+ * 2 {@link IInfoTask}
+ * 3 {@link IThreadState}
+ * 4 {@link IThreadTaskBuilder}
+ *
+ * @param component 待添加的组件
+ */
+ public LoaderStructure addComponent(ILoaderComponent component) {
+ parts.add(component);
+ return this;
}
}
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/NormalLoader.java b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/NormalLoader.java
index 6b113f2e..50755733 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/NormalLoader.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/NormalLoader.java
@@ -15,20 +15,17 @@
*/
package com.arialyy.aria.core.loader;
-import android.os.Handler;
-import android.os.Looper;
-import com.arialyy.aria.core.ThreadRecord;
+import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.common.AbsNormalEntity;
-import com.arialyy.aria.core.common.SubThreadConfig;
+import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.event.EventMsgUtil;
-import com.arialyy.aria.core.inf.IRecordHandler;
import com.arialyy.aria.core.inf.IThreadState;
-import com.arialyy.aria.core.listener.BaseDListener;
import com.arialyy.aria.core.listener.IDLoadListener;
import com.arialyy.aria.core.listener.IEventListener;
import com.arialyy.aria.core.manager.ThreadTaskManager;
import com.arialyy.aria.core.task.IThreadTask;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
+import com.arialyy.aria.exception.BaseException;
import com.arialyy.aria.util.ALog;
import java.io.File;
@@ -36,23 +33,15 @@ import java.io.File;
* 单文件
*/
public class NormalLoader extends AbsLoader {
- private ThreadStateManager mStateManager;
- private Handler mStateHandler;
- protected int mTotalThreadNum; //总线程数
private int mStartThreadNum; //启动的线程数
- private ILoaderAdapter mAdapter;
- public NormalLoader(IEventListener listener, AbsTaskWrapper wrapper) {
- super(listener, wrapper);
+ public NormalLoader(AbsTaskWrapper wrapper, IEventListener listener) {
+ super(wrapper, listener);
mTempFile = new File(getEntity().getFilePath());
EventMsgUtil.getDefault().register(this);
setUpdateInterval(wrapper.getConfig().getUpdateInterval());
}
- public void setAdapter(ILoaderAdapter adapter) {
- mAdapter = adapter;
- }
-
public AbsNormalEntity getEntity() {
return (AbsNormalEntity) mTaskWrapper.getEntity();
}
@@ -61,24 +50,15 @@ public class NormalLoader extends AbsLoader {
return getEntity().getFileSize();
}
- @Override public long getCurrentLocation() {
- return isRunning() ? mStateManager.getCurrentProgress() : getEntity().getCurrentProgress();
- }
-
- @Override protected IRecordHandler getRecordHandler(AbsTaskWrapper wrapper) {
- return mAdapter.recordHandler(wrapper);
- }
-
/**
- * 设置最大下载/上传速度
+ * 设置最大下载/上传速度AbsFtpInfoThread
*
* @param maxSpeed 单位为:kb
*/
protected void setMaxSpeed(int maxSpeed) {
- for (int i = 0; i < getTaskList().size(); i++) {
- IThreadTask task = getTaskList().valueAt(i);
- if (task != null && mStartThreadNum > 0) {
- task.setMaxSpeed(maxSpeed / mStartThreadNum);
+ for (IThreadTask threadTask : getTaskList()) {
+ if (threadTask != null && mStartThreadNum > 0) {
+ threadTask.setMaxSpeed(maxSpeed / mStartThreadNum);
}
}
}
@@ -90,11 +70,6 @@ public class NormalLoader extends AbsLoader {
@Override protected void onPostPre() {
super.onPostPre();
- if (mAdapter == null) {
- throw new NullPointerException("请使用adapter设置适配器");
- }
- mTotalThreadNum = mRecord.threadNum;
-
if (mListener instanceof IDLoadListener) {
((IDLoadListener) mListener).onPostPre(getEntity().getFileSize());
}
@@ -114,126 +89,63 @@ public class NormalLoader extends AbsLoader {
}
}
- @Override protected IThreadState createStateManager(Looper looper) {
- mStateManager = new ThreadStateManager(looper, mRecord, mListener);
- mStateHandler = new Handler(looper, mStateManager);
- return mStateManager;
- }
-
- @Override protected void handleTask() {
- if (mTaskWrapper.isSupportBP()) {
- handleBreakpoint();
- } else {
- handleNoSupportBP();
- }
- }
-
/**
- * 启动断点任务时,创建单线程任务
- *
- * @param record 线程记录
- * @param startNum 启动的线程数
+ * 启动单线程任务
*/
- private IThreadTask createSingThreadTask(ThreadRecord record, int startNum) {
- SubThreadConfig config = new SubThreadConfig();
- config.url = getEntity().isRedirect() ? getEntity().getRedirectUrl() : getEntity().getUrl();
- config.tempFile =
- mRecord.isBlock ? new File(
- String.format(IRecordHandler.SUB_PATH, mTempFile.getPath(), record.threadId))
- : mTempFile;
- config.isBlock = mRecord.isBlock;
- config.startThreadNum = startNum;
- config.taskWrapper = mTaskWrapper;
- config.record = record;
- config.stateHandler = mStateHandler;
- return mAdapter.createThreadTask(config);
- }
-
- private void handleBreakpoint() {
- long fileLength = getEntity().getFileSize();
- long blockSize = fileLength / mTotalThreadNum;
- long currentProgress = 0;
-
- mRecord.fileLength = fileLength;
- if (mTaskWrapper.isNewTask() && !mAdapter.handleNewTask(mRecord, mTotalThreadNum)) {
- closeTimer();
- mListener.onFail(false, null);
+ @Override
+ public void handleTask() {
+ if (isBreak()) {
return;
}
-
- for (ThreadRecord tr : mRecord.threadRecords) {
- if (!tr.isComplete) {
- mStartThreadNum++;
- }
- }
-
- for (int i = 0; i < mTotalThreadNum; i++) {
- long startL = i * blockSize, endL = (i + 1) * blockSize;
- ThreadRecord tr = mRecord.threadRecords.get(i);
-
- if (tr.isComplete) {//该线程已经完成
- currentProgress += endL - startL;
- ALog.d(TAG, String.format("任务【%s】线程__%s__已完成", mTaskWrapper.getKey(), i));
- mStateHandler.obtainMessage(IThreadState.STATE_COMPLETE).sendToTarget();
- if (mStateManager.isComplete()) {
- mRecord.deleteData();
- mListener.onComplete();
- return;
- }
- continue;
- }
-
- //如果有记录,则恢复任务
- long r = tr.startLocation;
- //记录的位置需要在线程区间中
- if (startL < r && r <= (i == (mTotalThreadNum - 1) ? fileLength : endL)) {
- currentProgress += r - startL;
- }
- ALog.d(TAG, String.format("任务【%s】线程__%s__恢复任务", getEntity().getFileName(), i));
-
- IThreadTask task = createSingThreadTask(tr, mStartThreadNum);
- if (task == null) return;
- getTaskList().put(tr.threadId, task);
- }
- if (currentProgress != 0 && currentProgress != getEntity().getCurrentProgress()) {
- ALog.d(TAG, String.format("进度修正,当前进度:%s", currentProgress));
- getEntity().setCurrentProgress(currentProgress);
- }
- mStateManager.updateProgress(currentProgress);
- startThreadTask();
+ mStateManager.setLooper(mRecord, getLooper());
+ mInfoTask.run();
}
- /**
- * 启动单线程任务
- */
private void startThreadTask() {
- if (isBreak()) {
- return;
- }
+ getTaskList().addAll(mTTBuilder.buildThreadTask(mRecord, getLooper(), mStateManager));
+ mStartThreadNum = mTTBuilder.getCreatedThreadNum();
if (mStateManager.getCurrentProgress() > 0) {
mListener.onResume(mStateManager.getCurrentProgress());
} else {
mListener.onStart(mStateManager.getCurrentProgress());
}
- for (int i = 0; i < getTaskList().size(); i++) {
- ThreadTaskManager.getInstance().startThread(mTaskWrapper.getKey(), getTaskList().valueAt(i));
+ for (IThreadTask threadTask : getTaskList()) {
+ ThreadTaskManager.getInstance().startThread(mTaskWrapper.getKey(), threadTask);
}
}
- /**
- * 处理不支持断点的任务
- */
- private void handleNoSupportBP() {
- if (mListener instanceof BaseDListener) {
- ((BaseDListener) mListener).supportBreakpoint(false);
+ @Override public long getCurrentProgress() {
+ return isRunning() ? mStateManager.getCurrentProgress() : getEntity().getCurrentProgress();
+ }
+
+ @Override public void addComponent(IRecordHandler recordHandler) {
+ mRecordHandler = recordHandler;
+ mRecord = mRecordHandler.getRecord();
+ if (recordHandler.checkTaskCompleted()) {
+ mRecord.deleteData();
+ mListener.onComplete();
}
- mStartThreadNum = 1;
+ }
+
+ @Override public void addComponent(IInfoTask infoTask) {
+ mInfoTask = infoTask;
+ infoTask.setCallback(new IInfoTask.Callback() {
+ @Override public void onSucceed(String key, CompleteInfo info) {
+ startThreadTask();
+ }
+
+ @Override public void onFail(AbsEntity entity, BaseException e, boolean needRetry) {
+ mListener.onFail(needRetry, e);
+ }
+ });
+ }
+
+ @Override public void addComponent(IThreadState threadState) {
+ mStateManager = threadState;
+ }
- IThreadTask task = createSingThreadTask(mRecord.threadRecords.get(0), 1);
- if (task == null) return;
- getTaskList().put(0, task);
- ThreadTaskManager.getInstance().startThread(mTaskWrapper.getKey(), task);
- mListener.onStart(0);
+ @Override public void addComponent(IThreadTaskBuilder builder) {
+ mTTBuilder = builder;
}
}
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/ThreadStateManager.java b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/ThreadStateManager.java
index c3fd33d8..e8bcf1b5 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/loader/ThreadStateManager.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/loader/ThreadStateManager.java
@@ -16,10 +16,10 @@
package com.arialyy.aria.core.loader;
import android.os.Bundle;
+import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import com.arialyy.aria.core.TaskRecord;
-import com.arialyy.aria.core.inf.IRecordHandler;
import com.arialyy.aria.core.inf.IThreadState;
import com.arialyy.aria.core.listener.IEventListener;
import com.arialyy.aria.exception.BaseException;
@@ -49,76 +49,90 @@ public class ThreadStateManager implements IThreadState {
private Looper mLooper;
/**
- * @param taskRecord 任务记录
* @param listener 任务事件
*/
- ThreadStateManager(Looper looper, TaskRecord taskRecord, IEventListener listener) {
- mLooper = looper;
+ public ThreadStateManager(IEventListener listener) {
+ mListener = listener;
+ }
+
+ @Override public void setLooper(TaskRecord taskRecord, Looper looper) {
mTaskRecord = taskRecord;
mThreadNum = mTaskRecord.threadNum;
- mListener = listener;
+ mLooper = looper;
}
- /**
- * 不要使用handle更新启动线程的进度,因为有延迟
- */
- void updateProgress(long curProgress) {
- mProgress = curProgress;
+ private void checkLooper(){
+ if (mTaskRecord == null){
+ throw new NullPointerException("任务记录为空");
+ }
+ if (mLooper == null){
+ throw new NullPointerException("Looper为空");
+ }
}
- @Override public boolean handleMessage(Message msg) {
- switch (msg.what) {
- case STATE_STOP:
- mStopNum++;
- if (isStop()) {
- quitLooper();
- }
- break;
- case STATE_CANCEL:
- mCancelNum++;
- if (isCancel()) {
- quitLooper();
- }
- break;
- case STATE_FAIL:
- mFailNum++;
- if (isFail()) {
- Bundle b = msg.getData();
- mListener.onFail(b.getBoolean(KEY_RETRY, false),
- (BaseException) b.getSerializable(KEY_ERROR_INFO));
- quitLooper();
- }
- break;
- case STATE_COMPLETE:
- mCompleteNum++;
- if (isComplete()) {
- ALog.d(TAG, "isComplete, completeNum = " + mCompleteNum);
- if (mTaskRecord.isBlock) {
- if (mergeFile()) {
- mListener.onComplete();
+ private Handler.Callback callback = new Handler.Callback() {
+ @Override public boolean handleMessage(Message msg) {
+ checkLooper();
+ switch (msg.what) {
+ case STATE_STOP:
+ mStopNum++;
+ if (isStop()) {
+ quitLooper();
+ }
+ break;
+ case STATE_CANCEL:
+ mCancelNum++;
+ if (isCancel()) {
+ quitLooper();
+ }
+ break;
+ case STATE_FAIL:
+ mFailNum++;
+ if (isFail()) {
+ Bundle b = msg.getData();
+ mListener.onFail(b.getBoolean(KEY_RETRY, false),
+ (BaseException) b.getSerializable(KEY_ERROR_INFO));
+ quitLooper();
+ }
+ break;
+ case STATE_COMPLETE:
+ mCompleteNum++;
+ if (isComplete()) {
+ ALog.d(TAG, "isComplete, completeNum = " + mCompleteNum);
+ if (mTaskRecord.isBlock) {
+ if (mergeFile()) {
+ mListener.onComplete();
+ } else {
+ mListener.onFail(false, null);
+ }
} else {
- mListener.onFail(false, null);
+ mListener.onComplete();
}
- } else {
- mListener.onComplete();
+ quitLooper();
}
- quitLooper();
- }
- break;
- case STATE_RUNNING:
- if (msg.obj instanceof Long) {
- mProgress += (long) msg.obj;
- }
- break;
- case STATE_UPDATE_PROGRESS:
- if (msg.obj == null) {
- mProgress = updateBlockProgress();
- } else if (msg.obj instanceof Long) {
- mProgress = (long) msg.obj;
- }
- break;
+ break;
+ case STATE_RUNNING:
+ if (msg.obj instanceof Long) {
+ mProgress += (long) msg.obj;
+ }
+ break;
+ case STATE_UPDATE_PROGRESS:
+ if (msg.obj == null) {
+ mProgress = updateBlockProgress();
+ } else if (msg.obj instanceof Long) {
+ mProgress = (long) msg.obj;
+ }
+ break;
+ }
+ return false;
}
- return false;
+ };
+
+ /**
+ * 不要使用handle更新启动线程的进度,因为有延迟
+ */
+ void updateProgress(long curProgress) {
+ mProgress = curProgress;
}
/**
@@ -138,6 +152,10 @@ public class ThreadStateManager implements IThreadState {
return mProgress;
}
+ @Override public Handler.Callback getHandlerCallback() {
+ return callback;
+ }
+
/**
* 所有子线程是否都已经停止
*/
@@ -226,4 +244,8 @@ public class ThreadStateManager implements IThreadState {
return false;
}
}
+
+ @Override public void accept(ILoaderVisitor visitor) {
+ visitor.addComponent(this);
+ }
}
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/task/AbsGroupTask.java b/PublicComponent/src/main/java/com/arialyy/aria/core/task/AbsGroupTask.java
index c8f0918e..215412a7 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/task/AbsGroupTask.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/task/AbsGroupTask.java
@@ -16,7 +16,7 @@
package com.arialyy.aria.core.task;
import com.arialyy.aria.core.download.AbsGroupTaskWrapper;
-import com.arialyy.aria.core.group.AbsGroupUtil;
+import com.arialyy.aria.core.group.AbsGroupLoaderUtil;
/**
* Created by AriaL on 2017/6/29.
@@ -36,7 +36,7 @@ public abstract class AbsGroupTask
*/
public void startSubTask(String url) {
if (getUtil() != null) {
- ((AbsGroupUtil) getUtil()).startSubTask(url);
+ ((AbsGroupLoaderUtil) getUtil()).startSubTask(url);
}
}
@@ -47,7 +47,7 @@ public abstract class AbsGroupTask
*/
public void stopSubTask(String url) {
if (getUtil() != null) {
- ((AbsGroupUtil) getUtil()).stopSubTask(url);
+ ((AbsGroupLoaderUtil) getUtil()).stopSubTask(url);
}
}
}
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/task/IThreadTask.java b/PublicComponent/src/main/java/com/arialyy/aria/core/task/IThreadTask.java
index 7af9aca5..364510a6 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/task/IThreadTask.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/task/IThreadTask.java
@@ -87,4 +87,10 @@ public interface IThreadTask extends Callable {
* @return {@code true} 分块分大小正常,{@code false} 分块大小错误
*/
boolean checkBlock();
+
+ /**
+ * 获取线程id
+ * @return
+ */
+ int getThreadId();
}
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/task/ThreadTask.java b/PublicComponent/src/main/java/com/arialyy/aria/core/task/ThreadTask.java
index d4ea3464..d86fa8b8 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/core/task/ThreadTask.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/core/task/ThreadTask.java
@@ -228,6 +228,10 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
return true;
}
+ @Override public int getThreadId() {
+ return mRecord.threadId;
+ }
+
/**
* 停止任务
*/
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/util/CheckUtil.java b/PublicComponent/src/main/java/com/arialyy/aria/util/CheckUtil.java
index d71c5003..35f2c14b 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/util/CheckUtil.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/util/CheckUtil.java
@@ -19,7 +19,7 @@ package com.arialyy.aria.util;
import android.text.TextUtils;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
-import com.arialyy.aria.core.inf.IRecordHandler;
+import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.orm.DbEntity;
import java.lang.reflect.Modifier;
diff --git a/PublicComponent/src/main/java/com/arialyy/aria/util/RecordUtil.java b/PublicComponent/src/main/java/com/arialyy/aria/util/RecordUtil.java
index 08603eb2..45b71aec 100644
--- a/PublicComponent/src/main/java/com/arialyy/aria/util/RecordUtil.java
+++ b/PublicComponent/src/main/java/com/arialyy/aria/util/RecordUtil.java
@@ -23,7 +23,7 @@ import com.arialyy.aria.core.common.AbsNormalEntity;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.download.M3U8Entity;
-import com.arialyy.aria.core.inf.IRecordHandler;
+import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.core.wrapper.RecordWrapper;
diff --git a/app/gradle.properties b/app/gradle.properties
index 89e0d99e..70172ced 100644
--- a/app/gradle.properties
+++ b/app/gradle.properties
@@ -4,7 +4,7 @@
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
-# For more details on how to configure your build environment visit
+# For more details on how to configure your build environment addComponent
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
@@ -13,6 +13,6 @@
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
-# This option should only be used with decoupled projects. More details, visit
+# This option should only be used with decoupled projects. More details, addComponent
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
diff --git a/build.gradle b/build.gradle
index 63797bf6..d82e187d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -44,8 +44,8 @@ task clean(type: Delete) {
}
ext {
- versionCode = 381
- versionName = '3.8.1'
+ versionCode = 382
+ versionName = '3.8.2'
userOrg = 'arialyy'
groupId = 'com.arialyy.aria'
publishVersion = versionName