修复组合任务在获取子任务信息的过程中,手动停止或删除,没有回调的问题

pull/907/head
laoyuyu 4 years ago
parent 35e66caab5
commit 9db8f1e9c0
  1. 10
      Aria/src/main/java/com/arialyy/aria/core/download/CheckDGEntityUtil.java
  2. 1
      DEV_LOG.md
  3. 35
      FtpComponent/src/main/java/com/arialyy/aria/ftp/AbsFtpInfoTask.java
  4. 12
      FtpComponent/src/main/java/com/arialyy/aria/ftp/download/FtpDFileInfoTask.java
  5. 16
      FtpComponent/src/main/java/com/arialyy/aria/ftp/download/FtpDGInfoTask.java
  6. 8
      FtpComponent/src/main/java/com/arialyy/aria/ftp/upload/FtpUFileInfoTask.java
  7. 23
      HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDFileInfoTask.java
  8. 24
      HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDGInfoTask.java
  9. 21
      M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8InfoTask.java
  10. 6
      PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsGroupLoader.java
  11. 19
      PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSubQueue.java
  12. 2
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsNormalLoader.java
  13. 10
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/IInfoTask.java
  14. 26
      SFtpComponent/src/main/java/com/arialyy/aria/sftp/AbsSFtpInfoTask.java
  15. 7
      SFtpComponent/src/main/java/com/arialyy/aria/sftp/download/SFtpDInfoTask.java
  16. 2
      SFtpComponent/src/main/java/com/arialyy/aria/sftp/upload/SFtpUInfoTask.java

