This commit is contained in:
@@ -43,6 +43,8 @@ import com.arialyy.aria.orm.DbEntity;
|
||||
import com.arialyy.aria.orm.DelegateWrapper;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.AriaCrashHandler;
|
||||
import com.arialyy.aria.util.DeleteDGRecord;
|
||||
import com.arialyy.aria.util.DeleteURecord;
|
||||
import com.arialyy.aria.util.RecordUtil;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@@ -285,7 +287,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
RecordUtil.delGroupTaskRecordByHash(key, removeFile);
|
||||
break;
|
||||
case 3:
|
||||
RecordUtil.delTaskRecord(key, IRecordHandler.TYPE_UPLOAD);
|
||||
DeleteURecord.getInstance().deleteRecord(key, removeFile, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.arialyy.aria.core.inf.IEntity;
|
||||
import com.arialyy.aria.core.manager.TaskWrapperManager;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.aria.util.DeleteDGRecord;
|
||||
import com.arialyy.aria.util.RecordUtil;
|
||||
|
||||
/**
|
||||
@@ -82,11 +83,10 @@ public abstract class AbsNormalTarget<TARGET extends AbsNormalTarget> extends Ab
|
||||
cancel();
|
||||
} else {
|
||||
if (getEntity() instanceof AbsNormalEntity) {
|
||||
RecordUtil.delTaskRecord((AbsNormalEntity) getEntity(), getTaskWrapper().isRemoveFile());
|
||||
RecordUtil.delNormalTaskRecord((AbsNormalEntity) getEntity(), getTaskWrapper().isRemoveFile());
|
||||
} else if (getEntity() instanceof DownloadGroupEntity) {
|
||||
RecordUtil.delGroupTaskRecord(((DownloadGroupEntity) getEntity()),
|
||||
getTaskWrapper().isRemoveFile(),
|
||||
true);
|
||||
DeleteDGRecord.getInstance()
|
||||
.deleteRecord(getEntity(), getTaskWrapper().isRemoveFile(), true);
|
||||
}
|
||||
TaskWrapperManager.getInstance().removeTaskWrapper(getTaskWrapper());
|
||||
}
|
||||
|
||||
@@ -140,7 +140,8 @@ public class CheckDEntityUtil implements ICheckEntityUtil {
|
||||
//设置文件保存路径,如果新文件路径和旧文件路径不同,则修改路径
|
||||
if (!filePath.equals(mEntity.getFilePath())) {
|
||||
// 检查路径冲突
|
||||
if (!CheckUtil.checkDPathConflicts(mWrapper.isIgnoreFilePathOccupy(), filePath)) {
|
||||
if (!CheckUtil.checkDPathConflicts(mWrapper.isIgnoreFilePathOccupy(), filePath,
|
||||
mWrapper.getRequestType())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ public class M3U8Option<OP extends M3U8Option> extends BaseOption {
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否合并ts文件,默认合并ts
|
||||
* 下载完成后,将所有的切片合并为一个文件
|
||||
*
|
||||
* @param mergeFile {@code true}合并所有ts文件为一个
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.arialyy.aria.core.queue;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.inf.IEntity;
|
||||
import com.arialyy.aria.core.inf.TaskSchedulerType;
|
||||
@@ -233,6 +234,7 @@ public abstract class AbsTaskQueue<TASK extends AbsTask, TASK_WRAPPER extends Ab
|
||||
if (task == null) {
|
||||
task = mCachePool.getTask(key);
|
||||
}
|
||||
ALog.i(TAG, "获取任务,key:" + key);
|
||||
return task;
|
||||
}
|
||||
|
||||
@@ -263,6 +265,7 @@ public abstract class AbsTaskQueue<TASK extends AbsTask, TASK_WRAPPER extends Ab
|
||||
ALog.w(TAG, String.format("任务【%s】执行中", task.getKey()));
|
||||
return;
|
||||
}
|
||||
ALog.i(TAG, "添加任务,key:" + task.getKey());
|
||||
mCachePool.removeTask(task);
|
||||
mExecutePool.putTask(task);
|
||||
task.getTaskWrapper().getEntity().setFailNum(0);
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.arialyy.aria.core.scheduler;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
import com.arialyy.annotations.TaskEnum;
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
|
||||
@@ -61,8 +61,9 @@ public class CheckUEntityUtil implements ICheckEntityUtil {
|
||||
return false;
|
||||
}
|
||||
// 任务是新任务,并且路径冲突就不会继续执行
|
||||
if (mWrapper.isNewTask() && !CheckUtil.checkUPathConflicts(
|
||||
mWrapper.isIgnoreFilePathOccupy(), filePath)) {
|
||||
if (mWrapper.isNewTask()
|
||||
&& !CheckUtil.checkUPathConflicts(mWrapper.isIgnoreFilePathOccupy(), filePath,
|
||||
mWrapper.getRequestType())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
- 修复组任务,其中一个子任务在获取文件长度失败后,重新恢复组合任务,组合任务状态变为完成的问题 https://github.com/AriaLyy/Aria/issues/628
|
||||
- 修复组任务中,其中一个子任务是30x地址,导致调度器无法出现该子任务状态的问题
|
||||
- 增加组任务groupHash冲突检查 https://github.com/AriaLyy/Aria/issues/635
|
||||
- 修复task.cancel(false)还是把本地文件删除的问题 https://github.com/AriaLyy/Aria/issues/646
|
||||
+ v_3.8.6 (2020/2/17)
|
||||
- fix bug https://github.com/AriaLyy/Aria/issues/608
|
||||
- fix bug https://github.com/AriaLyy/Aria/issues/579#issuecomment-586665035
|
||||
|
||||
@@ -32,7 +32,7 @@ import com.arialyy.aria.ftp.FtpTaskOption;
|
||||
import com.arialyy.aria.orm.DbEntity;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.aria.util.RecordUtil;
|
||||
import com.arialyy.aria.util.DeleteDGRecord;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
@@ -236,6 +236,6 @@ final class FtpDGInfoTask extends AbsFtpInfoTask<DownloadGroupEntity, DGTaskWrap
|
||||
@Override
|
||||
protected void failDownload(FTPClient client, String msg, Exception e, boolean needRetry) {
|
||||
super.failDownload(client, msg, e, needRetry);
|
||||
RecordUtil.delGroupTaskRecord(mTaskWrapper.getEntity(), true, true);
|
||||
DeleteDGRecord.getInstance().deleteRecord(mTaskWrapper.getEntity(), true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,11 @@ final class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
|
||||
return;
|
||||
}
|
||||
initPath();
|
||||
client.makeDirectory(dir);
|
||||
boolean b = client.makeDirectory(dir);
|
||||
if (!b) {
|
||||
ALog.w(TAG, String.format("创建目录失败,错误码为:%s, msg:%s", client.getReplyCode(),
|
||||
client.getReplyString()));
|
||||
}
|
||||
client.changeWorkingDirectory(dir);
|
||||
client.setRestartOffset(getThreadRecord().startLocation);
|
||||
int reply = client.getReplyCode();
|
||||
|
||||
@@ -176,7 +176,7 @@ final public class M3U8InfoTask implements IInfoTask {
|
||||
} else if (bandWidth == setBand) {
|
||||
handleBandWidth(conn, reader.readLine());
|
||||
} else {
|
||||
failDownload(String.format("【%s】码率不存在", bandWidth), false);
|
||||
failDownload(String.format("【%s】码率不存在", setBand), false);
|
||||
}
|
||||
return;
|
||||
} else if (line.startsWith("#EXT-X-KEY")) {
|
||||
|
||||
@@ -19,17 +19,22 @@ import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
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.listener.BaseDListener;
|
||||
import com.arialyy.aria.core.inf.TaskSchedulerType;
|
||||
import com.arialyy.aria.core.listener.BaseListener;
|
||||
import com.arialyy.aria.core.listener.IDLoadListener;
|
||||
import com.arialyy.aria.core.listener.ISchedulers;
|
||||
import com.arialyy.aria.core.task.AbsTask;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.aria.util.DeleteM3u8Record;
|
||||
|
||||
/**
|
||||
* 下载监听类
|
||||
*/
|
||||
public final class M3U8Listener extends BaseDListener implements IDLoadListener {
|
||||
public final class M3U8Listener
|
||||
extends BaseListener<DownloadEntity, DTaskWrapper, AbsTask<DTaskWrapper>>
|
||||
implements IDLoadListener {
|
||||
|
||||
public M3U8Listener(AbsTask<DTaskWrapper> task, Handler outHandler) {
|
||||
super(task, outHandler);
|
||||
@@ -43,6 +48,12 @@ public final class M3U8Listener extends BaseDListener implements IDLoadListener
|
||||
sendInState2Target(ISchedulers.POST_PRE);
|
||||
}
|
||||
|
||||
@Override public void supportBreakpoint(boolean support) {
|
||||
if (!support) {
|
||||
sendInState2Target(ISchedulers.NO_SUPPORT_BREAK_POINT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 切片开始下载
|
||||
*/
|
||||
@@ -75,4 +86,15 @@ public final class M3U8Listener extends BaseDListener implements IDLoadListener
|
||||
msg.arg1 = ISchedulers.IS_M3U8_PEER;
|
||||
msg.sendToTarget();
|
||||
}
|
||||
|
||||
@Override protected void handleCancel() {
|
||||
int sType = getTask().getSchedulerType();
|
||||
if (sType == TaskSchedulerType.TYPE_CANCEL_AND_NOT_NOTIFY) {
|
||||
mEntity.setComplete(false);
|
||||
mEntity.setState(IEntity.STATE_WAIT);
|
||||
DeleteM3u8Record.getInstance().deleteRecord(mEntity, mTaskWrapper.isRemoveFile(), false);
|
||||
} else {
|
||||
DeleteM3u8Record.getInstance().deleteRecord(mEntity, mTaskWrapper.isRemoveFile(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ 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.m3u8.M3U8TaskOption;
|
||||
import com.arialyy.aria.util.DeleteM3u8Record;
|
||||
import com.arialyy.aria.util.RecordUtil;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -41,7 +42,7 @@ final class LiveRecordHandler extends RecordHandler {
|
||||
|
||||
@Override public void onPre() {
|
||||
super.onPre();
|
||||
RecordUtil.delTaskRecord(getEntity().getFilePath(), IRecordHandler.TYPE_DOWNLOAD);
|
||||
DeleteM3u8Record.getInstance().deleteRecord(getEntity().getFilePath(), true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -144,20 +144,20 @@ public class AriaConfig {
|
||||
|
||||
@Override public void onLost(Network network) {
|
||||
super.onLost(network);
|
||||
isConnectedNet = false;
|
||||
ALog.d(TAG, "onLost");
|
||||
isConnectedNet = isNetworkAvailable();
|
||||
ALog.d(TAG, "onLost, isConnectNet = " + isConnectedNet);
|
||||
}
|
||||
|
||||
@Override public void onAvailable(Network network) {
|
||||
super.onAvailable(network);
|
||||
ALog.d(TAG, "onAvailable");
|
||||
isConnectedNet = true;
|
||||
ALog.d(TAG, "onAvailable, isConnectNet = true");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isNetworkAvailable() {
|
||||
private boolean isNetworkAvailable() {
|
||||
// 获取手机所有连接管理对象(包括对wi-fi,net等连接的管理)
|
||||
ConnectivityManager connectivityManager =
|
||||
(ConnectivityManager) getAPP().getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
|
||||
@@ -75,9 +75,13 @@ public class DownloadEntity extends AbsNormalEntity implements Parcelable {
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果是30x,则是30x后的地址
|
||||
* 设置进来的地址,如果需要获取真实的下载地址,请使用{@link #getRealUrl()}
|
||||
*/
|
||||
@Override public String getKey() {
|
||||
return getUrl();
|
||||
}
|
||||
|
||||
public String getRealUrl(){
|
||||
return isRedirect() ? getRedirectUrl() : getUrl();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ 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;
|
||||
import com.arialyy.aria.util.DeleteDRecord;
|
||||
import com.arialyy.aria.util.RecordUtil;
|
||||
|
||||
/**
|
||||
@@ -55,11 +56,15 @@ public class BaseDListener extends BaseListener<DownloadEntity, DTaskWrapper, Ab
|
||||
if (sType == TaskSchedulerType.TYPE_CANCEL_AND_NOT_NOTIFY) {
|
||||
mEntity.setComplete(false);
|
||||
mEntity.setState(IEntity.STATE_WAIT);
|
||||
RecordUtil.delTaskRecord(mEntity.getFilePath(), IRecordHandler.TYPE_DOWNLOAD,
|
||||
mTaskWrapper.isRemoveFile(), false);
|
||||
|
||||
DeleteDRecord.getInstance().deleteRecord(mEntity, mTaskWrapper.isRemoveFile(), false);
|
||||
//RecordUtil.delTaskRecord(mEntity.getFilePath(), IRecordHandler.TYPE_DOWNLOAD,
|
||||
// mTaskWrapper.isRemoveFile(), false);
|
||||
} else {
|
||||
RecordUtil.delTaskRecord(mEntity.getFilePath(), IRecordHandler.TYPE_DOWNLOAD,
|
||||
mTaskWrapper.isRemoveFile(), true);
|
||||
//RecordUtil.delTaskRecord(mEntity.getFilePath(), IRecordHandler.TYPE_DOWNLOAD,
|
||||
// mTaskWrapper.isRemoveFile(), true);
|
||||
|
||||
DeleteDRecord.getInstance().deleteRecord(mEntity, mTaskWrapper.isRemoveFile(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -180,7 +180,6 @@ public abstract class BaseListener<ENTITY extends AbsEntity, TASK_WRAPPER extend
|
||||
|
||||
protected void saveData(int state, long location) {
|
||||
mEntity.setState(state);
|
||||
mEntity.setComplete(false);
|
||||
|
||||
if (state == IEntity.STATE_CANCEL) {
|
||||
handleCancel();
|
||||
|
||||
@@ -17,12 +17,11 @@ package com.arialyy.aria.core.listener;
|
||||
|
||||
import android.os.Handler;
|
||||
import com.arialyy.aria.core.inf.IEntity;
|
||||
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;
|
||||
import com.arialyy.aria.core.upload.UploadEntity;
|
||||
import com.arialyy.aria.util.RecordUtil;
|
||||
import com.arialyy.aria.util.DeleteURecord;
|
||||
|
||||
/**
|
||||
* 下载监听类
|
||||
@@ -39,11 +38,9 @@ public class BaseUListener extends BaseListener<UploadEntity, UTaskWrapper, AbsT
|
||||
if (sType == TaskSchedulerType.TYPE_CANCEL_AND_NOT_NOTIFY) {
|
||||
mEntity.setComplete(false);
|
||||
mEntity.setState(IEntity.STATE_WAIT);
|
||||
RecordUtil.delTaskRecord(mEntity.getFilePath(), IRecordHandler.TYPE_UPLOAD,
|
||||
mTaskWrapper.isRemoveFile(), false);
|
||||
DeleteURecord.getInstance().deleteRecord(mEntity, mTaskWrapper.isRemoveFile(), false);
|
||||
} else {
|
||||
RecordUtil.delTaskRecord(mEntity.getFilePath(), IRecordHandler.TYPE_UPLOAD,
|
||||
mTaskWrapper.isRemoveFile(), true);
|
||||
DeleteURecord.getInstance().deleteRecord(mEntity, mTaskWrapper.isRemoveFile(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,8 +27,8 @@ import com.arialyy.aria.core.task.DownloadGroupTask;
|
||||
import com.arialyy.aria.exception.AriaException;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.aria.util.DeleteDGRecord;
|
||||
import com.arialyy.aria.util.ErrorHelp;
|
||||
import com.arialyy.aria.util.RecordUtil;
|
||||
|
||||
import static com.arialyy.aria.core.task.AbsTask.ERROR_INFO_KEY;
|
||||
|
||||
@@ -87,7 +87,7 @@ public class DownloadGroupListener
|
||||
handleSubSpeed(subEntity, 0);
|
||||
saveSubState(IEntity.STATE_FAIL, subEntity);
|
||||
saveCurrentLocation();
|
||||
mSeedEntity.groupTask.putExpand(ERROR_INFO_KEY,e);
|
||||
mSeedEntity.groupTask.putExpand(ERROR_INFO_KEY, e);
|
||||
sendInState2Target(ISchedulers.SUB_FAIL, subEntity);
|
||||
if (e != null) {
|
||||
e.printStackTrace();
|
||||
@@ -197,9 +197,9 @@ public class DownloadGroupListener
|
||||
if (sType == TaskSchedulerType.TYPE_CANCEL_AND_NOT_NOTIFY) {
|
||||
mEntity.setComplete(false);
|
||||
mEntity.setState(IEntity.STATE_WAIT);
|
||||
RecordUtil.delGroupTaskRecord(mEntity, mTaskWrapper.isRemoveFile(), false);
|
||||
DeleteDGRecord.getInstance().deleteRecord(mEntity, mTaskWrapper.isRemoveFile(), false);
|
||||
} else {
|
||||
RecordUtil.delGroupTaskRecord(mEntity, mTaskWrapper.isRemoveFile(), true);
|
||||
DeleteDGRecord.getInstance().deleteRecord(mEntity, mTaskWrapper.isRemoveFile(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.arialyy.aria.core.loader;
|
||||
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import com.arialyy.aria.core.TaskRecord;
|
||||
import com.arialyy.aria.core.inf.IThreadStateManager;
|
||||
import com.arialyy.aria.core.listener.IEventListener;
|
||||
@@ -154,33 +155,43 @@ public abstract class AbsNormalLoader<T extends AbsTaskWrapper> implements ILoad
|
||||
if (isBreak()) {
|
||||
return;
|
||||
}
|
||||
ALog.d(TAG, "启动定时器");
|
||||
mTimer = new ScheduledThreadPoolExecutor(1);
|
||||
mTimer.scheduleWithFixedDelay(new Runnable() {
|
||||
@Override public void run() {
|
||||
// 线程池中是不抛异常的,没有日志,很难定位问题,需要手动try-catch
|
||||
try {
|
||||
if (mStateManager == null) {
|
||||
ALog.e(TAG, "stateManager is null");
|
||||
} else if (mStateManager.isComplete()
|
||||
|| mStateManager.isFail()
|
||||
|| !isRunning()
|
||||
|| isBreak()) {
|
||||
//ALog.d(TAG, "isComplete = " + mStateManager.isComplete()
|
||||
// + "; isFail = " + mStateManager.isFail()
|
||||
// + "; isRunning = " + isRunning()
|
||||
// + "; isBreak = " + isBreak());
|
||||
ThreadTaskManager.getInstance().removeTaskThread(mTaskWrapper.getKey());
|
||||
closeTimer();
|
||||
onDestroy();
|
||||
} else if (mStateManager.getCurrentProgress() >= 0) {
|
||||
mListener.onProgress(mStateManager.getCurrentProgress());
|
||||
ALog.d(TAG, String.format("启动定时器,delayTimer = %s, updateInterval = %s", delayTimer(),
|
||||
mUpdateInterval));
|
||||
closeTimer();
|
||||
try {
|
||||
mTimer = new ScheduledThreadPoolExecutor(1);
|
||||
mTimer.scheduleWithFixedDelay(new Runnable() {
|
||||
@Override public void run() {
|
||||
// 线程池中是不抛异常的,没有日志,很难定位问题,需要手动try-catch
|
||||
try {
|
||||
if (mStateManager == null) {
|
||||
ALog.e(TAG, "stateManager is null");
|
||||
} else if (mStateManager.isComplete()
|
||||
|| mStateManager.isFail()
|
||||
|| !isRunning()
|
||||
|| isBreak()) {
|
||||
//ALog.d(TAG, "isComplete = " + mStateManager.isComplete()
|
||||
// + "; isFail = " + mStateManager.isFail()
|
||||
// + "; isRunning = " + isRunning()
|
||||
// + "; isBreak = " + isBreak());
|
||||
ThreadTaskManager.getInstance().removeTaskThread(mTaskWrapper.getKey());
|
||||
closeTimer();
|
||||
onDestroy();
|
||||
} else if (mStateManager.getCurrentProgress() >= 0) {
|
||||
Log.d(TAG, "running...");
|
||||
mListener.onProgress(mStateManager.getCurrentProgress());
|
||||
} else {
|
||||
Log.d(TAG, "未知状态");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}, delayTimer(), mUpdateInterval, TimeUnit.MILLISECONDS);
|
||||
}, delayTimer(), mUpdateInterval, TimeUnit.MILLISECONDS);
|
||||
} catch (Exception e) {
|
||||
ALog.e(TAG, "启动定时器失败");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void closeTimer() {
|
||||
|
||||
@@ -25,12 +25,14 @@ import com.arialyy.aria.core.inf.IThreadStateManager;
|
||||
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.AbsTask;
|
||||
import com.arialyy.aria.core.task.IThreadTask;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.exception.AriaException;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.FileUtil;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 单文件
|
||||
@@ -130,6 +132,8 @@ public class NormalLoader<T extends AbsTaskWrapper> extends AbsNormalLoader<T> {
|
||||
ThreadTaskManager.getInstance().startThread(mTaskWrapper.getKey(), threadTask);
|
||||
}
|
||||
|
||||
List<IThreadTask> list = getTaskList();
|
||||
|
||||
// 启动定时器
|
||||
startTimer();
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public class DownloadTask extends AbsTask<DTaskWrapper> {
|
||||
}
|
||||
|
||||
@Override public String getKey() {
|
||||
return mTaskWrapper.getEntity().getUrl();
|
||||
return mTaskWrapper.getEntity().getKey();
|
||||
}
|
||||
|
||||
public DownloadEntity getDownloadEntity() {
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.Process;
|
||||
import android.util.Log;
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.ThreadRecord;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
@@ -457,7 +458,7 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
|
||||
ThreadTaskManager.getInstance().retryThread(this);
|
||||
} else {
|
||||
ALog.e(TAG, String.format("任务【%s】执行失败", getFileName()));
|
||||
sendFailMsg(null, false);
|
||||
sendFailMsg(null, needRetry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ public class UploadTask extends AbsTask<UTaskWrapper> {
|
||||
}
|
||||
|
||||
@Override public String getKey() {
|
||||
return mTaskWrapper.getEntity().getFilePath();
|
||||
return mTaskWrapper.getEntity().getKey();
|
||||
}
|
||||
|
||||
public UploadEntity getEntity() {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
package com.arialyy.aria.exception;
|
||||
|
||||
public class AriaFTPException extends AriaException {
|
||||
private static final String FTP_EXCEPTION = "Aria SFTP Exception:";
|
||||
private static final String FTP_EXCEPTION = "Aria FTP Exception:";
|
||||
|
||||
public AriaFTPException(String tag, String message) {
|
||||
super(tag, String.format("%s\n%s", FTP_EXCEPTION, message));
|
||||
|
||||
@@ -19,8 +19,8 @@ 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.loader.IRecordHandler;
|
||||
import com.arialyy.aria.core.upload.UploadEntity;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.orm.DbEntity;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.HttpURLConnection;
|
||||
@@ -78,16 +78,17 @@ public class CheckUtil {
|
||||
*
|
||||
* @param isForceDownload true,如果路径冲突,将删除其它任务的记录的
|
||||
* @param filePath 文件保存路径
|
||||
* @param type {@link AbsTaskWrapper#getRequestType()}
|
||||
* @return false 任务不再执行,true 任务继续执行
|
||||
*/
|
||||
public static boolean checkDPathConflicts(boolean isForceDownload, String filePath) {
|
||||
public static boolean checkDPathConflicts(boolean isForceDownload, String filePath, int type) {
|
||||
if (DbEntity.checkDataExist(DownloadEntity.class, "downloadPath=?", filePath)) {
|
||||
if (!isForceDownload) {
|
||||
ALog.e(TAG, String.format("下载失败,保存路径【%s】已经被其它任务占用,请设置其它保存路径", filePath));
|
||||
return false;
|
||||
} else {
|
||||
ALog.w(TAG, String.format("保存路径【%s】已经被其它任务占用,当前任务将覆盖该路径的文件", filePath));
|
||||
RecordUtil.delTaskRecord(filePath, IRecordHandler.TYPE_DOWNLOAD);
|
||||
RecordUtil.delTaskRecord(filePath, type, false, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -99,16 +100,17 @@ public class CheckUtil {
|
||||
*
|
||||
* @param isForceUpload true,如果路径冲突,将删除其它任务的记录的
|
||||
* @param filePath 文件保存路径
|
||||
* @param type {@link AbsTaskWrapper#getRequestType()}
|
||||
* @return false 任务不再执行,true 任务继续执行
|
||||
*/
|
||||
public static boolean checkUPathConflicts(boolean isForceUpload, String filePath) {
|
||||
public static boolean checkUPathConflicts(boolean isForceUpload, String filePath, int type) {
|
||||
if (DbEntity.checkDataExist(UploadEntity.class, "filePath=?", filePath)) {
|
||||
if (!isForceUpload) {
|
||||
ALog.e(TAG, String.format("上传失败,文件路径【%s】已经被其它任务占用,请设置其它文件路径", filePath));
|
||||
return false;
|
||||
} else {
|
||||
ALog.w(TAG, String.format("文件路径【%s】已经被其它任务占用,当前任务将覆盖该路径的文件", filePath));
|
||||
RecordUtil.delTaskRecord(filePath, IRecordHandler.TYPE_UPLOAD);
|
||||
RecordUtil.delTaskRecord(filePath, type, false, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -129,7 +131,7 @@ public class CheckUtil {
|
||||
return false;
|
||||
} else {
|
||||
ALog.w(TAG, String.format("文件夹路径【%s】已经被其它任务占用,当前任务将覆盖该路径", dirPath));
|
||||
RecordUtil.delGroupTaskRecordByPath(dirPath, false);
|
||||
DeleteDGRecord.getInstance().deleteRecord(dirPath, false, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.aria.util;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import com.arialyy.aria.core.TaskRecord;
|
||||
import com.arialyy.aria.core.ThreadRecord;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.DownloadGroupEntity;
|
||||
import com.arialyy.aria.core.loader.IRecordHandler;
|
||||
import com.arialyy.aria.core.wrapper.RecordWrapper;
|
||||
import com.arialyy.aria.orm.DbEntity;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 删除组合任务记录
|
||||
*/
|
||||
public class DeleteDGRecord implements IDeleteRecord {
|
||||
private String TAG = CommonUtil.getClassName(this);
|
||||
|
||||
private static volatile DeleteDGRecord INSTANCE = null;
|
||||
|
||||
private DeleteDGRecord(){
|
||||
|
||||
}
|
||||
|
||||
public static DeleteDGRecord getInstance() {
|
||||
if (INSTANCE == null){
|
||||
synchronized (DeleteDGRecord.class){
|
||||
if (INSTANCE == null){
|
||||
INSTANCE = new DeleteDGRecord();
|
||||
}
|
||||
}
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dirPath 组合任务保存路径
|
||||
* @param needRemoveFile true,无论下载成功以否,都将删除下载下来的文件。false,只会删除下载任务没有完成的文件
|
||||
* @param needRemoveEntity 是否需要删除实体,true 删除实体
|
||||
*/
|
||||
@Override
|
||||
public void deleteRecord(String dirPath, boolean needRemoveFile, boolean needRemoveEntity) {
|
||||
if (TextUtils.isEmpty(dirPath)) {
|
||||
ALog.e(TAG, "删除下载任务组记录失败,组合任务路径为空");
|
||||
return;
|
||||
}
|
||||
deleteRecord(DbDataHelper.getDGEntityByPath(dirPath), needRemoveFile, needRemoveEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRecord(AbsEntity absEntity, boolean needRemoveFile, boolean needRemoveEntity) {
|
||||
if (absEntity == null) {
|
||||
ALog.e(TAG, "删除组合任务记录失败,组合任务实体为空");
|
||||
return;
|
||||
}
|
||||
DownloadGroupEntity groupEntity = (DownloadGroupEntity) absEntity;
|
||||
|
||||
List<RecordWrapper> records =
|
||||
DbEntity.findRelationData(RecordWrapper.class, "dGroupHash=?", groupEntity.getGroupHash());
|
||||
|
||||
// 删除子任务记录
|
||||
if (records == null || records.isEmpty()) {
|
||||
ALog.w(TAG, "组任务记录已删除");
|
||||
} else {
|
||||
for (RecordWrapper record : records) {
|
||||
if (record == null || record.taskRecord == null) {
|
||||
continue;
|
||||
}
|
||||
// 删除分块文件
|
||||
if (record.taskRecord.isBlock) {
|
||||
removeBlockFile(record.taskRecord);
|
||||
}
|
||||
DbEntity.deleteData(ThreadRecord.class, "taskKey=?", record.taskRecord.filePath);
|
||||
record.taskRecord.deleteData();
|
||||
}
|
||||
}
|
||||
|
||||
// 删除组合任务子任务的文件
|
||||
List<DownloadEntity> subs = groupEntity.getSubEntities();
|
||||
if (subs != null) {
|
||||
for (DownloadEntity sub : subs) {
|
||||
if (needRemoveFile || !groupEntity.isComplete()) {
|
||||
FileUtil.deleteFile(sub.getFilePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 删除文件夹
|
||||
if (!TextUtils.isEmpty(groupEntity.getDirPath())) {
|
||||
if (needRemoveFile || !groupEntity.isComplete()) {
|
||||
FileUtil.deleteFile(groupEntity.getDirPath());
|
||||
}
|
||||
}
|
||||
|
||||
if (needRemoveEntity) {
|
||||
DbEntity.deleteData(DownloadEntity.class, "groupHash=?", groupEntity.getGroupHash());
|
||||
DbEntity.deleteData(DownloadGroupEntity.class, "groupHash=?", groupEntity.getGroupHash());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除多线程分块下载的分块文件
|
||||
*/
|
||||
private void removeBlockFile(TaskRecord record) {
|
||||
for (int i = 0, len = record.threadNum; i < len; i++) {
|
||||
FileUtil.deleteFile(String.format(IRecordHandler.SUB_PATH, record.filePath, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.aria.util;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import com.arialyy.aria.core.TaskRecord;
|
||||
import com.arialyy.aria.core.ThreadRecord;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.loader.IRecordHandler;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import com.arialyy.aria.orm.DbEntity;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 删除下载记录
|
||||
*/
|
||||
public class DeleteDRecord implements IDeleteRecord {
|
||||
private String TAG = CommonUtil.getClassName(this);
|
||||
private static volatile DeleteDRecord INSTANCE = null;
|
||||
|
||||
private DeleteDRecord(){
|
||||
|
||||
}
|
||||
|
||||
public static DeleteDRecord getInstance() {
|
||||
if (INSTANCE == null){
|
||||
synchronized (DeleteDRecord.class){
|
||||
if (INSTANCE == null){
|
||||
INSTANCE = new DeleteDRecord();
|
||||
}
|
||||
}
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param filePath 文件保存路径
|
||||
* @param removeTarget true,无论下载成功以否,都将删除下载下来的文件。false,只会删除下载任务没有完成的文件
|
||||
* @param needRemoveEntity 是否需要删除实体
|
||||
*/
|
||||
@Override public void deleteRecord(String filePath, boolean removeTarget,
|
||||
boolean needRemoveEntity) {
|
||||
if (TextUtils.isEmpty(filePath)) {
|
||||
throw new NullPointerException("删除记录失败,文件路径为空");
|
||||
}
|
||||
if (!filePath.startsWith("/")) {
|
||||
throw new IllegalArgumentException(String.format("文件路径错误,filePath:%s", filePath));
|
||||
}
|
||||
DownloadEntity entity = DbEntity.findFirst(DownloadEntity.class, "downloadPath=?", filePath);
|
||||
if (entity == null) {
|
||||
ALog.e(TAG, "删除下载记录失败,没有在数据库中找到对应的实体文件,filePath:" + filePath);
|
||||
return;
|
||||
}
|
||||
deleteRecord(entity, removeTarget, needRemoveEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param absEntity 记录关联的实体
|
||||
* @param needRemoveFile true,无论下载成功以否,都将删除下载下来的文件。false,只会删除下载任务没有完成的文件
|
||||
* @param needRemoveEntity 是否需要删除实体
|
||||
*/
|
||||
@Override
|
||||
public void deleteRecord(AbsEntity absEntity, boolean needRemoveFile, boolean needRemoveEntity) {
|
||||
if (absEntity == null) {
|
||||
ALog.e(TAG, "删除下载记录失败,实体为空");
|
||||
return;
|
||||
}
|
||||
DownloadEntity entity = (DownloadEntity) absEntity;
|
||||
final String filePath = entity.getFilePath();
|
||||
File targetFile = new File(filePath);
|
||||
|
||||
// 兼容以前版本
|
||||
if (entity.getTaskType() == ITaskWrapper.M3U8_VOD || entity.getTaskType() == ITaskWrapper.M3U8_LIVE){
|
||||
DeleteM3u8Record.getInstance().deleteRecord(entity, needRemoveFile, needRemoveEntity);
|
||||
return;
|
||||
}
|
||||
|
||||
TaskRecord record = DbDataHelper.getTaskRecord(entity.getFilePath(), entity.getTaskType());
|
||||
if (record == null) {
|
||||
ALog.e(TAG, "删除下载记录失败,记录为空,filePath:" + entity.getFilePath());
|
||||
return;
|
||||
}
|
||||
|
||||
DbEntity.deleteData(ThreadRecord.class, "taskKey=? AND threadType=?", filePath,
|
||||
String.valueOf(entity.getTaskType()));
|
||||
|
||||
if (needRemoveEntity || !entity.isComplete()) {
|
||||
FileUtil.deleteFile(targetFile);
|
||||
if (record.isBlock) {
|
||||
removeBlockFile(record);
|
||||
}
|
||||
}
|
||||
|
||||
if (needRemoveEntity) {
|
||||
DbEntity.deleteData(DownloadEntity.class, "downloadPath=?", filePath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除多线程分块下载的分块文件
|
||||
*/
|
||||
private void removeBlockFile(TaskRecord record) {
|
||||
for (int i = 0, len = record.threadNum; i < len; i++) {
|
||||
FileUtil.deleteFile(String.format(IRecordHandler.SUB_PATH, record.filePath, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.aria.util;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import com.arialyy.aria.core.TaskRecord;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.M3U8Entity;
|
||||
import com.arialyy.aria.orm.DbEntity;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 删除m3u8记录
|
||||
*/
|
||||
public class DeleteM3u8Record implements IDeleteRecord {
|
||||
private String TAG = CommonUtil.getClassName(this);
|
||||
|
||||
private static volatile DeleteM3u8Record INSTANCE = null;
|
||||
|
||||
private DeleteM3u8Record() {
|
||||
|
||||
}
|
||||
|
||||
public static DeleteM3u8Record getInstance() {
|
||||
if (INSTANCE == null) {
|
||||
synchronized (DeleteM3u8Record.class) {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new DeleteM3u8Record();
|
||||
}
|
||||
}
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param filePath 文件保存路径
|
||||
* @param removeTarget true,无论下载成功以否,都将删除下载下来的文件。false,只会删除下载任务没有完成的文件
|
||||
* @param needRemoveEntity 是否需要删除实体
|
||||
*/
|
||||
@Override public void deleteRecord(String filePath, boolean removeTarget,
|
||||
boolean needRemoveEntity) {
|
||||
if (TextUtils.isEmpty(filePath)) {
|
||||
throw new NullPointerException("删除记录失败,文件路径为空");
|
||||
}
|
||||
if (!filePath.startsWith("/")) {
|
||||
throw new IllegalArgumentException(String.format("文件路径错误,filePath:%s", filePath));
|
||||
}
|
||||
DownloadEntity entity = DbEntity.findFirst(DownloadEntity.class, "downloadPath=?", filePath);
|
||||
if (entity == null) {
|
||||
ALog.e(TAG, "删除下载记录失败,没有在数据库中找到对应的实体文件,filePath:" + filePath);
|
||||
return;
|
||||
}
|
||||
deleteRecord(entity, removeTarget, needRemoveEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRecord(AbsEntity absEntity, boolean needRemoveFile, boolean needRemoveEntity) {
|
||||
if (absEntity == null) {
|
||||
ALog.e(TAG, "删除下载记录失败,实体为空");
|
||||
return;
|
||||
}
|
||||
|
||||
DownloadEntity entity = (DownloadEntity) absEntity;
|
||||
TaskRecord record = DbDataHelper.getTaskRecord(entity.getFilePath(), entity.getTaskType());
|
||||
if (record == null) {
|
||||
ALog.e(TAG, "删除下载记录失败,记录为空,filePath:" + entity.getFilePath());
|
||||
return;
|
||||
}
|
||||
final String filePath = entity.getFilePath();
|
||||
|
||||
DbEntity.deleteData(M3U8Entity.class, "filePath=?", filePath);
|
||||
|
||||
if (needRemoveFile || !entity.isComplete()) {
|
||||
removeTsCache(new File(filePath), record.bandWidth);
|
||||
FileUtil.deleteFile(filePath);
|
||||
}
|
||||
|
||||
if (needRemoveEntity) {
|
||||
DbEntity.deleteData(DownloadEntity.class, "downloadPath=?", filePath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除ts文件,和索引文件(如果有的话)
|
||||
*/
|
||||
private static void removeTsCache(File targetFile, long bandWidth) {
|
||||
|
||||
String cacheDir = null;
|
||||
if (!targetFile.isDirectory()) {
|
||||
cacheDir =
|
||||
String.format("%s/.%s_%s", targetFile.getParent(), targetFile.getName(), bandWidth);
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(cacheDir)) {
|
||||
File cacheDirF = new File(cacheDir);
|
||||
if (!cacheDirF.exists()) {
|
||||
return;
|
||||
}
|
||||
File[] files = cacheDirF.listFiles();
|
||||
for (File f : files) {
|
||||
if (f.exists()) {
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
File cDir = new File(cacheDir);
|
||||
if (cDir.exists()) {
|
||||
cDir.delete();
|
||||
}
|
||||
}
|
||||
|
||||
File indexFile = new File(String.format("%s.index", targetFile.getPath()));
|
||||
|
||||
if (indexFile.exists()) {
|
||||
indexFile.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.aria.util;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import com.arialyy.aria.core.TaskRecord;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.upload.UploadEntity;
|
||||
import com.arialyy.aria.orm.DbEntity;
|
||||
|
||||
/**
|
||||
* 删除上传记录
|
||||
*/
|
||||
public class DeleteURecord implements IDeleteRecord {
|
||||
private String TAG = CommonUtil.getClassName(this);
|
||||
|
||||
private static volatile DeleteURecord INSTANCE = null;
|
||||
|
||||
private DeleteURecord() {
|
||||
|
||||
}
|
||||
|
||||
public static DeleteURecord getInstance() {
|
||||
if (INSTANCE == null) {
|
||||
synchronized (DeleteURecord.class) {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new DeleteURecord();
|
||||
}
|
||||
}
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除上传记录
|
||||
*
|
||||
* @param filePath 上传文件的地址
|
||||
* @param needRemoveFile 上传完成后是否需要删除本地文件。true,上传完成后删除本地文件
|
||||
* @param needRemoveEntity 是否需要删除实体,true 删除实体
|
||||
*/
|
||||
@Override public void deleteRecord(String filePath, boolean needRemoveFile,
|
||||
boolean needRemoveEntity) {
|
||||
if (TextUtils.isEmpty(filePath)) {
|
||||
throw new NullPointerException("删除记录失败,文件路径为空");
|
||||
}
|
||||
if (!filePath.startsWith("/")) {
|
||||
throw new IllegalArgumentException(String.format("文件路径错误,filePath:%s", filePath));
|
||||
}
|
||||
|
||||
UploadEntity entity = DbEntity.findFirst(UploadEntity.class, "filePath=?", filePath);
|
||||
if (entity == null) {
|
||||
ALog.e(TAG, "删除上传记录失败,没有在数据库中找到对应的实体文件,filePath:" + filePath);
|
||||
return;
|
||||
}
|
||||
deleteRecord(entity, needRemoveFile, needRemoveEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRecord(AbsEntity absEntity, boolean needRemoveFile, boolean needRemoveEntity) {
|
||||
if (absEntity == null) {
|
||||
ALog.e(TAG, "删除上传记录失败,实体为空");
|
||||
return;
|
||||
}
|
||||
|
||||
UploadEntity entity = (UploadEntity) absEntity;
|
||||
DbEntity.deleteData(TaskRecord.class, "filePath=? AND taskType=?", entity.getFilePath(),
|
||||
String.valueOf(entity.getTaskType()));
|
||||
|
||||
if (needRemoveFile) {
|
||||
FileUtil.deleteFile(entity.getFilePath());
|
||||
}
|
||||
|
||||
if (needRemoveEntity) {
|
||||
DbEntity.deleteData(UploadEntity.class, "filePath=?", entity.getFilePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.aria.util;
|
||||
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
|
||||
/**
|
||||
* 删除记录
|
||||
*/
|
||||
public interface IDeleteRecord {
|
||||
|
||||
/**
|
||||
* 删除记录
|
||||
*
|
||||
* @param key 记录关联的key
|
||||
* @param needRemoveFile 是否需要删除文件
|
||||
* @param needRemoveEntity 是否需要删除实体,true 删除实体
|
||||
*/
|
||||
void deleteRecord(String key, boolean needRemoveFile, boolean needRemoveEntity);
|
||||
|
||||
/**
|
||||
* 删除记录
|
||||
*
|
||||
* @param absEntity 记录关联的实体
|
||||
* @param needRemoveFile 是否需要删除文件
|
||||
* @param needRemoveEntity 是否需要删除实体,true 删除实体
|
||||
*/
|
||||
void deleteRecord(AbsEntity absEntity, boolean needRemoveFile, boolean needRemoveEntity);
|
||||
}
|
||||
@@ -18,18 +18,13 @@ package com.arialyy.aria.util;
|
||||
import android.text.TextUtils;
|
||||
import com.arialyy.aria.core.TaskRecord;
|
||||
import com.arialyy.aria.core.ThreadRecord;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.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.loader.IRecordHandler;
|
||||
import com.arialyy.aria.core.upload.UploadEntity;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import com.arialyy.aria.core.wrapper.RecordWrapper;
|
||||
import com.arialyy.aria.orm.DbEntity;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 任务记录处理工具
|
||||
@@ -49,93 +44,7 @@ public class RecordUtil {
|
||||
return;
|
||||
}
|
||||
DownloadGroupEntity groupEntity = DbDataHelper.getDGEntityByHash(groupHash);
|
||||
|
||||
delGroupTaskRecord(groupEntity, removeFile, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据路径删除组合任务记录
|
||||
*
|
||||
* @param removeFile {@code true} 无论任务是否完成,都会删除记录和文件;
|
||||
* {@code false} 如果任务已经完成,则只删除记录,不删除文件;任务未完成,记录和文件都会删除。
|
||||
*/
|
||||
public static void delGroupTaskRecordByPath(String dirPath, boolean removeFile) {
|
||||
if (TextUtils.isEmpty(dirPath)) {
|
||||
ALog.e(TAG, "删除下载任务组记录失败,组合任务路径为空");
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除任务组记录
|
||||
*
|
||||
* @param removeFile {@code true} 无论任务是否完成,都会删除记录和文件;
|
||||
* {@code false} 如果任务已经完成,则只删除记录,不删除文件;任务未完成,记录和文件都会删除。
|
||||
*/
|
||||
public static void delGroupTaskRecord(DownloadGroupEntity groupEntity, boolean removeFile,
|
||||
boolean removeEntity) {
|
||||
if (groupEntity == null) {
|
||||
ALog.e(TAG, "删除下载任务组记录失败,任务组实体为null");
|
||||
return;
|
||||
}
|
||||
List<RecordWrapper> records =
|
||||
DbEntity.findRelationData(RecordWrapper.class, "dGroupHash=?", groupEntity.getGroupHash());
|
||||
|
||||
if (records == null || records.isEmpty()) {
|
||||
ALog.w(TAG, "组任务记录已删除");
|
||||
} else {
|
||||
for (RecordWrapper record : records) {
|
||||
if (record == null || record.taskRecord == null) {
|
||||
continue;
|
||||
}
|
||||
// 删除分块文件
|
||||
if (record.taskRecord.isBlock) {
|
||||
for (int i = 0, len = record.taskRecord.threadNum; i < len; i++) {
|
||||
File partFile =
|
||||
new File(String.format(IRecordHandler.SUB_PATH, record.taskRecord.filePath, i));
|
||||
if (partFile.exists()) {
|
||||
partFile.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
DbEntity.deleteData(ThreadRecord.class, "taskKey=?", record.taskRecord.filePath);
|
||||
record.taskRecord.deleteData();
|
||||
}
|
||||
}
|
||||
|
||||
List<DownloadEntity> subs = groupEntity.getSubEntities();
|
||||
if (subs != null) {
|
||||
for (DownloadEntity sub : subs) {
|
||||
File file = new File(sub.getFilePath());
|
||||
if (file.exists() && (removeFile || !sub.isComplete())) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 删除文件夹
|
||||
if (!TextUtils.isEmpty(groupEntity.getDirPath())) {
|
||||
File dir = new File(groupEntity.getDirPath());
|
||||
if (dir.exists() && (removeFile || !groupEntity.isComplete())) {
|
||||
dir.delete();
|
||||
}
|
||||
}
|
||||
if (removeEntity) {
|
||||
DbEntity.deleteData(DownloadEntity.class, "groupHash=?", groupEntity.getGroupHash());
|
||||
DbEntity.deleteData(DownloadGroupEntity.class, "groupHash=?", groupEntity.getGroupHash());
|
||||
}
|
||||
DeleteDGRecord.getInstance().deleteRecord(groupEntity, removeFile, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,215 +54,23 @@ public class RecordUtil {
|
||||
* {@code false} 如果是下载任务,并且任务已经完成,则只删除记录,不删除文件;任务未完成,记录和文件都会删除。
|
||||
* 如果是上传任务,无论任务是否完成,都只删除记录
|
||||
*/
|
||||
public static void delTaskRecord(AbsNormalEntity entity, boolean removeFile) {
|
||||
if (entity == null) return;
|
||||
String filePath;
|
||||
int type;
|
||||
if (entity instanceof DownloadEntity) {
|
||||
type = IRecordHandler.TYPE_DOWNLOAD;
|
||||
filePath = entity.getFilePath();
|
||||
} else if (entity instanceof UploadEntity) {
|
||||
type = IRecordHandler.TYPE_UPLOAD;
|
||||
filePath = entity.getFilePath();
|
||||
} else {
|
||||
ALog.w(TAG, "删除记录失败,未知类型");
|
||||
return;
|
||||
}
|
||||
File targetFile = new File(filePath);
|
||||
TaskRecord record = getTaskRecord(filePath);
|
||||
if (record == null) {
|
||||
if (removeFile) {
|
||||
removeTargetFile(targetFile);
|
||||
}
|
||||
removeRecord(filePath);
|
||||
removeEntity(type, filePath);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* 处理任务未完成的情况
|
||||
*/
|
||||
if (!entity.isComplete()) {
|
||||
if (recordIsM3U8(record.taskType)) { // 删除ts分片文件
|
||||
removeTsCache(targetFile, record.bandWidth);
|
||||
} else if (record.isBlock) { // 删除分块文件
|
||||
removeBlockFile(record);
|
||||
}
|
||||
removeTargetFile(targetFile);
|
||||
} else if (removeFile) { // 处理任务完成情况
|
||||
if (recordIsM3U8(record.taskType)) {
|
||||
removeTsCache(targetFile, record.bandWidth);
|
||||
}
|
||||
removeTargetFile(targetFile);
|
||||
}
|
||||
|
||||
// 成功与否都将删除记录
|
||||
removeRecord(filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务记录是否是m3u8记录
|
||||
*
|
||||
* @param recordType 任务记录类型
|
||||
* @return true 为m3u8任务
|
||||
*/
|
||||
private static boolean recordIsM3U8(int recordType) {
|
||||
return recordType == ITaskWrapper.M3U8_VOD || recordType == ITaskWrapper.M3U8_LIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除任务记录,默认删除文件
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @param removeFile {@code true} 无论任务是否完成,都会删除记录和文件;
|
||||
* {@code false} 如果是下载任务,并且任务已经完成,则只删除记录,不删除文件;任务未完成,记录和文件都会删除。
|
||||
* 如果是上传任务,无论任务是否完成,都只删除记录
|
||||
* @param type {@link IRecordHandler#TYPE_DOWNLOAD}下载任务的记录,{@link IRecordHandler#TYPE_UPLOAD}
|
||||
* 上传任务的记录
|
||||
* @param removeEntity {@code true} 删除任务实体,
|
||||
*/
|
||||
public static void delTaskRecord(String filePath, int type, boolean removeFile,
|
||||
boolean removeEntity) {
|
||||
if (TextUtils.isEmpty(filePath)) {
|
||||
throw new NullPointerException("删除记录失败,文件路径为空");
|
||||
}
|
||||
if (!filePath.startsWith("/")) {
|
||||
throw new IllegalArgumentException(String.format("文件路径错误,filePath:%s", filePath));
|
||||
}
|
||||
if (type != IRecordHandler.TYPE_DOWNLOAD && type != IRecordHandler.TYPE_UPLOAD) {
|
||||
throw new IllegalArgumentException("任务记录类型错误");
|
||||
}
|
||||
|
||||
AbsEntity entity;
|
||||
if (type == IRecordHandler.TYPE_DOWNLOAD) {
|
||||
entity = DbEntity.findFirst(DownloadEntity.class, "downloadPath=?", filePath);
|
||||
} else {
|
||||
entity = DbEntity.findFirst(UploadEntity.class, "filePath=?", filePath);
|
||||
}
|
||||
File targetFile = new File(filePath);
|
||||
TaskRecord record = getTaskRecord(filePath);
|
||||
if (entity == null || record == null) {
|
||||
if (removeFile) {
|
||||
removeTargetFile(targetFile);
|
||||
}
|
||||
removeRecord(filePath);
|
||||
removeEntity(type, filePath);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* 处理任务未完成的情况
|
||||
*/
|
||||
if (!entity.isComplete()) {
|
||||
if (recordIsM3U8(record.taskType)) { // 删除ts分片文件
|
||||
removeTsCache(targetFile, record.bandWidth);
|
||||
} else if (record.isBlock) { // 删除分块文件
|
||||
removeBlockFile(record);
|
||||
}
|
||||
removeTargetFile(targetFile);
|
||||
} else if (removeFile) { // 处理任务完成情况
|
||||
if (recordIsM3U8(record.taskType)) {
|
||||
removeTsCache(targetFile, record.bandWidth);
|
||||
}
|
||||
removeTargetFile(targetFile);
|
||||
}
|
||||
|
||||
// 成功与否都将删除记录
|
||||
removeRecord(filePath);
|
||||
|
||||
if (removeEntity) {
|
||||
removeEntity(type, filePath);
|
||||
}
|
||||
}
|
||||
|
||||
private static void removeTargetFile(File targetFile) {
|
||||
if (targetFile.exists()) {
|
||||
targetFile.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private static void removeRecord(String filePath) {
|
||||
ALog.i(TAG, "删除任务记录");
|
||||
DbEntity.deleteData(ThreadRecord.class, "taskKey=?", filePath);
|
||||
DbEntity.deleteData(TaskRecord.class, "filePath=?", filePath);
|
||||
// 处理m3u8实体的删除
|
||||
DbEntity.deleteData(M3U8Entity.class, "filePath=?", filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除实体
|
||||
*
|
||||
* @param type {@link IRecordHandler#TYPE_DOWNLOAD}下载任务的记录,{@link IRecordHandler#TYPE_UPLOAD}
|
||||
* 上传任务的记录
|
||||
*/
|
||||
private static void removeEntity(int type, String filePath) {
|
||||
if (type == IRecordHandler.TYPE_DOWNLOAD) {
|
||||
DbEntity.deleteData(DownloadEntity.class, "downloadPath=?", filePath);
|
||||
} else {
|
||||
DbEntity.deleteData(UploadEntity.class, "filePath=?", filePath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据文件路径获取任务记录
|
||||
*/
|
||||
private static TaskRecord getTaskRecord(String filePath) {
|
||||
List<RecordWrapper> recordWrapper =
|
||||
DbEntity.findRelationData(RecordWrapper.class, "filePath=?", filePath);
|
||||
if (recordWrapper == null
|
||||
|| recordWrapper.isEmpty()
|
||||
|| recordWrapper.get(0) == null
|
||||
|| recordWrapper.get(0).taskRecord == null) {
|
||||
return null;
|
||||
} else {
|
||||
return recordWrapper.get(0).taskRecord;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除多线程分块下载的分块文件
|
||||
*/
|
||||
private static void removeBlockFile(TaskRecord record) {
|
||||
for (int i = 0, len = record.threadNum; i < len; i++) {
|
||||
File partFile = new File(String.format(IRecordHandler.SUB_PATH, record.filePath, i));
|
||||
if (partFile.exists()) {
|
||||
partFile.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除ts文件,和索引文件(如果有的话)
|
||||
*/
|
||||
private static void removeTsCache(File targetFile, long bandWidth) {
|
||||
|
||||
String cacheDir = null;
|
||||
if (!targetFile.isDirectory()) {
|
||||
cacheDir =
|
||||
String.format("%s/.%s_%s", targetFile.getParent(), targetFile.getName(), bandWidth);
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(cacheDir)) {
|
||||
File cacheDirF = new File(cacheDir);
|
||||
if (!cacheDirF.exists()) {
|
||||
return;
|
||||
}
|
||||
File[] files = cacheDirF.listFiles();
|
||||
for (File f : files) {
|
||||
if (f.exists()) {
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
File cDir = new File(cacheDir);
|
||||
if (cDir.exists()) {
|
||||
cDir.delete();
|
||||
}
|
||||
}
|
||||
|
||||
File indexFile = new File(String.format("%s.index", targetFile.getPath()));
|
||||
|
||||
if (indexFile.exists()) {
|
||||
indexFile.delete();
|
||||
public static void delNormalTaskRecord(AbsNormalEntity entity, boolean removeFile) {
|
||||
switch (entity.getTaskType()) {
|
||||
case ITaskWrapper.D_FTP:
|
||||
case ITaskWrapper.D_HTTP:
|
||||
case ITaskWrapper.D_SFTP:
|
||||
case ITaskWrapper.D_TCP:
|
||||
DeleteDRecord.getInstance().deleteRecord(entity, removeFile, true);
|
||||
break;
|
||||
case ITaskWrapper.U_FTP:
|
||||
case ITaskWrapper.U_HTTP:
|
||||
case ITaskWrapper.U_SFTP:
|
||||
DeleteURecord.getInstance().deleteRecord(entity, removeFile, true);
|
||||
break;
|
||||
case ITaskWrapper.M3U8_LIVE:
|
||||
case ITaskWrapper.M3U8_VOD:
|
||||
DeleteM3u8Record.getInstance().deleteRecord(entity, removeFile, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,11 +78,31 @@ public class RecordUtil {
|
||||
* 删除任务记录,默认删除文件,删除任务实体
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @param type {@link IRecordHandler#TYPE_DOWNLOAD}下载任务的记录,{@link IRecordHandler#TYPE_UPLOAD}
|
||||
* @param removeFile {@code true} 无论任务是否完成,都会删除记录和文件;
|
||||
* @param type {@link AbsTaskWrapper#getRequestType()}
|
||||
* {@code false} 如果是下载任务,并且任务已经完成,则只删除记录,不删除文件;任务未完成,记录和文件都会删除。
|
||||
* 如果是上传任务,无论任务是否完成,都只删除记录
|
||||
* 上传任务的记录
|
||||
*/
|
||||
public static void delTaskRecord(String filePath, int type) {
|
||||
delTaskRecord(filePath, type, false, true);
|
||||
public static void delTaskRecord(String filePath, int type, boolean removeFile,
|
||||
boolean removeEntity) {
|
||||
switch (type) {
|
||||
case ITaskWrapper.D_FTP:
|
||||
case ITaskWrapper.D_HTTP:
|
||||
case ITaskWrapper.D_SFTP:
|
||||
case ITaskWrapper.D_TCP:
|
||||
DeleteDRecord.getInstance().deleteRecord(filePath, removeFile, removeEntity);
|
||||
break;
|
||||
case ITaskWrapper.U_FTP:
|
||||
case ITaskWrapper.U_HTTP:
|
||||
case ITaskWrapper.U_SFTP:
|
||||
DeleteURecord.getInstance().deleteRecord(filePath, removeFile, removeEntity);
|
||||
break;
|
||||
case ITaskWrapper.M3U8_LIVE:
|
||||
case ITaskWrapper.M3U8_VOD:
|
||||
DeleteM3u8Record.getInstance().deleteRecord(filePath, removeFile, removeEntity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,6 +15,8 @@ android {
|
||||
versionName "1.0"
|
||||
multiDexEnabled true
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
@@ -56,6 +58,10 @@ android {
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'androidx.test:runner:1.2.0'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'com.google.android.material:material:1.0.0'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:${rootProject.ext.kotlin_version}"
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.example.arial.downloaddemo
|
||||
|
||||
import androidx.test.runner.AndroidJUnit4
|
||||
import com.arialyy.aria.util.CommonUtil
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import kotlin.math.pow
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ApiTest {
|
||||
|
||||
@Test
|
||||
fun testSpeed() {
|
||||
val speed = 1024.0.pow(4.0) * 2
|
||||
println("speed = ${CommonUtil.formatFileSize(speed)}")
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(DownloadUtil)
|
||||
*
|
||||
* 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.example.arial.downloaddemo;
|
||||
|
||||
import android.app.Application;
|
||||
import android.test.ApplicationTestCase;
|
||||
|
||||
/**
|
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||
*/
|
||||
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||
public ApplicationTest() {
|
||||
super(Application.class);
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
<!-- http://aria.laoyuyu.me/aria_doc/api/use_broadcast.html -->
|
||||
<useBroadcast value="false"/>
|
||||
<!--断网的时候是否重试,true:断网也重试;false:断网不重试,直接走失败的回调-->
|
||||
<notNetRetry value="false"/>
|
||||
<notNetRetry value="true"/>
|
||||
</app>
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ public class BaseApplication extends Application {
|
||||
super.onCreate();
|
||||
INSTANCE = this;
|
||||
AbsFrame.init(this);
|
||||
//Aria.init(this);
|
||||
Aria.init(this);
|
||||
if (BuildConfig.DEBUG) {
|
||||
//StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
|
||||
// .detectAll()
|
||||
|
||||
@@ -55,11 +55,11 @@ public class HttpDownloadModule extends BaseViewModule {
|
||||
//String url = "http://fdfs.speedata.cn:9989/group1/M00/00/05/rBGFrl3fdAKAVJwfMtSa9R18wLU139.zip";
|
||||
//String url = "http://9.9.9.28:8088/files/update.zip";
|
||||
//String url = "https://ss1.baidu.com/-4o3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/sign=a9e671b9a551f3dedcb2bf64a4eff0ec/4610b912c8fcc3cef70d70409845d688d53f20f7.jpg";
|
||||
//String url = "https://imtt.dd.qq.com/16891/apk/70BFFDB05AB8686F2A4CF3E07588A377.apk?fsname=com.tencent.tmgp.speedmobile_1.16.0.33877_1160033877.apk&csr=1bbd";
|
||||
String url = "https://imtt.dd.qq.com/16891/apk/70BFFDB05AB8686F2A4CF3E07588A377.apk?fsname=com.tencent.tmgp.speedmobile_1.16.0.33877_1160033877.apk&csr=1bbd";
|
||||
//String url = "https://ss1.baidu.com/-4o3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/sign=a9e671b9a551f3dedcb2bf64a4eff0ec/4610b912c8fcc3cef70d70409845d688d53f20f7.jpg";
|
||||
//String filePath = AppUtil.getConfigValue(context, HTTP_PATH_KEY, defFilePath);
|
||||
//String url = "https://y.qq.com/download/import/QQMusic-import-1.2.1.zip";
|
||||
String url = "https://video-hkt1-1.xx.fbcdn.net/v/t42.9040-2/89465702_658301101378505_5469280744218034176_n.mp4?_nc_cat=107&_nc_sid=985c63&efg=eyJ2ZW5jb2RlX3RhZyI6ImxlZ2FjeV9zZCJ9&_nc_oc=AQmzYwQG9vccyqr7S44-cfHc4wJ9010O1nvspG2DPV4cTct1pLrjKl1e1UmOJV99bJw&_nc_ht=video-hkt1-1.xx&oh=49bd04435aaa8b4459b8d5cb7d1e7c79&oe=5E672E37";
|
||||
//String url = "https://video-hkt1-1.xx.fbcdn.net/v/t42.9040-2/89465702_658301101378505_5469280744218034176_n.mp4?_nc_cat=107&_nc_sid=985c63&efg=eyJ2ZW5jb2RlX3RhZyI6ImxlZ2FjeV9zZCJ9&_nc_oc=AQmzYwQG9vccyqr7S44-cfHc4wJ9010O1nvspG2DPV4cTct1pLrjKl1e1UmOJV99bJw&_nc_ht=video-hkt1-1.xx&oh=49bd04435aaa8b4459b8d5cb7d1e7c79&oe=5E672E37";
|
||||
//String url = "http://donuts.aigauss.com/doc_fPhW2DBGj3_1578932414.png";
|
||||
String filePath = "/mnt/sdcard/update.mp4";
|
||||
//String url = "https://dhfspace.360drm.com/1_12809_1543904946_VID_20180808_212829.vep?e=1578554567&token=gUBmfZgZS5wy4wdQIDZG8UVxlNCyVSjvksIb13K5:WYSZRgmLbH1_9hjgqOAGmqR27JM=";
|
||||
|
||||
@@ -118,7 +118,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
}
|
||||
|
||||
@Override public void cancel(View v, AbsEntity entity) {
|
||||
Aria.download(this).load(mTaskId).cancel();
|
||||
Aria.download(this).load(mTaskId).cancel(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -311,7 +311,7 @@ public class M3U8VodDLoadActivity extends BaseActivity<ActivityM3u8VodBinding> {
|
||||
.setVodTsUrlConvert(new VodTsUrlConverter());
|
||||
//.setMergeHandler(new TsMergeHandler());
|
||||
option.setKeyUrlConverter(new KeyUrlConverter());
|
||||
//option.setBandWidthUrlConverter(new BandWidthUrlConverter(mUrl));
|
||||
option.setBandWidthUrlConverter(new BandWidthUrlConverter(mUrl));
|
||||
return option;
|
||||
}
|
||||
|
||||
@@ -327,10 +327,11 @@ public class M3U8VodDLoadActivity extends BaseActivity<ActivityM3u8VodBinding> {
|
||||
static class VodTsUrlConverter implements IVodTsUrlConverter {
|
||||
@Override public List<String> convert(String m3u8Url, List<String> tsUrls) {
|
||||
Uri uri = Uri.parse(m3u8Url);
|
||||
String parentUrl = "http://devimages.apple.com/iphone/samples/bipbop/gear1/";
|
||||
//String parentUrl = "http://" + uri.getHost() + "/gear1/";
|
||||
int index = m3u8Url.lastIndexOf("/");
|
||||
//int index = m3u8Url.lastIndexOf("/");
|
||||
//String parentUrl = m3u8Url.substring(0, index + 1);
|
||||
String parentUrl = "https://135zyv5.xw0371.com/2018/10/29/X05c7CG3VB91gi1M/";
|
||||
//String parentUrl = "https://v1.szjal.cn/20190819/Ql6UD1od/";
|
||||
//String parentUrl = "http://" + uri.getHost() + "/";
|
||||
List<String> newUrls = new ArrayList<>();
|
||||
for (String url : tsUrls) {
|
||||
|
||||
@@ -34,13 +34,13 @@ public class M3U8VodModule extends BaseViewModule {
|
||||
// m3u8测试集合:http://www.voidcn.com/article/p-snaliarm-ct.html
|
||||
//private final String defUrl = "https://www.gaoya123.cn/2019/1557993797897.m3u8";
|
||||
// 多码率地址:
|
||||
//private final String defUrl = "http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8";
|
||||
private final String defUrl = "http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8";
|
||||
//private final String defUrl = "https://cn7.kankia.com/hls/20200108/e1eaec074274c64fe46a3bdb5d2ba487/1578488360/index.m3u8";
|
||||
//private final String defUrl = "https://youku.cdn7-okzy.com/20191213/16167_c3592a02/index.m3u8";
|
||||
//private final String defUrl = "http://qn.shytong.cn/b83137769ff6b555/11b0c9970f9a3fa0.mp4.m3u8";
|
||||
//private final String defUrl = "https://135zyv5.xw0371.com/2018/10/29/X05c7CG3VB91gi1M/playlist.m3u8";
|
||||
//private final String defUrl = "https://fangao.qfxmj.com/video/20191111/dbf7e2aa0c5f42a8b040442b54c13e3a/cloudv-transfer/555555556nr593o75556r165q86n82n0_eb3da35b8f4442808756a6ddc8ec1372_0_3.m3u8?wsSecret=d5fb403512d4cd427f18858086b35ce4&wsTime=1582197537";
|
||||
private final String defUrl = "https://v1.szjal.cn/20190819/Ql6UD1od/index.m3u8";
|
||||
//private final String defUrl = "https://v1.szjal.cn/20190819/Ql6UD1od/index.m3u8";
|
||||
private final String filePath =
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath()
|
||||
//+ "/道士下山.ts";
|
||||
|
||||
@@ -94,7 +94,7 @@ public class FtpUploadActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
}
|
||||
|
||||
@Override public void cancel(View v, AbsEntity entity) {
|
||||
Aria.upload(this).loadFtp(mTaskId).cancel(false);
|
||||
Aria.upload(this).loadFtp(mTaskId).cancel(true);
|
||||
mTaskId = -1;
|
||||
}
|
||||
});
|
||||
@@ -135,7 +135,7 @@ public class FtpUploadActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
|
||||
@Upload.onWait
|
||||
void onWait(UploadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
if (task.getEntity().getUrl().equals(mUrl)) {
|
||||
Log.d(TAG, "wait ==> " + task.getEntity().getFileName());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
@@ -143,14 +143,14 @@ public class FtpUploadActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
|
||||
@Upload.onPre
|
||||
protected void onPre(UploadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
if (task.getEntity().getUrl().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onTaskStart
|
||||
void taskStart(UploadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
if (task.getEntity().getUrl().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
ALog.d(TAG, "isComplete = " + task.isComplete() + ", state = " + task.getState());
|
||||
}
|
||||
@@ -158,7 +158,7 @@ public class FtpUploadActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
|
||||
@Upload.onTaskRunning
|
||||
protected void running(UploadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
if (task.getEntity().getUrl().equals(mUrl)) {
|
||||
ALog.d(TAG, "isRunning" + "; state = " + task.getEntity().getState());
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
@@ -166,7 +166,8 @@ public class FtpUploadActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
|
||||
@Upload.onTaskResume
|
||||
void taskResume(UploadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
if (task.getEntity().getUrl().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
ALog.d(TAG, "resume");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
@@ -174,7 +175,7 @@ public class FtpUploadActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
|
||||
@Upload.onTaskStop
|
||||
void taskStop(UploadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
if (task.getEntity().getUrl().equals(mUrl)) {
|
||||
ALog.d(TAG, "stop");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
@@ -182,7 +183,7 @@ public class FtpUploadActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
|
||||
@Upload.onTaskCancel
|
||||
void taskCancel(UploadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
if (task.getEntity().getUrl().equals(mUrl)) {
|
||||
mTaskId = -1;
|
||||
Log.d(TAG, "cancel");
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
@@ -192,17 +193,17 @@ public class FtpUploadActivity extends BaseActivity<ActivitySingleBinding> {
|
||||
@Upload.onTaskFail
|
||||
void taskFail(UploadTask task, Exception e) {
|
||||
ALog.d(TAG, "fail");
|
||||
Toast.makeText(this, getString(R.string.download_fail), Toast.LENGTH_SHORT)
|
||||
Toast.makeText(this, getString(R.string.upload_fail), Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
if (task != null && task.getKey().equals(mUrl)) {
|
||||
if (task != null && task.getEntity().getUrl().equals(mUrl)) {
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Upload.onTaskComplete
|
||||
void taskComplete(UploadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Toast.makeText(this, getString(R.string.download_success),
|
||||
if (task.getEntity().getUrl().equals(mUrl)) {
|
||||
Toast.makeText(this, getString(R.string.upload_success),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
ALog.d(TAG, "md5: " + CommonUtil.getFileMD5(new File(task.getEntity().getFilePath())));
|
||||
getBinding().pl.setInfo(task.getEntity());
|
||||
|
||||
@@ -38,7 +38,7 @@ public class UploadModule extends BaseViewModule {
|
||||
//String url = AppUtil.getConfigValue(context, FTP_URL_KEY, "ftp://9.9.9.72:2121/aab/你好");
|
||||
//String filePath = AppUtil.getConfigValue(context, FTP_PATH_KEY,
|
||||
// Environment.getExternalStorageDirectory().getPath() + "/Download/AndroidAria.db");
|
||||
String url = "ftp://9.9.9.72:2121/aab/你好";
|
||||
String url = "ftp://192.168.0.105:2121/aab/你好";
|
||||
String filePath = "/mnt/sdcard/QQMusic-import-1.2.1.zip";
|
||||
|
||||
UploadEntity entity = Aria.upload(context).getFirstUploadEntity(filePath);
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
<string name="completed">已完成</string>
|
||||
<string name="code_simple">代码示例:</string>
|
||||
<string name="download_success">下载完成</string>
|
||||
<string name="upload_success">上传完成</string>
|
||||
<string name="download_fail">下载失败</string>
|
||||
<string name="upload_fail">上传失败</string>
|
||||
<string name="re_start">重新开始</string>
|
||||
<string name="choose_current_dir">选择当前文件夹</string>
|
||||
<string name="choose_dir">选择文件夹</string>
|
||||
|
||||
@@ -45,7 +45,7 @@ task clean(type: Delete) {
|
||||
|
||||
ext {
|
||||
versionCode = 387
|
||||
versionName = '3.8.7-beta-8'
|
||||
versionName = '3.8.7-beta-11'
|
||||
userOrg = 'arialyy'
|
||||
groupId = 'com.arialyy.aria'
|
||||
publishVersion = versionName
|
||||
|
||||
Reference in New Issue
Block a user