修复ftp上传完成后,删除服务器端的文件,无法重新下载的问题
This commit is contained in:
@@ -53,7 +53,7 @@ public class DownloadGroupEntity extends AbsGroupEntity {
|
||||
getSubEntities().get(0).getUrl())) {
|
||||
return ITaskWrapper.ERROR;
|
||||
}
|
||||
return getSubEntities().get(0).getUrl().startsWith("ftp") ? ITaskWrapper.D_FTP_DIR
|
||||
return (groupHash.startsWith("ftp") || groupHash.startsWith("sftp")) ? ITaskWrapper.D_FTP_DIR
|
||||
: ITaskWrapper.DG_HTTP;
|
||||
}
|
||||
|
||||
|
||||
@@ -267,7 +267,8 @@ public abstract class AbsGroupLoader implements ILoaderVisitor, ILoader {
|
||||
Looper looper = Looper.myLooper();
|
||||
initState(looper);
|
||||
getState().setSubSize(getWrapper().getSubTaskWrapper().size());
|
||||
if (getState().getCompleteNum() == getState().getSubSize()) {
|
||||
if (getState().getCompleteNum() != 0
|
||||
&& getState().getCompleteNum() == getState().getSubSize()) {
|
||||
mListener.onComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.arialyy.aria.core.group;
|
||||
|
||||
import android.os.Handler;
|
||||
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.IUtil;
|
||||
@@ -81,6 +82,10 @@ public abstract class AbsSubDLoadUtil implements IUtil, Runnable {
|
||||
return mWrapper.getEntity();
|
||||
}
|
||||
|
||||
public TaskRecord getRecord(){
|
||||
return getLoader().getRecord();
|
||||
}
|
||||
|
||||
@Override public void run() {
|
||||
if (isStop || isCancel) {
|
||||
return;
|
||||
|
||||
@@ -23,7 +23,7 @@ import java.util.Set;
|
||||
/**
|
||||
* 组合任务执行中的状态信息
|
||||
*/
|
||||
public class GroupRunState {
|
||||
public final class GroupRunState {
|
||||
/**
|
||||
* 子任务数
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,7 @@ import com.arialyy.aria.core.task.AbsGroupTask;
|
||||
* Created by lyy on 2017/9/8.
|
||||
* 任务组参数传递
|
||||
*/
|
||||
public class GroupSendParams<GROUP_TASK extends AbsGroupTask, ENTITY extends AbsNormalEntity> {
|
||||
public final class GroupSendParams<GROUP_TASK extends AbsGroupTask, ENTITY extends AbsNormalEntity> {
|
||||
|
||||
public GROUP_TASK groupTask;
|
||||
public ENTITY entity;
|
||||
|
||||
@@ -20,21 +20,20 @@ import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.config.Configuration;
|
||||
import com.arialyy.aria.core.inf.IThreadStateManager;
|
||||
import com.arialyy.aria.core.loader.IRecordHandler;
|
||||
import com.arialyy.aria.core.manager.ThreadTaskManager;
|
||||
import com.arialyy.aria.exception.TaskException;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.NetUtils;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 组合任务子任务调度器,用于调度任务的开始、停止、失败、完成等情况
|
||||
* 该调度器生命周期和{@link AbsGroupLoaderUtil}生命周期一致
|
||||
*/
|
||||
class SimpleSchedulers implements Handler.Callback {
|
||||
final class SimpleSchedulers implements Handler.Callback {
|
||||
private static final String TAG = "SimpleSchedulers";
|
||||
private SimpleSubQueue mQueue;
|
||||
private GroupRunState mGState;
|
||||
@@ -86,7 +85,8 @@ class SimpleSchedulers implements Handler.Callback {
|
||||
ThreadTaskManager.getInstance().removeSingleTaskThread(mKey, threadName);
|
||||
break;
|
||||
case IThreadStateManager.STATE_FAIL:
|
||||
handleFail(loaderUtil);
|
||||
boolean needRetry = b.getBoolean(IThreadStateManager.DATA_RETRY, false);
|
||||
handleFail(loaderUtil, needRetry);
|
||||
ThreadTaskManager.getInstance().removeSingleTaskThread(mKey, threadName);
|
||||
break;
|
||||
}
|
||||
@@ -98,18 +98,19 @@ class SimpleSchedulers implements Handler.Callback {
|
||||
* 1、子任务失败次数大于等于配置的重试次数,才能认为子任务停止
|
||||
* 2、stopNum + failNum + completeNum + cacheNum == subSize,则认为组合任务停止
|
||||
* 3、failNum == subSize,只有全部的子任务都失败了,才能任务组合任务失败
|
||||
*
|
||||
* @param needRetry true 需要重试,false 不需要重试
|
||||
*/
|
||||
private synchronized void handleFail(final AbsSubDLoadUtil loaderUtil) {
|
||||
private synchronized void handleFail(final AbsSubDLoadUtil loaderUtil, boolean needRetry) {
|
||||
Configuration config = Configuration.getInstance();
|
||||
|
||||
long interval = config.dGroupCfg.getSubReTryInterval();
|
||||
int num = config.dGroupCfg.getSubReTryNum();
|
||||
boolean isNotNetRetry = config.appCfg.isNotNetRetry();
|
||||
|
||||
final int reTryNum = num;
|
||||
if ((!NetUtils.isConnected(AriaConfig.getInstance().getAPP()) && !isNotNetRetry)
|
||||
if (!needRetry
|
||||
|| (!NetUtils.isConnected(AriaConfig.getInstance().getAPP()) && !isNotNetRetry)
|
||||
|| loaderUtil.getLoader() == null // 如果获取不到文件信息,loader为空
|
||||
|| loaderUtil.getEntity().getFailNum() > reTryNum) {
|
||||
|| loaderUtil.getEntity().getFailNum() > num) {
|
||||
mQueue.removeTaskFromExecQ(loaderUtil);
|
||||
mGState.listener.onSubFail(loaderUtil.getEntity(), new TaskException(TAG,
|
||||
String.format("任务组子任务【%s】下载失败,下载地址【%s】", loaderUtil.getEntity().getFileName(),
|
||||
@@ -127,20 +128,7 @@ class SimpleSchedulers implements Handler.Callback {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果获取不到文件信息,loader为空
|
||||
final ScheduledThreadPoolExecutor timer = new ScheduledThreadPoolExecutor(1);
|
||||
timer.schedule(new Runnable() {
|
||||
@Override public void run() {
|
||||
AbsEntity entity = loaderUtil.getEntity();
|
||||
if (entity.getFailNum() <= reTryNum) {
|
||||
ALog.d(TAG, String.format("任务【%s】开始重试", loaderUtil.getEntity().getFileName()));
|
||||
loaderUtil.reStart();
|
||||
} else {
|
||||
startNext();
|
||||
}
|
||||
}
|
||||
}, interval, TimeUnit.MILLISECONDS);
|
||||
SimpleSubRetryQueue.getInstance().offer(loaderUtil);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,6 +163,11 @@ class SimpleSchedulers implements Handler.Callback {
|
||||
*/
|
||||
private synchronized void handleComplete(AbsSubDLoadUtil loader) {
|
||||
ALog.d(TAG, String.format("子任务【%s】完成", loader.getEntity().getFileName()));
|
||||
if (loader.getRecord().isBlock) {
|
||||
File partFile =
|
||||
new File(String.format(IRecordHandler.SUB_PATH, loader.getRecord().filePath, 0));
|
||||
partFile.renameTo(new File(loader.getRecord().filePath));
|
||||
}
|
||||
ThreadTaskManager.getInstance().removeTaskThread(loader.getKey());
|
||||
mGState.listener.onSubComplete(loader.getEntity());
|
||||
mQueue.removeTaskFromExecQ(loader);
|
||||
|
||||
@@ -29,7 +29,7 @@ import java.util.Set;
|
||||
/**
|
||||
* 组合任务队列,该队列生命周期和{@link AbsGroupLoaderUtil}生命周期一致
|
||||
*/
|
||||
class SimpleSubQueue implements ISubQueue<AbsSubDLoadUtil> {
|
||||
final class SimpleSubQueue implements ISubQueue<AbsSubDLoadUtil> {
|
||||
private final String TAG = CommonUtil.getClassName(getClass());
|
||||
/**
|
||||
* 缓存下载器
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.group;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 子任务重试队列
|
||||
*/
|
||||
final class SimpleSubRetryQueue {
|
||||
private volatile static SimpleSubRetryQueue INSTANCE = null;
|
||||
private ExecutorService pool = new ThreadPoolExecutor(5, 100,
|
||||
60L, TimeUnit.SECONDS,
|
||||
new SynchronousQueue<Runnable>());
|
||||
|
||||
public synchronized static SimpleSubRetryQueue getInstance() {
|
||||
if (INSTANCE == null) {
|
||||
synchronized (SimpleSubRetryQueue.class) {
|
||||
INSTANCE = new SimpleSubRetryQueue();
|
||||
}
|
||||
}
|
||||
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private SimpleSubRetryQueue() {
|
||||
|
||||
}
|
||||
|
||||
void offer(AbsSubDLoadUtil subDLoadUtil) {
|
||||
pool.submit(subDLoadUtil.getLoader());
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.arialyy.aria.core.loader;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import com.arialyy.aria.core.TaskRecord;
|
||||
import com.arialyy.aria.core.ThreadRecord;
|
||||
import com.arialyy.aria.core.common.AbsNormalEntity;
|
||||
@@ -133,7 +135,16 @@ public abstract class AbsNormalTTBuilder implements IThreadTaskBuilder {
|
||||
if (tr.isComplete) {//该线程已经完成
|
||||
currentProgress += endL - startL;
|
||||
ALog.d(TAG, String.format("任务【%s】线程__%s__已完成", mWrapper.getKey(), i));
|
||||
mStateHandler.obtainMessage(IThreadStateManager.STATE_COMPLETE).sendToTarget();
|
||||
Message msg = mStateHandler.obtainMessage();
|
||||
msg.what = IThreadStateManager.STATE_COMPLETE;
|
||||
Bundle b = msg.getData();
|
||||
if (b == null){
|
||||
b = new Bundle();
|
||||
}
|
||||
b.putString(IThreadStateManager.DATA_THREAD_NAME,
|
||||
CommonUtil.getThreadName(getEntity().getUrl(), tr.threadId));
|
||||
msg.setData(b);
|
||||
msg.sendToTarget();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ public final class SubLoader implements ILoader, ILoaderVisitor {
|
||||
private IRecordHandler recordHandler;
|
||||
private IThreadTask threadTask;
|
||||
private String parentKey;
|
||||
private TaskRecord record;
|
||||
|
||||
public SubLoader(AbsTaskWrapper wrapper, Handler schedulers) {
|
||||
this.wrapper = wrapper;
|
||||
@@ -92,7 +93,7 @@ public final class SubLoader implements ILoader, ILoaderVisitor {
|
||||
}
|
||||
|
||||
private void handlerTask() {
|
||||
TaskRecord record = recordHandler.getRecord(wrapper.getEntity().getFileSize());
|
||||
record = recordHandler.getRecord(wrapper.getEntity().getFileSize());
|
||||
if (record.threadRecords != null
|
||||
&& !TextUtils.isEmpty(record.filePath)
|
||||
&& new File(record.filePath).exists()
|
||||
@@ -123,6 +124,10 @@ public final class SubLoader implements ILoader, ILoaderVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
public TaskRecord getRecord(){
|
||||
return record;
|
||||
}
|
||||
|
||||
public void setParentKey(String parentKey) {
|
||||
this.parentKey = parentKey;
|
||||
}
|
||||
|
||||
@@ -86,11 +86,17 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
|
||||
mEntity = mTaskWrapper.getEntity();
|
||||
mLastSaveTime = System.currentTimeMillis();
|
||||
mConfigThreadPool = Executors.newCachedThreadPool();
|
||||
|
||||
isNotNetRetry = AriaConfig.getInstance().getAConfig().isNotNetRetry();
|
||||
mRangeProgress = mRecord.startLocation;
|
||||
mLastRangeProgress = mRangeProgress;
|
||||
updateInterval = config.updateInterval;
|
||||
checkFileExist();
|
||||
}
|
||||
|
||||
private void checkFileExist() {
|
||||
if (!getConfig().tempFile.exists()) {
|
||||
FileUtil.createFile(getConfig().tempFile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -98,7 +98,7 @@ class DelegateFind extends AbsDelegate {
|
||||
*/
|
||||
<T extends AbsDbWrapper> List<T> findRelationData(SQLiteDatabase db, Class<T> clazz,
|
||||
String... expression) {
|
||||
return exeRelationSql(db, clazz, -1, -1, expression);
|
||||
return exeRelationSql(db, clazz, 1, 10, expression);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,6 +111,7 @@ class DelegateFind extends AbsDelegate {
|
||||
<T extends AbsDbWrapper> List<T> findRelationData(SQLiteDatabase db, Class<T> clazz,
|
||||
int page, int num, String... expression) {
|
||||
if (page < 1 || num < 1) {
|
||||
ALog.w(TAG, "page,num 小于1");
|
||||
return null;
|
||||
}
|
||||
return exeRelationSql(db, clazz, page, num, expression);
|
||||
@@ -345,6 +346,7 @@ class DelegateFind extends AbsDelegate {
|
||||
<T extends DbEntity> List<T> findData(SQLiteDatabase db, Class<T> clazz, int page, int num,
|
||||
String... expression) {
|
||||
if (page < 1 || num < 1) {
|
||||
ALog.w(TAG, "page, bum 小于1");
|
||||
return null;
|
||||
}
|
||||
db = checkDb(db);
|
||||
@@ -390,6 +392,7 @@ class DelegateFind extends AbsDelegate {
|
||||
<T extends DbEntity> List<T> findDataByFuzzy(SQLiteDatabase db, Class<T> clazz,
|
||||
int page, int num, String conditions) {
|
||||
if (page < 1 || num < 1) {
|
||||
ALog.w(TAG, "page, bum 小于1");
|
||||
return null;
|
||||
}
|
||||
db = checkDb(db);
|
||||
|
||||
@@ -65,6 +65,15 @@ public class RecordUtil {
|
||||
return;
|
||||
}
|
||||
DownloadGroupEntity groupEntity = DbDataHelper.getDGEntityByPath(dirPath);
|
||||
// 处理组任务存在,而子任务为空的情况
|
||||
if (groupEntity == null) {
|
||||
groupEntity = DbEntity.findFirst(DownloadGroupEntity.class, "dirPath=?", dirPath);
|
||||
if (groupEntity != null) {
|
||||
groupEntity.deleteData();
|
||||
DbEntity.deleteData(DownloadEntity.class, "groupHash=?", groupEntity.getGroupHash());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
delGroupTaskRecord(groupEntity, removeFile, true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user