@ -69,7 +69,8 @@ public class CheckDGEntityUtil implements ICheckEntityUtil {
ALog.e(TAG, "文件夹路径不能为null"); ALog.e(TAG, "文件夹路径不能为null");
return false; return false;
} }
if (!FileUtil.canWrite(dirPath)){ File file = new File(dirPath);
if (!FileUtil.canWrite(file.getParent()) && !FileUtil.canWrite(dirPath)) {
ALog.e(TAG, String.format("路径【%s】不可写", dirPath)); ALog.e(TAG, String.format("路径【%s】不可写", dirPath));
return false; return false;
} }
@ -77,7 +78,7 @@ public class CheckDGEntityUtil implements ICheckEntityUtil {
ALog.e(TAG, String.format("文件夹路径【%s】错误", dirPath)); ALog.e(TAG, String.format("文件夹路径【%s】错误", dirPath));
return false; return false;
} }
File file = new File(dirPath);
if (file.isFile()) { if (file.isFile()) {
ALog.e(TAG, String.format("路径【%s】是文件,请设置文件夹路径", dirPath)); ALog.e(TAG, String.format("路径【%s】是文件,请设置文件夹路径", dirPath));
return false; return false;
@ -131,8 +132,9 @@ public class CheckDGEntityUtil implements ICheckEntityUtil {
* @return false 任务不再执行true 任务继续执行 * @return false 任务不再执行true 任务继续执行
*/ */
private boolean checkGroupHash(boolean isIgnoreTaskOccupy, String groupHash) { private boolean checkGroupHash(boolean isIgnoreTaskOccupy, String groupHash) {
DownloadGroupEntity dge = DbEntity.findFirst(DownloadGroupEntity.class, "groupHash=?", groupHash); DownloadGroupEntity dge =
if (dge != null && dge.getGroupHash().equals(mEntity.getGroupHash())){ DbEntity.findFirst(DownloadGroupEntity.class, "groupHash=?", groupHash);
if (dge != null && dge.getGroupHash().equals(mEntity.getGroupHash())) {
mEntity.rowID = dge.rowID; mEntity.rowID = dge.rowID;
return true; return true;
} }

@ -4,6 +4,7 @@
- 修复一个重新下载文件时,同名路径文件没有被被删除的问题 - 修复一个重新下载文件时,同名路径文件没有被被删除的问题
- fix bug https://github.com/AriaLyy/Aria/issues/807 - fix bug https://github.com/AriaLyy/Aria/issues/807
- fix bug https://github.com/AriaLyy/Aria/issues/811 - fix bug https://github.com/AriaLyy/Aria/issues/811
- 修复组合任务在获取子任务信息的过程中,手动停止或删除,没有回调的问题
+ v_3.8.15 (2020/11/9) + v_3.8.15 (2020/11/9)
- 修复不支持断点的连接下载失败问题,https://github.com/AriaLyy/Aria/issues/771 - 修复不支持断点的连接下载失败问题,https://github.com/AriaLyy/Aria/issues/771
- 修复iv不存在时,索引文件异常的问题,https://github.com/AriaLyy/Aria/issues/780 - 修复iv不存在时,索引文件异常的问题,https://github.com/AriaLyy/Aria/issues/780

@ -27,6 +27,7 @@ import aria.apache.commons.net.ftp.FTPSClient;
import com.arialyy.aria.core.AriaConfig; import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.FtpUrlEntity; import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.common.AbsEntity; import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.common.FtpConnectionMode; import com.arialyy.aria.core.common.FtpConnectionMode;
import com.arialyy.aria.core.loader.IInfoTask; import com.arialyy.aria.core.loader.IInfoTask;
import com.arialyy.aria.core.loader.ILoaderVisitor; import com.arialyy.aria.core.loader.ILoaderVisitor;
@ -55,7 +56,8 @@ public abstract class AbsFtpInfoTask<ENTITY extends AbsEntity, TASK_WRAPPER exte
private int mConnectTimeOut; private int mConnectTimeOut;
protected long mSize = 0; protected long mSize = 0;
protected String charSet = "UTF-8"; protected String charSet = "UTF-8";
protected Callback callback; private Callback callback;
private boolean isStop = false, isCancel = false;
public AbsFtpInfoTask(TASK_WRAPPER taskWrapper) { public AbsFtpInfoTask(TASK_WRAPPER taskWrapper) {
mTaskWrapper = taskWrapper; mTaskWrapper = taskWrapper;
@ -81,6 +83,14 @@ public abstract class AbsFtpInfoTask<ENTITY extends AbsEntity, TASK_WRAPPER exte
protected abstract void handelFileInfo(FTPClient client, FTPFile[] files, protected abstract void handelFileInfo(FTPClient client, FTPFile[] files,
String convertedRemotePath) throws IOException; String convertedRemotePath) throws IOException;
@Override public void stop() {
isStop = true;
}
@Override public void cancel() {
isCancel = true;
}
@Override public void setCallback(Callback callback) { @Override public void setCallback(Callback callback) {
this.callback = callback; this.callback = callback;
} }
@ -101,10 +111,10 @@ public abstract class AbsFtpInfoTask<ENTITY extends AbsEntity, TASK_WRAPPER exte
handelFileInfo(client, files, convertedRemotePath); handelFileInfo(client, files, convertedRemotePath);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
failDownload(client, "FTP错误信息", e, true); handleFail(client, "FTP错误信息", e, true);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
failDownload(client, "FTP错误信息", e, true); handleFail(client, "FTP错误信息", e, true);
} finally { } finally {
closeClient(client); closeClient(client);
} }
@ -146,7 +156,7 @@ public abstract class AbsFtpInfoTask<ENTITY extends AbsEntity, TASK_WRAPPER exte
} }
if (client == null) { if (client == null) {
failDownload(client, String.format("链接失败, url: %s", mTaskOption.getUrlEntity().url), null, handleFail(client, String.format("链接失败, url: %s", mTaskOption.getUrlEntity().url), null,
true); true);
return null; return null;
} }
@ -168,14 +178,14 @@ public abstract class AbsFtpInfoTask<ENTITY extends AbsEntity, TASK_WRAPPER exte
} }
if (!loginSuccess) { if (!loginSuccess) {
failDownload(client, "登录失败", null, false); handleFail(client, "登录失败", null, false);
client.disconnect(); client.disconnect();
return null; return null;
} }
int reply = client.getReplyCode(); int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) { if (!FTPReply.isPositiveCompletion(reply)) {
failDownload(client, String.format("无法连接到ftp服务器,filePath: %s, url: %s", mEntity.getKey(), handleFail(client, String.format("无法连接到ftp服务器,filePath: %s, url: %s", mEntity.getKey(),
mTaskOption.getUrlEntity().url), null, true); mTaskOption.getUrlEntity().url), null, true);
client.disconnect(); client.disconnect();
return null; return null;
@ -299,7 +309,7 @@ public abstract class AbsFtpInfoTask<ENTITY extends AbsEntity, TASK_WRAPPER exte
for (FTPFile file : files) { for (FTPFile file : files) {
if (file.isFile()) { if (file.isFile()) {
size += file.getSize(); size += file.getSize();
handleFile(path + file.getName(), file); handleFile(client, path + file.getName(), file);
} else { } else {
String remotePath = CommonUtil.convertFtpChar(charSet, path + file.getName()); String remotePath = CommonUtil.convertFtpChar(charSet, path + file.getName());
size += getFileSize(client.listFiles(remotePath), client, path + file.getName()); size += getFileSize(client.listFiles(remotePath), client, path + file.getName());
@ -314,10 +324,13 @@ public abstract class AbsFtpInfoTask<ENTITY extends AbsEntity, TASK_WRAPPER exte
* @param remotePath ftp服务器文件夹路径 * @param remotePath ftp服务器文件夹路径
* @param ftpFile ftp服务器上对应的文件 * @param ftpFile ftp服务器上对应的文件
*/ */
protected void handleFile(String remotePath, FTPFile ftpFile) { protected void handleFile(FTPClient client, String remotePath, FTPFile ftpFile) {
} }
protected void failDownload(FTPClient client, String msg, Exception e, boolean needRetry) { protected void handleFail(FTPClient client, String msg, Exception e, boolean needRetry) {
if (isStop || isCancel) {
return;
}
if (callback != null) { if (callback != null) {
if (client == null) { if (client == null) {
msg = "创建ftp客户端失败"; msg = "创建ftp客户端失败";
@ -332,6 +345,10 @@ public abstract class AbsFtpInfoTask<ENTITY extends AbsEntity, TASK_WRAPPER exte
} }
} }
protected void onSucceed(CompleteInfo info){
callback.onSucceed(mEntity.getKey(), info);
}
@Override public void accept(ILoaderVisitor visitor) { @Override public void accept(ILoaderVisitor visitor) {
visitor.addComponent(this); visitor.addComponent(this);
} }

@ -38,10 +38,10 @@ final class FtpDFileInfoTask extends AbsFtpInfoTask<DownloadEntity, DTaskWrapper
super(taskEntity); super(taskEntity);
} }
@Override protected void handleFile(String remotePath, FTPFile ftpFile) { @Override protected void handleFile(FTPClient client, String remotePath, FTPFile ftpFile) {
super.handleFile(remotePath, ftpFile); super.handleFile(client, remotePath, ftpFile);
if (!FileUtil.checkMemorySpace(mEntity.getFilePath(), ftpFile.getSize())) { if (!FileUtil.checkMemorySpace(mEntity.getFilePath(), ftpFile.getSize())) {
callback.onFail(mEntity, new AriaFTPException( handleFail(client, "内存空间不足", new AriaFTPException(
String.format("获取ftp文件信息失败,内存空间不足, filePath: %s", mEntity.getFilePath())), String.format("获取ftp文件信息失败,内存空间不足, filePath: %s", mEntity.getFilePath())),
false); false);
} }
@ -72,7 +72,7 @@ final class FtpDFileInfoTask extends AbsFtpInfoTask<DownloadEntity, DTaskWrapper
} }
closeClient(client); closeClient(client);
failDownload(client, handleFail(client,
String.format("文件不存在,url: %s, remotePath:%s", mTaskOption.getUrlEntity().url, String.format("文件不存在,url: %s, remotePath:%s", mTaskOption.getUrlEntity().url,
getRemotePath()), null, false); getRemotePath()), null, false);
return; return;
@ -90,7 +90,7 @@ final class FtpDFileInfoTask extends AbsFtpInfoTask<DownloadEntity, DTaskWrapper
int reply = client.getReplyCode(); int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) { if (!FTPReply.isPositiveCompletion(reply)) {
closeClient(client); closeClient(client);
failDownload(client, "获取文件信息错误,url: " + mTaskOption.getUrlEntity().url, null, true); handleFail(client, "获取文件信息错误,url: " + mTaskOption.getUrlEntity().url, null, true);
return; return;
} }
mTaskWrapper.setCode(reply); mTaskWrapper.setCode(reply);
@ -112,6 +112,6 @@ final class FtpDFileInfoTask extends AbsFtpInfoTask<DownloadEntity, DTaskWrapper
mTaskWrapper.setNewTask(true); mTaskWrapper.setNewTask(true);
} }
mEntity.setFileSize(mSize); mEntity.setFileSize(mSize);
callback.onSucceed(mEntity.getUrl(), new CompleteInfo(code, mTaskWrapper)); onSucceed(new CompleteInfo(code, mTaskWrapper));
} }
} }

@ -49,7 +49,7 @@ final class FtpDGInfoTask extends AbsFtpInfoTask<DownloadGroupEntity, DGTaskWrap
@Override public void run() { @Override public void run() {
if (mTaskWrapper.getEntity().getFileSize() > 1 && checkSubOption()) { if (mTaskWrapper.getEntity().getFileSize() > 1 && checkSubOption()) {
callback.onSucceed(mEntity.getKey(), new CompleteInfo(200, mTaskWrapper)); onSucceed(new CompleteInfo(200, mTaskWrapper));
} else { } else {
super.run(); super.run();
} }
@ -80,7 +80,7 @@ final class FtpDGInfoTask extends AbsFtpInfoTask<DownloadGroupEntity, DGTaskWrap
} }
closeClient(client); closeClient(client);
failDownload(client, handleFail(client,
String.format("文件不存在,url: %s, remotePath:%s", mTaskOption.getUrlEntity().url, String.format("文件不存在,url: %s, remotePath:%s", mTaskOption.getUrlEntity().url,
getRemotePath()), null, false); getRemotePath()), null, false);
return; return;
@ -98,7 +98,7 @@ final class FtpDGInfoTask extends AbsFtpInfoTask<DownloadGroupEntity, DGTaskWrap
int reply = client.getReplyCode(); int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) { if (!FTPReply.isPositiveCompletion(reply)) {
closeClient(client); closeClient(client);
failDownload(client, "获取文件信息错误,url: " + mTaskOption.getUrlEntity().url, null, true); handleFail(client, "获取文件信息错误,url: " + mTaskOption.getUrlEntity().url, null, true);
return; return;
} }
mTaskWrapper.setCode(reply); mTaskWrapper.setCode(reply);
@ -127,8 +127,8 @@ final class FtpDGInfoTask extends AbsFtpInfoTask<DownloadGroupEntity, DGTaskWrap
return mTaskOption.getUrlEntity().remotePath; return mTaskOption.getUrlEntity().remotePath;
} }
@Override protected void handleFile(String remotePath, FTPFile ftpFile) { @Override protected void handleFile(FTPClient client, String remotePath, FTPFile ftpFile) {
super.handleFile(remotePath, ftpFile); super.handleFile(client, remotePath, ftpFile);
addEntity(remotePath, ftpFile); addEntity(remotePath, ftpFile);
} }
@ -138,7 +138,7 @@ final class FtpDGInfoTask extends AbsFtpInfoTask<DownloadGroupEntity, DGTaskWrap
for (DTaskWrapper wrapper : mTaskWrapper.getSubTaskWrapper()) { for (DTaskWrapper wrapper : mTaskWrapper.getSubTaskWrapper()) {
cloneInfo(wrapper); cloneInfo(wrapper);
} }
callback.onSucceed(mEntity.getKey(), new CompleteInfo(code, mTaskWrapper)); onSucceed(new CompleteInfo(code, mTaskWrapper));
} }
private void cloneInfo(DTaskWrapper subWrapper) { private void cloneInfo(DTaskWrapper subWrapper) {
@ -234,8 +234,8 @@ final class FtpDGInfoTask extends AbsFtpInfoTask<DownloadGroupEntity, DGTaskWrap
} }
@Override @Override
protected void failDownload(FTPClient client, String msg, Exception e, boolean needRetry) { protected void handleFail(FTPClient client, String msg, Exception e, boolean needRetry) {
super.failDownload(client, msg, e, needRetry); super.handleFail(client, msg, e, needRetry);
DeleteDGRecord.getInstance().deleteRecord(mTaskWrapper.getEntity(), true, true); DeleteDGRecord.getInstance().deleteRecord(mTaskWrapper.getEntity(), true, true);
} }
} }

@ -60,7 +60,7 @@ final class FtpUFileInfoTask extends AbsFtpInfoTask<UploadEntity, UTaskWrapper>
return; return;
} }
handleFile(getRemotePath(), files.length == 0 ? null : files[0]); handleFile(client, getRemotePath(), files.length == 0 ? null : files[0]);
int reply = client.getReplyCode(); int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) { if (!FTPReply.isPositiveCompletion(reply)) {
//服务器上没有该文件路径,表示该任务为新的上传任务 //服务器上没有该文件路径,表示该任务为新的上传任务
@ -133,8 +133,8 @@ final class FtpUFileInfoTask extends AbsFtpInfoTask<UploadEntity, UTaskWrapper>
* @param remotePath ftp服务器文件夹路径 * @param remotePath ftp服务器文件夹路径
* @param ftpFile ftp服务器上对应的文件 * @param ftpFile ftp服务器上对应的文件
*/ */
@Override protected void handleFile(String remotePath, FTPFile ftpFile) { @Override protected void handleFile(FTPClient client,String remotePath, FTPFile ftpFile) {
super.handleFile(remotePath, ftpFile); super.handleFile(client, remotePath, ftpFile);
this.ftpFile = ftpFile; this.ftpFile = ftpFile;
if (ftpFile != null && ftpFile.getSize() == mEntity.getFileSize()) { if (ftpFile != null && ftpFile.getSize() == mEntity.getFileSize()) {
isComplete = true; isComplete = true;
@ -145,6 +145,6 @@ final class FtpUFileInfoTask extends AbsFtpInfoTask<UploadEntity, UTaskWrapper>
super.onPreComplete(code); super.onPreComplete(code);
CompleteInfo info = new CompleteInfo(isComplete ? CODE_COMPLETE : code, mTaskWrapper); CompleteInfo info = new CompleteInfo(isComplete ? CODE_COMPLETE : code, mTaskWrapper);
info.obj = ftpFile; info.obj = ftpFile;
callback.onSucceed(mEntity.getKey(), info); onSucceed(info);
} }
} }

@ -64,6 +64,7 @@ final class HttpDFileInfoTask implements IInfoTask, Runnable {
private int mConnectTimeOut; private int mConnectTimeOut;
private Callback callback; private Callback callback;
private HttpTaskOption taskOption; private HttpTaskOption taskOption;
private boolean isStop = false, isCancel = false;
HttpDFileInfoTask(DTaskWrapper taskWrapper) { HttpDFileInfoTask(DTaskWrapper taskWrapper) {
this.mTaskWrapper = taskWrapper; this.mTaskWrapper = taskWrapper;
@ -81,7 +82,7 @@ final class HttpDFileInfoTask implements IInfoTask, Runnable {
conn = ConnectionHelp.handleConnection(url, taskOption); conn = ConnectionHelp.handleConnection(url, taskOption);
ConnectionHelp.setConnectParam(taskOption, conn); ConnectionHelp.setConnectParam(taskOption, conn);
conn.setRequestProperty("Range", "bytes=" + 0 + "-"); conn.setRequestProperty("Range", "bytes=" + 0 + "-");
if (AriaConfig.getInstance().getDConfig().isUseHeadRequest()){ if (AriaConfig.getInstance().getDConfig().isUseHeadRequest()) {
ALog.d(TAG, "head请求"); ALog.d(TAG, "head请求");
conn.setRequestMethod("HEAD"); conn.setRequestMethod("HEAD");
} }
@ -111,6 +112,14 @@ final class HttpDFileInfoTask implements IInfoTask, Runnable {
this.callback = callback; this.callback = callback;
} }
@Override public void stop() {
isStop = true;
}
@Override public void cancel() {
isCancel = true;
}
private void handleConnect(HttpURLConnection conn) throws IOException { private void handleConnect(HttpURLConnection conn) throws IOException {
if (taskOption.getRequestEnum() == RequestEnum.POST) { if (taskOption.getRequestEnum() == RequestEnum.POST) {
Map<String, String> params = taskOption.getParams(); Map<String, String> params = taskOption.getParams();
@ -232,7 +241,7 @@ final class HttpDFileInfoTask implements IInfoTask, Runnable {
|| code == HttpURLConnection.HTTP_CREATED // 201 跳转 || code == HttpURLConnection.HTTP_CREATED // 201 跳转
|| code == 307) { || code == 307) {
handleUrlReTurn(conn, conn.getHeaderField("Location")); handleUrlReTurn(conn, conn.getHeaderField("Location"));
}else if (code == 416){ // 处理0k长度的文件的情况 } else if (code == 416) { // 处理0k长度的文件的情况
ALog.w(TAG, "文件长度为0,不支持断点"); ALog.w(TAG, "文件长度为0,不支持断点");
mTaskWrapper.setSupportBP(false); mTaskWrapper.setSupportBP(false);
mTaskWrapper.setNewTask(true); mTaskWrapper.setNewTask(true);
@ -245,12 +254,13 @@ final class HttpDFileInfoTask implements IInfoTask, Runnable {
String.format("任务下载失败,errorCode:%s, errorMsg: %s, url: %s", code, String.format("任务下载失败,errorCode:%s, errorMsg: %s, url: %s", code,
conn.getResponseMessage(), mEntity.getUrl())), !CheckUtil.httpIsBadRequest(code)); conn.getResponseMessage(), mEntity.getUrl())), !CheckUtil.httpIsBadRequest(code));
} }
if (isStop || isCancel) {
return;
}
if (end) { if (end) {
taskOption.setChunked(isChunked); taskOption.setChunked(isChunked);
if (callback != null) {
CompleteInfo info = new CompleteInfo(code, mTaskWrapper); CompleteInfo info = new CompleteInfo(code, mTaskWrapper);
callback.onSucceed(mEntity.getUrl(), info); callback.onSucceed(mEntity.getUrl(), info);
}
mEntity.update(); mEntity.update();
} }
} }
@ -343,7 +353,7 @@ final class HttpDFileInfoTask implements IInfoTask, Runnable {
ConnectionHelp.setConnectParam(taskOption, conn); ConnectionHelp.setConnectParam(taskOption, conn);
conn.setRequestProperty("Cookie", cookies); conn.setRequestProperty("Cookie", cookies);
conn.setRequestProperty("Range", "bytes=" + 0 + "-"); conn.setRequestProperty("Range", "bytes=" + 0 + "-");
if (AriaConfig.getInstance().getDConfig().isUseHeadRequest()){ if (AriaConfig.getInstance().getDConfig().isUseHeadRequest()) {
conn.setRequestMethod("HEAD"); conn.setRequestMethod("HEAD");
} }
conn.setConnectTimeout(mConnectTimeOut); conn.setConnectTimeout(mConnectTimeOut);
@ -367,6 +377,9 @@ final class HttpDFileInfoTask implements IInfoTask, Runnable {
} }
private void failDownload(AriaHTTPException e, boolean needRetry) { private void failDownload(AriaHTTPException e, boolean needRetry) {
if (isStop || isCancel) {
return;
}
if (callback != null) { if (callback != null) {
callback.onFail(mEntity, e, needRetry); callback.onFail(mEntity, e, needRetry);
} }

@ -45,6 +45,7 @@ public final class HttpDGInfoTask implements IInfoTask {
private AtomicInteger count = new AtomicInteger(); private AtomicInteger count = new AtomicInteger();
private AtomicInteger failCount = new AtomicInteger(); private AtomicInteger failCount = new AtomicInteger();
private DownloadGroupListener listener; private DownloadGroupListener listener;
private boolean isStop = false, isCancel = false;
/** /**
* 子任务回调 * 子任务回调
@ -71,6 +72,24 @@ public final class HttpDGInfoTask implements IInfoTask {
this.listener = listener; this.listener = listener;
} }
/**
* 停止
*/
@Override
public void stop() {
isStop = true;
if (mPool != null) {
mPool.shutdown();
}
}
@Override public void cancel() {
isCancel = true;
if (mPool != null) {
mPool.shutdown();
}
}
@Override public void run() { @Override public void run() {
// 如果是isUnknownSize()标志,并且获取大小没有完成,则直接回调onStop // 如果是isUnknownSize()标志,并且获取大小没有完成,则直接回调onStop
if (mPool != null && !getLenComplete) { if (mPool != null && !getLenComplete) {
@ -131,6 +150,11 @@ public final class HttpDGInfoTask implements IInfoTask {
* 检查组合任务大小是否获取完成获取完成后取消阻塞并设置组合任务大小 * 检查组合任务大小是否获取完成获取完成后取消阻塞并设置组合任务大小
*/ */
private void checkGetSizeComplete(int count, int failCount) { private void checkGetSizeComplete(int count, int failCount) {
if (isStop || isCancel){
ALog.w(TAG, "任务已停止或已取消,isStop = " + isStop + ", isCancel = " + isCancel);
notifyLock();
return;
}
if (failCount == wrapper.getSubTaskWrapper().size()) { if (failCount == wrapper.getSubTaskWrapper().size()) {
callback.onFail(wrapper.getEntity(), new AriaHTTPException("获取子任务长度失败"), false); callback.onFail(wrapper.getEntity(), new AriaHTTPException("获取子任务长度失败"), false);
notifyLock(); notifyLock();

@ -115,6 +115,14 @@ final public class M3U8InfoTask implements IInfoTask {
mCallback = callback; mCallback = callback;
} }
@Override public void stop() {
this.isStop = true;
}
@Override public void cancel() {
this.isStop = true;
}
private void handleConnect(String tsListUrl, HttpURLConnection conn) throws IOException { private void handleConnect(String tsListUrl, HttpURLConnection conn) throws IOException {
int code = conn.getResponseCode(); int code = conn.getResponseCode();
if (code == HttpURLConnection.HTTP_OK) { if (code == HttpURLConnection.HTTP_OK) {
@ -205,8 +213,7 @@ final public class M3U8InfoTask implements IInfoTask {
} }
CompleteInfo info = new CompleteInfo(); CompleteInfo info = new CompleteInfo();
info.obj = extInf; info.obj = extInf;
onSucceed(info);
mCallback.onSucceed(mEntity.getKey(), info);
if (fos != null) { if (fos != null) {
fos.close(); fos.close();
} }
@ -223,6 +230,13 @@ final public class M3U8InfoTask implements IInfoTask {
} }
} }
private void onSucceed(CompleteInfo info) {
if (isStop) {
return;
}
mCallback.onSucceed(mEntity.getKey(), info);
}
/** /**
* 添加切片信息到索引文件中 * 添加切片信息到索引文件中
* 直播下载的索引只记录头部信息不记录EXTINF中的信息该信息在onGetPeer的方法中添加 * 直播下载的索引只记录头部信息不记录EXTINF中的信息该信息在onGetPeer的方法中添加
@ -362,6 +376,9 @@ final public class M3U8InfoTask implements IInfoTask {
} }
private void failDownload(String errorInfo, boolean needRetry) { private void failDownload(String errorInfo, boolean needRetry) {
if (isStop) {
return;
}
mCallback.onFail(mEntity, new AriaM3U8Exception(errorInfo), needRetry); mCallback.onFail(mEntity, new AriaM3U8Exception(errorInfo), needRetry);
} }

@ -217,14 +217,20 @@ public abstract class AbsGroupLoader implements ILoaderVisitor, ILoader {
@Override public void cancel() { @Override public void cancel() {
isCancel = true; isCancel = true;
mInfoTask.cancel();
closeTimer(); closeTimer();
mSubQueue.removeAllTask(); mSubQueue.removeAllTask();
mListener.onCancel(); mListener.onCancel();
} }
@Override public void stop() { @Override public void stop() {
mInfoTask.stop();
isStop = true; isStop = true;
if (mSubQueue.getExecSize() == 0) {
mListener.onStop(mGTWrapper.getEntity().getCurrentProgress());
} else {
mSubQueue.stopAllTask(); mSubQueue.stopAllTask();
}
closeTimer(); closeTimer();
} }

@ -43,7 +43,7 @@ final class SimpleSubQueue implements ISubQueue<AbsSubDLoadUtil> {
/** /**
* 最大执行任务数 * 最大执行任务数
*/ */
private int mExecSize; private int mMaxExecSize;
/** /**
* 是否停止任务任务 * 是否停止任务任务
@ -51,7 +51,7 @@ final class SimpleSubQueue implements ISubQueue<AbsSubDLoadUtil> {
private boolean isStopAll = false; private boolean isStopAll = false;
private SimpleSubQueue() { private SimpleSubQueue() {
mExecSize = Configuration.getInstance().dGroupCfg.getSubMaxTaskNum(); mMaxExecSize = Configuration.getInstance().dGroupCfg.getSubMaxTaskNum();
} }
static SimpleSubQueue newInstance() { static SimpleSubQueue newInstance() {
@ -73,6 +73,10 @@ final class SimpleSubQueue implements ISubQueue<AbsSubDLoadUtil> {
return mCache.size(); return mCache.size();
} }
public int getExecSize(){
return mExec.size();
}
boolean isStopAll() { boolean isStopAll() {
return isStopAll; return isStopAll;
} }
@ -82,7 +86,7 @@ final class SimpleSubQueue implements ISubQueue<AbsSubDLoadUtil> {
} }
@Override public void startTask(AbsSubDLoadUtil fileer) { @Override public void startTask(AbsSubDLoadUtil fileer) {
if (mExec.size() < mExecSize) { if (mExec.size() < mMaxExecSize) {
mCache.remove(fileer.getKey()); mCache.remove(fileer.getKey());
mExec.put(fileer.getKey(), fileer); mExec.put(fileer.getKey(), fileer);
ALog.d(TAG, ALog.d(TAG,
@ -102,6 +106,7 @@ final class SimpleSubQueue implements ISubQueue<AbsSubDLoadUtil> {
@Override public void stopAllTask() { @Override public void stopAllTask() {
isStopAll = true; isStopAll = true;
ALog.d(TAG, "停止组合任务"); ALog.d(TAG, "停止组合任务");
mCache.clear();
Set<String> keys = mExec.keySet(); Set<String> keys = mExec.keySet();
for (String key : keys) { for (String key : keys) {
AbsSubDLoadUtil loader = mExec.get(key); AbsSubDLoadUtil loader = mExec.get(key);
@ -117,12 +122,12 @@ final class SimpleSubQueue implements ISubQueue<AbsSubDLoadUtil> {
ALog.e(TAG, String.format("修改组合任务子任务队列数失败,num: %s", num)); ALog.e(TAG, String.format("修改组合任务子任务队列数失败,num: %s", num));
return; return;
} }
if (num == mExecSize) { if (num == mMaxExecSize) {
ALog.i(TAG, String.format("忽略此次修改,oldSize: %s, num: %s", mExecSize, num)); ALog.i(TAG, String.format("忽略此次修改,oldSize: %s, num: %s", mMaxExecSize, num));
return; return;
} }
int oldSize = mExecSize; int oldSize = mMaxExecSize;
mExecSize = num; mMaxExecSize = num;
int diff = Math.abs(oldSize - num); int diff = Math.abs(oldSize - num);
if (oldSize < num) { // 处理队列变小的情况,该情况下将停止队尾任务,并将这些任务添加到缓存队列中 if (oldSize < num) { // 处理队列变小的情况,该情况下将停止队尾任务,并将这些任务添加到缓存队列中

@ -229,6 +229,7 @@ public abstract class AbsNormalLoader<T extends AbsTaskWrapper> implements ILoad
ALog.d(TAG, String.format("任务【%s】正在删除,删除任务失败", mTaskWrapper.getKey())); ALog.d(TAG, String.format("任务【%s】正在删除,删除任务失败", mTaskWrapper.getKey()));
return; return;
} }
mInfoTask.cancel();
closeTimer(); closeTimer();
isCancel = true; isCancel = true;
onCancel(); onCancel();
@ -262,6 +263,7 @@ public abstract class AbsNormalLoader<T extends AbsTaskWrapper> implements ILoad
if (isStop) { if (isStop) {
return; return;
} }
mInfoTask.stop();
closeTimer(); closeTimer();
isStop = true; isStop = true;
onStop(); onStop();

@ -34,6 +34,16 @@ public interface IInfoTask extends ILoaderComponent {
*/ */
void setCallback(Callback callback); void setCallback(Callback callback);
/**
* 任务停止
*/
void stop();
/**
* 任务取消
*/
void cancel();
interface Callback { interface Callback {
/** /**
* 处理完成 * 处理完成

@ -16,6 +16,7 @@
package com.arialyy.aria.sftp; package com.arialyy.aria.sftp;
import com.arialyy.aria.core.FtpUrlEntity; import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.loader.IInfoTask; import com.arialyy.aria.core.loader.IInfoTask;
import com.arialyy.aria.core.loader.ILoaderVisitor; import com.arialyy.aria.core.loader.ILoaderVisitor;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper; import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
@ -32,9 +33,10 @@ import java.io.UnsupportedEncodingException;
*/ */
public abstract class AbsSFtpInfoTask<WP extends AbsTaskWrapper> implements IInfoTask { public abstract class AbsSFtpInfoTask<WP extends AbsTaskWrapper> implements IInfoTask {
protected String TAG = CommonUtil.getClassName(this); protected String TAG = CommonUtil.getClassName(this);
protected Callback callback; private Callback callback;
private WP wrapper; private WP wrapper;
private SFtpTaskOption option; private SFtpTaskOption option;
private boolean isStop = false, isCancel = false;
public AbsSFtpInfoTask(WP wp) { public AbsSFtpInfoTask(WP wp) {
this.wrapper = wp; this.wrapper = wp;
@ -44,6 +46,28 @@ public abstract class AbsSFtpInfoTask<WP extends AbsTaskWrapper> implements IInf
protected abstract void getFileInfo(Session session) protected abstract void getFileInfo(Session session)
throws JSchException, UnsupportedEncodingException, SftpException; throws JSchException, UnsupportedEncodingException, SftpException;
@Override public void stop() {
isStop = true;
}
@Override public void cancel() {
isCancel = true;
}
protected void handleFail(AriaException e, boolean needRetry) {
if (isStop || isCancel){
return;
}
callback.onFail(getWrapper().getEntity(), e, needRetry);
}
protected void onSucceed(CompleteInfo info){
if (isStop || isCancel){
return;
}
callback.onSucceed(getWrapper().getKey(), info);
}
@Override public void run() { @Override public void run() {
try { try {
FtpUrlEntity entity = option.getUrlEntity(); FtpUrlEntity entity = option.getUrlEntity();

@ -39,7 +39,7 @@ final class SFtpDInfoTask extends AbsSFtpInfoTask<DTaskWrapper> {
} }
@Override protected void getFileInfo(Session session) throws JSchException, @Override protected void getFileInfo(Session session) throws JSchException,
UnsupportedEncodingException, SftpException { UnsupportedEncodingException {
SFtpTaskOption option = (SFtpTaskOption) getWrapper().getTaskOption(); SFtpTaskOption option = (SFtpTaskOption) getWrapper().getTaskOption();
ChannelSftp channel = (ChannelSftp) session.openChannel("sftp"); ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
channel.connect(1000); channel.connect(1000);
@ -60,10 +60,9 @@ final class SFtpDInfoTask extends AbsSFtpInfoTask<DTaskWrapper> {
getWrapper().getEntity().setFileSize(attr.getSize()); getWrapper().getEntity().setFileSize(attr.getSize());
CompleteInfo info = new CompleteInfo(); CompleteInfo info = new CompleteInfo();
info.code = 200; info.code = 200;
callback.onSucceed(getWrapper().getKey(), info); onSucceed(info);
} else { } else {
callback.onFail(getWrapper().getEntity(), handleFail(new AriaSFTPException(String.format("文件不存在,remotePath:%s", remotePath)), false);
new AriaSFTPException(String.format("文件不存在,remotePath:%s", remotePath)), false);
} }
channel.disconnect(); channel.disconnect();
} }

@ -64,6 +64,6 @@ final class SFtpUInfoTask extends AbsSFtpInfoTask<UTaskWrapper> {
info.code = isComplete ? ISCOMPLETE : 200; info.code = isComplete ? ISCOMPLETE : 200;
info.obj = attr; info.obj = attr;
channel.disconnect(); channel.disconnect();
callback.onSucceed(getWrapper().getKey(), info); onSucceed(info);
} }
} }

Loading…
Cancel
Save