fix bug https://github.com/AriaLyy/Aria/issues/542
fix bug https://github.com/AriaLyy/Aria/issues/547
修复下载失败时,中断重试无效的问题
增加忽略权限检查的api,`ignoreCheckPermissions()`
pull/617/head
laoyuyu 5 years ago
parent 91daecd039
commit 669aa6981c
  1. 10
      Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
  2. 3
      Aria/src/main/java/com/arialyy/aria/core/command/HighestPriorityCmd.java
  3. 4
      Aria/src/main/java/com/arialyy/aria/core/command/ResumeAllCmd.java
  4. 11
      Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java
  5. 10
      Aria/src/main/java/com/arialyy/aria/core/common/AbsBuilderTarget.java
  6. 8
      Aria/src/main/java/com/arialyy/aria/core/common/AbsNormalTarget.java
  7. 29
      Aria/src/main/java/com/arialyy/aria/core/common/controller/FeatureController.java
  8. 4
      Aria/src/main/java/com/arialyy/aria/core/download/CheckDEntityUtil.java
  9. 3
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java
  10. 8
      Aria/src/main/java/com/arialyy/aria/core/queue/DGroupTaskQueue.java
  11. 10
      Aria/src/main/java/com/arialyy/aria/core/queue/DTaskQueue.java
  12. 5
      Aria/src/main/java/com/arialyy/aria/core/queue/UTaskQueue.java
  13. 3
      Aria/src/main/java/com/arialyy/aria/core/queue/pool/DGLoadExecutePool.java
  14. 4
      Aria/src/main/java/com/arialyy/aria/core/queue/pool/DLoadExecutePool.java
  15. 4
      Aria/src/main/java/com/arialyy/aria/core/queue/pool/UploadExecutePool.java
  16. 25
      Aria/src/main/java/com/arialyy/aria/core/scheduler/FailureTaskHandler.java
  17. 28
      Aria/src/main/java/com/arialyy/aria/core/scheduler/TaskSchedulers.java
  18. 3
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadReceiver.java
  19. 6
      DEV_LOG.md
  20. 10
      FtpComponent/src/main/java/com/arialyy/aria/ftp/upload/FtpUThreadTaskAdapter.java
  21. 4
      M3U8Component/src/main/java/com/arialyy/aria/m3u8/BaseM3U8Loader.java
  22. 3
      M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8RecordAdapter.java
  23. 10
      PublicComponent/src/main/java/com/arialyy/aria/core/AriaConfig.java
  24. 55
      PublicComponent/src/main/java/com/arialyy/aria/core/listener/UploadListener.java
  25. 2
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/ThreadStateManager.java
  26. 17
      PublicComponent/src/main/java/com/arialyy/aria/core/task/ThreadTask.java
  27. 4
      PublicComponent/src/main/java/com/arialyy/aria/orm/DBConfig.java
  28. 18
      PublicComponent/src/main/java/com/arialyy/aria/orm/DelegateCommon.java
  29. 83
      PublicComponent/src/main/java/com/arialyy/aria/orm/SqlHelper.java
  30. 2
      PublicComponent/src/main/java/com/arialyy/aria/util/CheckUtil.java
  31. 43
      PublicComponent/src/main/java/com/arialyy/aria/util/FileUtil.java
  32. 11
      app/src/main/java/com/arialyy/simple/core/download/HttpDownloadModule.java
  33. 8
      app/src/main/java/com/arialyy/simple/core/download/SingleTaskActivity.java
  34. 4
      app/src/main/java/com/arialyy/simple/core/upload/UploadModule.java
  35. 4
      build.gradle
  36. 15
      py/.vscode/launch.json
  37. 6
      py/.vscode/settings.json
  38. BIN
      test/347/AndroidAria.db

@ -23,8 +23,6 @@ import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.widget.PopupWindow; import android.widget.PopupWindow;
import com.arialyy.aria.core.command.CommandManager; import com.arialyy.aria.core.command.CommandManager;
import com.arialyy.aria.core.common.QueueMod; import com.arialyy.aria.core.common.QueueMod;
@ -76,7 +74,6 @@ import java.util.concurrent.ConcurrentHashMap;
*/ */
private Map<String, List<String>> mSubClass = new ConcurrentHashMap<>(); private Map<String, List<String>> mSubClass = new ConcurrentHashMap<>();
private static Context APP; private static Context APP;
private Handler mAriaHandler;
private DelegateWrapper mDbWrapper; private DelegateWrapper mDbWrapper;
private AriaConfig mConfig; private AriaConfig mConfig;
@ -168,13 +165,6 @@ import java.util.concurrent.ConcurrentHashMap;
} }
} }
public synchronized Handler getAriaHandler() {
if (mAriaHandler == null) {
mAriaHandler = new Handler(Looper.getMainLooper());
}
return mAriaHandler;
}
public Map<String, AbsReceiver> getReceiver() { public Map<String, AbsReceiver> getReceiver() {
return mReceivers; return mReceivers;
} }

@ -15,6 +15,7 @@
*/ */
package com.arialyy.aria.core.command; package com.arialyy.aria.core.command;
import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.task.DownloadTask; import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper; import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
@ -41,7 +42,7 @@ final class HighestPriorityCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T>
@Override public void executeCmd() { @Override public void executeCmd() {
if (!canExeCmd) return; if (!canExeCmd) return;
if (!NetUtils.isConnected(AriaManager.getInstance().getAPP())){ if (!NetUtils.isConnected(AriaConfig.getInstance().getAPP())){
ALog.e(TAG, "启动任务失败,网络未连接"); ALog.e(TAG, "启动任务失败,网络未连接");
return; return;
} }

@ -15,7 +15,7 @@
*/ */
package com.arialyy.aria.core.command; package com.arialyy.aria.core.command;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper; import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
@ -36,7 +36,7 @@ final class ResumeAllCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
} }
@Override public void executeCmd() { @Override public void executeCmd() {
if (!NetUtils.isConnected(AriaManager.getInstance().getAPP())) { if (!NetUtils.isConnected(AriaConfig.getInstance().getAPP())) {
ALog.w(TAG, "恢复任务失败,网络未连接"); ALog.w(TAG, "恢复任务失败,网络未连接");
return; return;
} }

@ -16,7 +16,7 @@
package com.arialyy.aria.core.command; package com.arialyy.aria.core.command;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.common.QueueMod; import com.arialyy.aria.core.common.QueueMod;
import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.task.AbsTask; import com.arialyy.aria.core.task.AbsTask;
@ -37,6 +37,7 @@ final public class StartCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
/** /**
* 立即执行任务 * 立即执行任务
*
* @param newStart true 立即执行任务无论执行队列是否满了 * @param newStart true 立即执行任务无论执行队列是否满了
*/ */
public void setNewStart(boolean newStart) { public void setNewStart(boolean newStart) {
@ -45,17 +46,17 @@ final public class StartCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
@Override public void executeCmd() { @Override public void executeCmd() {
if (!canExeCmd) return; if (!canExeCmd) return;
if (!NetUtils.isConnected(AriaManager.getInstance().getAPP())) { if (!NetUtils.isConnected(AriaConfig.getInstance().getAPP())) {
ALog.e(TAG, "启动任务失败,网络未连接"); ALog.e(TAG, "启动任务失败,网络未连接");
return; return;
} }
String mod; String mod;
int maxTaskNum = mQueue.getMaxTaskNum(); int maxTaskNum = mQueue.getMaxTaskNum();
AriaManager manager = AriaManager.getInstance(); AriaConfig config = AriaConfig.getInstance();
if (isDownloadCmd) { if (isDownloadCmd) {
mod = manager.getDownloadConfig().getQueueMod(); mod = config.getDConfig().getQueueMod();
} else { } else {
mod = manager.getUploadConfig().getQueueMod(); mod = config.getUConfig().getQueueMod();
} }
AbsTask task = getTask(); AbsTask task = getTask();

@ -15,8 +15,8 @@
*/ */
package com.arialyy.aria.core.common; package com.arialyy.aria.core.common;
import com.arialyy.aria.core.common.controller.IStartFeature;
import com.arialyy.aria.core.common.controller.BuilderController; import com.arialyy.aria.core.common.controller.BuilderController;
import com.arialyy.aria.core.common.controller.IStartFeature;
import com.arialyy.aria.core.inf.AbsTarget; import com.arialyy.aria.core.inf.AbsTarget;
/** /**
@ -34,6 +34,14 @@ public abstract class AbsBuilderTarget<TARGET extends AbsBuilderTarget> extends
return mStartController; return mStartController;
} }
/**
* 是否忽略权限检查
*/
public TARGET ignoreCheckPermissions() {
getController().ignoreCheckPermissions();
return (TARGET) this;
}
/** /**
* 添加任务 * 添加任务
* *

@ -31,6 +31,14 @@ import com.arialyy.aria.util.RecordUtil;
public abstract class AbsNormalTarget<TARGET extends AbsNormalTarget> extends AbsTarget<TARGET> public abstract class AbsNormalTarget<TARGET extends AbsNormalTarget> extends AbsTarget<TARGET>
implements INormalFeature { implements INormalFeature {
/**
* 是否忽略权限检查
*/
public TARGET ignoreCheckPermissions() {
getController().ignoreCheckPermissions();
return (TARGET) this;
}
/** /**
* 任务是否在执行 * 任务是否在执行
* *

@ -19,21 +19,21 @@ import android.Manifest;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.download.CheckDEntityUtil; import com.arialyy.aria.core.download.CheckDEntityUtil;
import com.arialyy.aria.core.download.CheckDGEntityUtil; import com.arialyy.aria.core.download.CheckDGEntityUtil;
import com.arialyy.aria.core.download.CheckFtpDirEntityUtil; import com.arialyy.aria.core.download.CheckFtpDirEntityUtil;
import com.arialyy.aria.core.download.DGTaskWrapper; import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.aria.core.download.DTaskWrapper; import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.inf.ICheckEntityUtil; import com.arialyy.aria.core.inf.ICheckEntityUtil;
import com.arialyy.aria.core.task.ITask;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.core.listener.ISchedulers; import com.arialyy.aria.core.listener.ISchedulers;
import com.arialyy.aria.core.scheduler.TaskSchedulers; import com.arialyy.aria.core.scheduler.TaskSchedulers;
import com.arialyy.aria.core.task.ITask;
import com.arialyy.aria.core.upload.CheckUEntityUtil; import com.arialyy.aria.core.upload.CheckUEntityUtil;
import com.arialyy.aria.core.upload.UTaskWrapper; import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
@ -46,6 +46,10 @@ public abstract class FeatureController {
private final String TAG; private final String TAG;
private AbsTaskWrapper mTaskWrapper; private AbsTaskWrapper mTaskWrapper;
/**
* 是否忽略权限检查 true 忽略权限检查
*/
private boolean ignoreCheckPermissions = false;
FeatureController(AbsTaskWrapper wrapper) { FeatureController(AbsTaskWrapper wrapper) {
mTaskWrapper = wrapper; mTaskWrapper = wrapper;
@ -87,6 +91,13 @@ public abstract class FeatureController {
return null; return null;
} }
/**
* 是否忽略权限检查
*/
public void ignoreCheckPermissions() {
this.ignoreCheckPermissions = true;
}
protected AbsTaskWrapper getTaskWrapper() { protected AbsTaskWrapper getTaskWrapper() {
return mTaskWrapper; return mTaskWrapper;
} }
@ -111,7 +122,7 @@ public abstract class FeatureController {
* 如果检查实体失败将错误回调 * 如果检查实体失败将错误回调
*/ */
boolean checkConfig() { boolean checkConfig() {
if (!checkPermission()) { if (!ignoreCheckPermissions && !checkPermission()) {
return false; return false;
} }
boolean b = checkEntity(); boolean b = checkEntity();
@ -134,21 +145,21 @@ public abstract class FeatureController {
*/ */
private boolean checkPermission() { private boolean checkPermission() {
if (AriaManager.getInstance() if (AriaConfig.getInstance()
.getAPP() .getAPP()
.checkCallingOrSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) .checkCallingOrSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) { != PackageManager.PERMISSION_GRANTED) {
ALog.e(TAG, "启动失败,缺少权限:Manifest.permission.WRITE_EXTERNAL_STORAGE"); ALog.e(TAG, "启动失败,缺少权限:Manifest.permission.WRITE_EXTERNAL_STORAGE");
return false; return false;
} }
if (AriaManager.getInstance() if (AriaConfig.getInstance()
.getAPP() .getAPP()
.checkCallingOrSelfPermission(Manifest.permission.INTERNET) .checkCallingOrSelfPermission(Manifest.permission.INTERNET)
!= PackageManager.PERMISSION_GRANTED) { != PackageManager.PERMISSION_GRANTED) {
ALog.e(TAG, "启动失败,缺少权限:Manifest.permission.INTERNET"); ALog.e(TAG, "启动失败,缺少权限:Manifest.permission.INTERNET");
return false; return false;
} }
if (AriaManager.getInstance() if (AriaConfig.getInstance()
.getAPP() .getAPP()
.checkCallingOrSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) .checkCallingOrSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) { != PackageManager.PERMISSION_GRANTED) {

@ -23,6 +23,7 @@ import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CheckUtil; import com.arialyy.aria.util.CheckUtil;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.util.FileUtil;
import com.arialyy.aria.util.RecordUtil; import com.arialyy.aria.util.RecordUtil;
import java.io.File; import java.io.File;
@ -65,8 +66,7 @@ public class CheckDEntityUtil implements ICheckEntityUtil {
File file = new File(mWrapper.getTempFilePath()); File file = new File(mWrapper.getTempFilePath());
Object bw = mWrapper.getM3U8Params().getParam(IOptionConstant.bandWidth); Object bw = mWrapper.getM3U8Params().getParam(IOptionConstant.bandWidth);
int bandWidth = bw == null ? 0 : (int) bw; int bandWidth = bw == null ? 0 : (int) bw;
// 缓存文件夹格式:问文件夹/.文件名_码率 String cacheDir = FileUtil.getTsCacheDir(file.getPath(), bandWidth);
String cacheDir = String.format("%s/.%s_%s", file.getParent(), file.getName(), bandWidth);
mWrapper.getM3U8Params().setParams(IOptionConstant.cacheDir, cacheDir); mWrapper.getM3U8Params().setParams(IOptionConstant.cacheDir, cacheDir);
M3U8Entity m3U8Entity = mEntity.getM3U8Entity(); M3U8Entity m3U8Entity = mEntity.getM3U8Entity();

@ -18,6 +18,7 @@ package com.arialyy.aria.core.download;
import androidx.annotation.CheckResult; import androidx.annotation.CheckResult;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.arialyy.annotations.TaskEnum; import com.arialyy.annotations.TaskEnum;
import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.command.CancelAllCmd; import com.arialyy.aria.core.command.CancelAllCmd;
import com.arialyy.aria.core.command.CmdHelper; import com.arialyy.aria.core.command.CmdHelper;
@ -64,7 +65,7 @@ public class DownloadReceiver extends AbsReceiver {
*/ */
@Deprecated @Deprecated
public DownloadReceiver setMaxSpeed(int maxSpeed) { public DownloadReceiver setMaxSpeed(int maxSpeed) {
AriaManager.getInstance().getDownloadConfig().setMaxSpeed(maxSpeed); AriaConfig.getInstance().getDConfig().setMaxSpeed(maxSpeed);
return this; return this;
} }

@ -16,13 +16,13 @@
package com.arialyy.aria.core.queue; package com.arialyy.aria.core.queue;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.download.DGTaskWrapper; import com.arialyy.aria.core.download.DGTaskWrapper;
import com.arialyy.aria.core.task.DownloadGroupTask;
import com.arialyy.aria.core.event.DGMaxNumEvent; import com.arialyy.aria.core.event.DGMaxNumEvent;
import com.arialyy.aria.core.event.Event; import com.arialyy.aria.core.event.Event;
import com.arialyy.aria.core.event.EventMsgUtil; import com.arialyy.aria.core.event.EventMsgUtil;
import com.arialyy.aria.core.scheduler.TaskSchedulers; import com.arialyy.aria.core.scheduler.TaskSchedulers;
import com.arialyy.aria.core.task.DownloadGroupTask;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
/** /**
@ -57,7 +57,7 @@ public class DGroupTaskQueue
} }
@Override public int getMaxTaskNum() { @Override public int getMaxTaskNum() {
return AriaManager.getInstance().getDGroupConfig().getMaxTaskNum(); return AriaConfig.getInstance().getDConfig().getMaxTaskNum();
} }
@Override public DownloadGroupTask createTask(DGTaskWrapper wrapper) { @Override public DownloadGroupTask createTask(DGTaskWrapper wrapper) {
@ -74,6 +74,6 @@ public class DGroupTaskQueue
} }
@Override public int getOldMaxNum() { @Override public int getOldMaxNum() {
return AriaManager.getInstance().getDGroupConfig().oldMaxTaskNum; return AriaConfig.getInstance().getDGConfig().oldMaxTaskNum;
} }
} }

@ -16,14 +16,14 @@
package com.arialyy.aria.core.queue; package com.arialyy.aria.core.queue;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.download.DTaskWrapper; import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.core.event.DMaxNumEvent; import com.arialyy.aria.core.event.DMaxNumEvent;
import com.arialyy.aria.core.event.Event; import com.arialyy.aria.core.event.Event;
import com.arialyy.aria.core.event.EventMsgUtil; import com.arialyy.aria.core.event.EventMsgUtil;
import com.arialyy.aria.core.inf.TaskSchedulerType; import com.arialyy.aria.core.inf.TaskSchedulerType;
import com.arialyy.aria.core.scheduler.TaskSchedulers; import com.arialyy.aria.core.scheduler.TaskSchedulers;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Map; import java.util.Map;
@ -60,7 +60,7 @@ public class DTaskQueue extends AbsTaskQueue<DownloadTask, DTaskWrapper> {
} }
@Override public int getOldMaxNum() { @Override public int getOldMaxNum() {
return AriaManager.getInstance().getDownloadConfig().oldMaxTaskNum; return AriaConfig.getInstance().getDConfig().oldMaxTaskNum;
} }
/** /**
@ -81,7 +81,7 @@ public class DTaskQueue extends AbsTaskQueue<DownloadTask, DTaskWrapper> {
} }
} }
} }
int maxSize = AriaManager.getInstance().getDownloadConfig().getMaxTaskNum(); int maxSize = AriaConfig.getInstance().getDConfig().getMaxTaskNum();
int currentSize = mExecutePool.size(); int currentSize = mExecutePool.size();
if (currentSize == 0 || currentSize < maxSize) { if (currentSize == 0 || currentSize < maxSize) {
startTask(task); startTask(task);
@ -126,6 +126,6 @@ public class DTaskQueue extends AbsTaskQueue<DownloadTask, DTaskWrapper> {
} }
@Override public int getMaxTaskNum() { @Override public int getMaxTaskNum() {
return AriaManager.getInstance().getDownloadConfig().getMaxTaskNum(); return AriaConfig.getInstance().getDConfig().getMaxTaskNum();
} }
} }

@ -16,6 +16,7 @@
package com.arialyy.aria.core.queue; package com.arialyy.aria.core.queue;
import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.event.Event; import com.arialyy.aria.core.event.Event;
import com.arialyy.aria.core.event.EventMsgUtil; import com.arialyy.aria.core.event.EventMsgUtil;
@ -55,11 +56,11 @@ public class UTaskQueue extends AbsTaskQueue<UploadTask, UTaskWrapper> {
} }
@Override public int getOldMaxNum() { @Override public int getOldMaxNum() {
return AriaManager.getInstance().getUploadConfig().oldMaxTaskNum; return AriaConfig.getInstance().getUConfig().oldMaxTaskNum;
} }
@Override public int getMaxTaskNum() { @Override public int getMaxTaskNum() {
return AriaManager.getInstance().getUploadConfig().getMaxTaskNum(); return AriaConfig.getInstance().getUConfig().getMaxTaskNum();
} }
@Override public UploadTask createTask(UTaskWrapper wrapper) { @Override public UploadTask createTask(UTaskWrapper wrapper) {

@ -15,6 +15,7 @@
*/ */
package com.arialyy.aria.core.queue.pool; package com.arialyy.aria.core.queue.pool;
import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.task.AbsTask; import com.arialyy.aria.core.task.AbsTask;
@ -26,6 +27,6 @@ class DGLoadExecutePool<TASK extends AbsTask> extends DLoadExecutePool<TASK> {
private final String TAG = "DGLoadExecutePool"; private final String TAG = "DGLoadExecutePool";
@Override protected int getMaxSize() { @Override protected int getMaxSize() {
return AriaManager.getInstance().getDGroupConfig().getMaxTaskNum(); return AriaConfig.getInstance().getDGConfig().getMaxTaskNum();
} }
} }

@ -15,7 +15,7 @@
*/ */
package com.arialyy.aria.core.queue.pool; package com.arialyy.aria.core.queue.pool;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.task.AbsTask; import com.arialyy.aria.core.task.AbsTask;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
@ -30,7 +30,7 @@ class DLoadExecutePool<TASK extends AbsTask> extends BaseExecutePool<TASK> {
private final String TAG = "DownloadExecutePool"; private final String TAG = "DownloadExecutePool";
@Override protected int getMaxSize() { @Override protected int getMaxSize() {
return AriaManager.getInstance().getDownloadConfig().getMaxTaskNum(); return AriaConfig.getInstance().getDConfig().getMaxTaskNum();
} }
@Override public boolean putTask(TASK task) { @Override public boolean putTask(TASK task) {

@ -15,7 +15,7 @@
*/ */
package com.arialyy.aria.core.queue.pool; package com.arialyy.aria.core.queue.pool;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.task.AbsTask; import com.arialyy.aria.core.task.AbsTask;
/** /**
@ -23,6 +23,6 @@ import com.arialyy.aria.core.task.AbsTask;
*/ */
public class UploadExecutePool<TASK extends AbsTask> extends BaseExecutePool<TASK> { public class UploadExecutePool<TASK extends AbsTask> extends BaseExecutePool<TASK> {
@Override protected int getMaxSize() { @Override protected int getMaxSize() {
return AriaManager.getInstance().getUploadConfig().getMaxTaskNum(); return AriaConfig.getInstance().getUConfig().getMaxTaskNum();
} }
} }

@ -15,11 +15,11 @@
*/ */
package com.arialyy.aria.core.scheduler; package com.arialyy.aria.core.scheduler;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.common.AbsEntity; import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.task.ITask;
import com.arialyy.aria.core.manager.TaskWrapperManager; import com.arialyy.aria.core.manager.TaskWrapperManager;
import com.arialyy.aria.core.queue.ITaskQueue; import com.arialyy.aria.core.queue.ITaskQueue;
import com.arialyy.aria.core.task.ITask;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import java.util.ArrayList; import java.util.ArrayList;
@ -42,7 +42,6 @@ class FailureTaskHandler<TASK extends ITask> {
private TaskSchedulers mSchedulers; private TaskSchedulers mSchedulers;
private final ReentrantLock LOCK = new ReentrantLock(); private final ReentrantLock LOCK = new ReentrantLock();
private Condition mCondition = LOCK.newCondition(); private Condition mCondition = LOCK.newCondition();
private AriaManager mAriaManager;
static FailureTaskHandler init(TaskSchedulers schedulers) { static FailureTaskHandler init(TaskSchedulers schedulers) {
if (INSTANCE == null) { if (INSTANCE == null) {
@ -57,7 +56,6 @@ class FailureTaskHandler<TASK extends ITask> {
private FailureTaskHandler(TaskSchedulers schedulers) { private FailureTaskHandler(TaskSchedulers schedulers) {
mSchedulers = schedulers; mSchedulers = schedulers;
mAriaManager = AriaManager.getInstance();
new Thread(new Runnable() { new Thread(new Runnable() {
@Override public void run() { @Override public void run() {
while (true) { while (true) {
@ -82,10 +80,11 @@ class FailureTaskHandler<TASK extends ITask> {
} }
private void retryTask(final TASK task) { private void retryTask(final TASK task) {
final ITaskQueue queue = mSchedulers.getQueue(task.getTaskType());
if (task.isNeedRetry()){
long interval = task.getTaskWrapper().getConfig().getReTryInterval(); long interval = task.getTaskWrapper().getConfig().getReTryInterval();
final int num = task.getTaskWrapper().getConfig().getReTryNum(); final int num = task.getTaskWrapper().getConfig().getReTryNum();
final ITaskQueue queue = mSchedulers.getQueue(task.getTaskType()); AriaConfig.getInstance().getAriaHandler().postDelayed(new Runnable() {
mAriaManager.getAriaHandler().postDelayed(new Runnable() {
@Override public void run() { @Override public void run() {
AbsEntity entity = task.getTaskWrapper().getEntity(); AbsEntity entity = task.getTaskWrapper().getEntity();
if (entity.getFailNum() <= num) { if (entity.getFailNum() <= num) {
@ -96,6 +95,18 @@ class FailureTaskHandler<TASK extends ITask> {
mSchedulers.startNextTask(queue, task.getSchedulerType()); mSchedulers.startNextTask(queue, task.getSchedulerType());
TaskWrapperManager.getInstance().removeTaskWrapper(task.getTaskWrapper()); TaskWrapperManager.getInstance().removeTaskWrapper(task.getTaskWrapper());
} }
next(task);
}
}, interval);
}else {
queue.removeTaskFormQueue(task.getKey());
mSchedulers.startNextTask(queue, task.getSchedulerType());
TaskWrapperManager.getInstance().removeTaskWrapper(task.getTaskWrapper());
next(task);
}
}
private void next(TASK task){
mExeQueue.remove(task); mExeQueue.remove(task);
int index = mHashList.indexOf(task.hashCode()); int index = mHashList.indexOf(task.hashCode());
if (index != -1) { if (index != -1) {
@ -110,8 +121,6 @@ class FailureTaskHandler<TASK extends ITask> {
} }
} }
} }
}, interval);
}
void offer(TASK task) { void offer(TASK task) {
int hashCode = task.hashCode(); int hashCode = task.hashCode();

@ -19,7 +19,7 @@ import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Message; import android.os.Message;
import com.arialyy.annotations.TaskEnum; import com.arialyy.annotations.TaskEnum;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.common.AbsEntity; import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.common.AbsNormalEntity; import com.arialyy.aria.core.common.AbsNormalEntity;
import com.arialyy.aria.core.group.GroupSendParams; import com.arialyy.aria.core.group.GroupSendParams;
@ -53,10 +53,10 @@ public class TaskSchedulers<TASK extends ITask> implements ISchedulers {
private static FailureTaskHandler mFailureTaskHandler; private static FailureTaskHandler mFailureTaskHandler;
private Map<String, Map<TaskEnum, ISchedulerListener>> mObservers = new ConcurrentHashMap<>(); private Map<String, Map<TaskEnum, ISchedulerListener>> mObservers = new ConcurrentHashMap<>();
private AriaManager mAriaManager; private AriaConfig mAriaConfig;
private TaskSchedulers() { private TaskSchedulers() {
mAriaManager = AriaManager.getInstance(); mAriaConfig = AriaConfig.getInstance();
} }
public static TaskSchedulers getInstance() { public static TaskSchedulers getInstance() {
@ -230,11 +230,11 @@ public class TaskSchedulers<TASK extends ITask> implements ISchedulers {
} }
} }
boolean canSend = mAriaManager.getAppConfig().isUseBroadcast(); boolean canSend = mAriaConfig.getAConfig().isUseBroadcast();
if (canSend) { if (canSend) {
Intent intent = new Intent(ISchedulers.ARIA_TASK_INFO_ACTION); Intent intent = new Intent(ISchedulers.ARIA_TASK_INFO_ACTION);
intent.putExtras(data); intent.putExtras(data);
mAriaManager.getAPP().sendBroadcast(intent); mAriaConfig.getAPP().sendBroadcast(intent);
} }
return true; return true;
@ -284,9 +284,9 @@ public class TaskSchedulers<TASK extends ITask> implements ISchedulers {
} }
} }
boolean canSend = mAriaManager.getAppConfig().isUseBroadcast(); boolean canSend = mAriaConfig.getAConfig().isUseBroadcast();
if (canSend) { if (canSend) {
mAriaManager.getAPP().sendBroadcast( mAriaConfig.getAPP().sendBroadcast(
createData(msg.what, ITask.DOWNLOAD_GROUP_SUB, params.entity)); createData(msg.what, ITask.DOWNLOAD_GROUP_SUB, params.entity));
} }
@ -353,13 +353,13 @@ public class TaskSchedulers<TASK extends ITask> implements ISchedulers {
startNextTask(getQueue(taskType), TaskSchedulerType.TYPE_DEFAULT); startNextTask(getQueue(taskType), TaskSchedulerType.TYPE_DEFAULT);
// 发送广播 // 发送广播
boolean canSend = mAriaManager.getAppConfig().isUseBroadcast(); boolean canSend = mAriaConfig.getAConfig().isUseBroadcast();
if (canSend) { if (canSend) {
Intent intent = new Intent(ISchedulers.ARIA_TASK_INFO_ACTION); Intent intent = new Intent(ISchedulers.ARIA_TASK_INFO_ACTION);
Bundle b = new Bundle(); Bundle b = new Bundle();
b.putInt(ISchedulers.TASK_TYPE, taskType); b.putInt(ISchedulers.TASK_TYPE, taskType);
b.putInt(ISchedulers.TASK_STATE, ISchedulers.FAIL); b.putInt(ISchedulers.TASK_STATE, ISchedulers.FAIL);
mAriaManager.getAPP().sendBroadcast(intent); mAriaConfig.getAPP().sendBroadcast(intent);
} }
// 处理回调 // 处理回调
@ -470,16 +470,16 @@ public class TaskSchedulers<TASK extends ITask> implements ISchedulers {
* 发送普通任务的广播 * 发送普通任务的广播
*/ */
private void sendNormalBroadcast(int state, TASK task) { private void sendNormalBroadcast(int state, TASK task) {
boolean canSend = mAriaManager.getAppConfig().isUseBroadcast(); boolean canSend = mAriaConfig.getAConfig().isUseBroadcast();
if (!canSend) { if (!canSend) {
return; return;
} }
int type = task.getTaskType(); int type = task.getTaskType();
if (type == ITask.DOWNLOAD || type == ITask.DOWNLOAD_GROUP) { if (type == ITask.DOWNLOAD || type == ITask.DOWNLOAD_GROUP) {
mAriaManager.getAPP().sendBroadcast( mAriaConfig.getAPP().sendBroadcast(
createData(state, type, task.getTaskWrapper().getEntity())); createData(state, type, task.getTaskWrapper().getEntity()));
} else if (type == ITask.UPLOAD) { } else if (type == ITask.UPLOAD) {
mAriaManager.getAPP().sendBroadcast( mAriaConfig.getAPP().sendBroadcast(
createData(state, type, task.getTaskWrapper().getEntity())); createData(state, type, task.getTaskWrapper().getEntity()));
} else { } else {
ALog.w(TAG, "发送广播失败,没有对应的任务"); ALog.w(TAG, "发送广播失败,没有对应的任务");
@ -519,9 +519,9 @@ public class TaskSchedulers<TASK extends ITask> implements ISchedulers {
} }
int num = task.getTaskWrapper().getConfig().getReTryNum(); int num = task.getTaskWrapper().getConfig().getReTryNum();
boolean isNotNetRetry = mAriaManager.getAppConfig().isNotNetRetry(); boolean isNotNetRetry = mAriaConfig.getAConfig().isNotNetRetry();
if ((!NetUtils.isConnected(mAriaManager.getAPP()) && !isNotNetRetry) if ((!NetUtils.isConnected(mAriaConfig.getAPP()) && !isNotNetRetry)
|| task.getTaskWrapper().getEntity().getFailNum() > num) { || task.getTaskWrapper().getEntity().getFailNum() > num) {
queue.removeTaskFormQueue(task.getKey()); queue.removeTaskFormQueue(task.getKey());
startNextTask(queue, task.getSchedulerType()); startNextTask(queue, task.getSchedulerType());

@ -19,6 +19,7 @@ import android.text.TextUtils;
import androidx.annotation.CheckResult; import androidx.annotation.CheckResult;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.arialyy.annotations.TaskEnum; import com.arialyy.annotations.TaskEnum;
import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.command.CancelAllCmd; import com.arialyy.aria.core.command.CancelAllCmd;
import com.arialyy.aria.core.command.CmdHelper; import com.arialyy.aria.core.command.CmdHelper;
@ -58,7 +59,7 @@ public class UploadReceiver extends AbsReceiver {
*/ */
@Deprecated @Deprecated
public UploadReceiver setMaxSpeed(int maxSpeed) { public UploadReceiver setMaxSpeed(int maxSpeed) {
AriaManager.getInstance().getUploadConfig().setMaxSpeed(maxSpeed); AriaConfig.getInstance().getUConfig().setMaxSpeed(maxSpeed);
return this; return this;
} }

@ -1,4 +1,10 @@
## 开发日志 ## 开发日志
+ v_3.7.10
- fix bug https://github.com/AriaLyy/Aria/issues/543#issuecomment-559733124
- fix bug https://github.com/AriaLyy/Aria/issues/542
- fix bug https://github.com/AriaLyy/Aria/issues/547
- 修复下载失败时,中断重试无效的问题
- 增加忽略权限检查的api,`ignoreCheckPermissions()`
+ v_3.7.9 (2019/11/28) + v_3.7.9 (2019/11/28)
- fix bug https://github.com/AriaLyy/Aria/issues/537 - fix bug https://github.com/AriaLyy/Aria/issues/537
+ v_3.7.8 (2019/11/28) + v_3.7.8 (2019/11/28)

@ -33,7 +33,6 @@ import java.io.UnsupportedEncodingException;
* Created by Aria.Lao on 2017/7/28. D_FTP 单线程上传任务需要FTP 服务器给用户打开append和write的权限 * Created by Aria.Lao on 2017/7/28. D_FTP 单线程上传任务需要FTP 服务器给用户打开append和write的权限
*/ */
class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter { class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
private final String TAG = "FtpThreadTask";
private String dir, remotePath; private String dir, remotePath;
FtpUThreadTaskAdapter(SubThreadConfig config) { FtpUThreadTaskAdapter(SubThreadConfig config) {
@ -66,7 +65,8 @@ class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
} }
file = file =
new BufferedRandomAccessFile(getThreadConfig().tempFile, "rwd", getTaskConfig().getBuffSize()); new BufferedRandomAccessFile(getThreadConfig().tempFile, "rwd",
getTaskConfig().getBuffSize());
if (getThreadRecord().startLocation != 0) { if (getThreadRecord().startLocation != 0) {
//file.skipBytes((int) getThreadConfig().START_LOCATION); //file.skipBytes((int) getThreadConfig().START_LOCATION);
file.seek(getThreadRecord().startLocation); file.seek(getThreadRecord().startLocation);
@ -103,10 +103,8 @@ class FtpUThreadTaskAdapter extends BaseFtpThreadTaskAdapter {
private void initPath() throws UnsupportedEncodingException { private void initPath() throws UnsupportedEncodingException {
dir = CommonUtil.convertFtpChar(charSet, mTaskOption.getUrlEntity().remotePath); dir = CommonUtil.convertFtpChar(charSet, mTaskOption.getUrlEntity().remotePath);
String fileName = String fileName = TextUtils.isEmpty(mTaskOption.getNewFileName()) ? getEntity().getFileName()
TextUtils.isEmpty(mTaskOption.getNewFileName()) ? CommonUtil.convertFtpChar(charSet, : mTaskOption.getNewFileName();
getEntity().getFileName())
: CommonUtil.convertFtpChar(charSet, mTaskOption.getNewFileName());
remotePath = remotePath =
CommonUtil.convertFtpChar(charSet, CommonUtil.convertFtpChar(charSet,

@ -15,6 +15,7 @@
*/ */
package com.arialyy.aria.m3u8; package com.arialyy.aria.m3u8;
import android.text.TextUtils;
import com.arialyy.aria.core.common.RecordHandler; import com.arialyy.aria.core.common.RecordHandler;
import com.arialyy.aria.core.download.DTaskWrapper; import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadEntity;
@ -59,6 +60,9 @@ public abstract class BaseM3U8Loader extends AbsLoader {
protected String getCacheDir() { protected String getCacheDir() {
String cacheDir = mM3U8Option.getCacheDir(); String cacheDir = mM3U8Option.getCacheDir();
if (TextUtils.isEmpty(cacheDir)) {
cacheDir = FileUtil.getTsCacheDir(getEntity().getFilePath(), mM3U8Option.getBandWidth());
}
if (!new File(cacheDir).exists()) { if (!new File(cacheDir).exists()) {
FileUtil.createDir(cacheDir); FileUtil.createDir(cacheDir);
} }

@ -131,7 +131,8 @@ public class M3U8RecordAdapter extends AbsRecordHandlerAdapter {
@Override public int initTaskThreadNum() { @Override public int initTaskThreadNum() {
if (getWrapper().getRequestType() == ITaskWrapper.M3U8_VOD) { if (getWrapper().getRequestType() == ITaskWrapper.M3U8_VOD) {
return mOption.getUrls().size(); return
mOption.getUrls() == null || mOption.getUrls().isEmpty() ? 1 : mOption.getUrls().size();
} }
if (getWrapper().getRequestType() == ITaskWrapper.M3U8_LIVE) { if (getWrapper().getRequestType() == ITaskWrapper.M3U8_LIVE) {
return 1; return 1;

@ -23,6 +23,8 @@ import android.net.Network;
import android.net.NetworkCapabilities; import android.net.NetworkCapabilities;
import android.net.NetworkRequest; import android.net.NetworkRequest;
import android.os.Build; import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import com.arialyy.aria.core.config.AppConfig; import com.arialyy.aria.core.config.AppConfig;
import com.arialyy.aria.core.config.Configuration; import com.arialyy.aria.core.config.Configuration;
import com.arialyy.aria.core.config.DGroupConfig; import com.arialyy.aria.core.config.DGroupConfig;
@ -56,6 +58,7 @@ public class AriaConfig {
* 是否已经联网true 已经联网 * 是否已经联网true 已经联网
*/ */
private static boolean isConnectedNet = true; private static boolean isConnectedNet = true;
private Handler mAriaHandler;
private AriaConfig(Context context) { private AriaConfig(Context context) {
APP = context.getApplicationContext(); APP = context.getApplicationContext();
@ -105,6 +108,13 @@ public class AriaConfig {
return mDGConfig; return mDGConfig;
} }
public synchronized Handler getAriaHandler() {
if (mAriaHandler == null) {
mAriaHandler = new Handler(Looper.getMainLooper());
}
return mAriaHandler;
}
/** /**
* 注册网络监听只有配置了检查网络{@link AppConfig#isNetCheck()}才会注册事件 * 注册网络监听只有配置了检查网络{@link AppConfig#isNetCheck()}才会注册事件
*/ */

@ -1,55 +0,0 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.listener;
import com.arialyy.aria.exception.BaseException;
/**
* Created by lyy on 2017/2/23.
*/
class UploadListener implements IUploadListener {
@Override public void onPre() {
}
@Override public void onStart(long startLocation) {
}
@Override public void onResume(long resumeLocation) {
}
@Override public void onStop(long stopLocation) {
}
@Override public void onProgress(long currentLocation) {
}
@Override public void onCancel() {
}
@Override public void onComplete() {
}
@Override public void onFail(boolean needRetry, BaseException e) {
}
}

@ -84,7 +84,7 @@ public class ThreadStateManager implements IThreadState {
mFailNum++; mFailNum++;
if (isFail()) { if (isFail()) {
Bundle b = msg.getData(); Bundle b = msg.getData();
mListener.onFail(b.getBoolean(KEY_RETRY, true), mListener.onFail(b.getBoolean(KEY_RETRY, false),
(BaseException) b.getSerializable(KEY_ERROR_INFO)); (BaseException) b.getSerializable(KEY_ERROR_INFO));
quitLooper(); quitLooper();
} }

@ -353,7 +353,7 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
} else { } else {
ALog.e(TAG, String.format("任务【%s】执行失败", getFileName())); ALog.e(TAG, String.format("任务【%s】执行失败", getFileName()));
ErrorHelp.saveError(TAG, "", ALog.getExceptionString(ex)); ErrorHelp.saveError(TAG, "", ALog.getExceptionString(ex));
sendFailMsg(null); sendFailMsg(null, needRetry);
} }
} }
} }
@ -365,7 +365,7 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
boolean isConnected = NetUtils.isConnected(AriaConfig.getInstance().getAPP()); boolean isConnected = NetUtils.isConnected(AriaConfig.getInstance().getAPP());
if (!isConnected && !isNotNetRetry) { if (!isConnected && !isNotNetRetry) {
ALog.w(TAG, String.format("ts切片【%s】重试失败,网络未连接", getFileName())); ALog.w(TAG, String.format("ts切片【%s】重试失败,网络未连接", getFileName()));
sendFailMsg(null); sendFailMsg(null, false);
return; return;
} }
if (mFailTimes < RETRY_NUM && needRetry && (NetUtils.isConnected( if (mFailTimes < RETRY_NUM && needRetry && (NetUtils.isConnected(
@ -377,7 +377,7 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
FileUtil.createFile(mConfig.tempFile); FileUtil.createFile(mConfig.tempFile);
ThreadTaskManager.getInstance().retryThread(this); ThreadTaskManager.getInstance().retryThread(this);
} else { } else {
sendFailMsg(null); sendFailMsg(null, needRetry);
} }
} }
@ -389,7 +389,7 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
private void retryBlockTask(boolean needRetry) { private void retryBlockTask(boolean needRetry) {
if (!NetUtils.isConnected(AriaConfig.getInstance().getAPP()) && !isNotNetRetry) { if (!NetUtils.isConnected(AriaConfig.getInstance().getAPP()) && !isNotNetRetry) {
ALog.w(TAG, String.format("分块【%s】重试失败,网络未连接", getFileName())); ALog.w(TAG, String.format("分块【%s】重试失败,网络未连接", getFileName()));
sendFailMsg(null); sendFailMsg(null, false);
return; return;
} }
if (mFailTimes < RETRY_NUM && needRetry && (NetUtils.isConnected( if (mFailTimes < RETRY_NUM && needRetry && (NetUtils.isConnected(
@ -400,7 +400,7 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
handleBlockRecord(); handleBlockRecord();
ThreadTaskManager.getInstance().retryThread(this); ThreadTaskManager.getInstance().retryThread(this);
} else { } else {
sendFailMsg(null); sendFailMsg(null, needRetry);
} }
} }
@ -448,13 +448,14 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
/** /**
* 发送失败信息 * 发送失败信息
*/ */
private void sendFailMsg(@Nullable BaseException e) { private void sendFailMsg(@Nullable BaseException e,boolean needRetry) {
if (e != null) {
Bundle b = new Bundle(); Bundle b = new Bundle();
b.putBoolean(IThreadState.KEY_RETRY, needRetry);
if (e != null) {
b.putSerializable(IThreadState.KEY_ERROR_INFO, e); b.putSerializable(IThreadState.KEY_ERROR_INFO, e);
updateState(IThreadState.STATE_FAIL, b); updateState(IThreadState.STATE_FAIL, b);
} else { } else {
updateState(IThreadState.STATE_FAIL, null); updateState(IThreadState.STATE_FAIL, b);
} }
} }

@ -32,7 +32,7 @@ import java.util.Map;
class DBConfig { class DBConfig {
/*adb pull /mnt/sdcard/Android/data/com.arialyy.simple/files/DB/AriaLyyDb d:/db*/ /*adb pull /mnt/sdcard/Android/data/com.arialyy.simple/files/DB/AriaLyyDb d:/db*/
static boolean DEBUG = false; static boolean DEBUG = false;
static Map<String, Class> mapping = new LinkedHashMap<>(); static Map<String, Class<? extends DbEntity>> mapping = new LinkedHashMap<>();
static String DB_NAME; static String DB_NAME;
static int VERSION = 56; static int VERSION = 56;
@ -51,8 +51,8 @@ class DBConfig {
} }
static { static {
mapping.put("DownloadGroupEntity", DownloadGroupEntity.class);
mapping.put("DownloadEntity", DownloadEntity.class); mapping.put("DownloadEntity", DownloadEntity.class);
mapping.put("DownloadGroupEntity", DownloadGroupEntity.class);
mapping.put("UploadEntity", UploadEntity.class); mapping.put("UploadEntity", UploadEntity.class);
mapping.put("ThreadRecord", ThreadRecord.class); mapping.put("ThreadRecord", ThreadRecord.class);
mapping.put("TaskRecord", TaskRecord.class); mapping.put("TaskRecord", TaskRecord.class);

@ -221,4 +221,22 @@ class DelegateCommon extends AbsDelegate {
db.execSQL(str); db.execSQL(str);
} }
} }
/**
* 通过class 获取该class的表字段
*
* @return 表字段列表
*/
List<String> getColumns(Class<? extends DbEntity> clazz) {
List<String> columns = new ArrayList<>();
List<Field> fields = CommonUtil.getAllFields(clazz);
for (Field field : fields) {
field.setAccessible(true);
if (SqlUtil.isIgnore(field)) {
continue;
}
columns.add(field.getName());
}
return columns;
}
} }

@ -100,14 +100,14 @@ final class SqlHelper extends SQLiteOpenHelper {
} else if (oldVersion < 53) { } else if (oldVersion < 53) {
handle366Update(db); handle366Update(db);
} else { } else {
handleDbUpdate(db, null, null); handleDbUpdate(db, null);
} }
} }
} }
@Override public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { @Override public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion > newVersion) { if (oldVersion > newVersion) {
handleDbUpdate(db, null, null); handleDbUpdate(db, null);
} }
} }
@ -145,10 +145,8 @@ final class SqlHelper extends SQLiteOpenHelper {
* *
* @param modifyColumns 需要修改的表字段的映射key为表名 * @param modifyColumns 需要修改的表字段的映射key为表名
* value{@code Map<String, String>}中的Map的key为老字段名称value为该老字段对应的新字段名称 * value{@code Map<String, String>}中的Map的key为老字段名称value为该老字段对应的新字段名称
* @param delColumns 需要删除的表字段key为表名value{@code List<String>}为需要删除的字段列表
*/ */
private void handleDbUpdate(SQLiteDatabase db, Map<String, Map<String, String>> modifyColumns, private void handleDbUpdate(SQLiteDatabase db, Map<String, Map<String, String>> modifyColumns) {
Map<String, List<String>> delColumns) {
if (db == null) { if (db == null) {
ALog.e("SqlHelper", "db 为 null"); ALog.e("SqlHelper", "db 为 null");
return; return;
@ -161,7 +159,7 @@ final class SqlHelper extends SQLiteOpenHelper {
db.beginTransaction(); db.beginTransaction();
Set<String> tables = DBConfig.mapping.keySet(); Set<String> tables = DBConfig.mapping.keySet();
for (String tableName : tables) { for (String tableName : tables) {
Class clazz = DBConfig.mapping.get(tableName); Class<? extends DbEntity> clazz = DBConfig.mapping.get(tableName);
if (mDelegate.tableExists(db, clazz)) { if (mDelegate.tableExists(db, clazz)) {
//修改表名为中介表名 //修改表名为中介表名
String alertSql = String.format("ALTER TABLE %s RENAME TO %s_temp", tableName, tableName); String alertSql = String.format("ALTER TABLE %s RENAME TO %s_temp", tableName, tableName);
@ -178,46 +176,57 @@ final class SqlHelper extends SQLiteOpenHelper {
// 复制数据 // 复制数据
if (count > 0) { if (count > 0) {
// 获取旧表的所有字段名称
Cursor columnC = Cursor columnC =
db.rawQuery(String.format("PRAGMA table_info(%s_temp)", tableName), null); db.rawQuery(String.format("PRAGMA table_info(%s_temp)", tableName), null);
StringBuilder params = new StringBuilder();
// 获取新表的所有字段名称
List<String> newTabColumns = mDelegate.getColumns(clazz);
// 获取旧表的所有字段名称
List<String> oldTabColumns = new ArrayList<>();
while (columnC.moveToNext()) { while (columnC.moveToNext()) {
String columnName = columnC.getString(columnC.getColumnIndex("name")); String columnName = columnC.getString(columnC.getColumnIndex("name"));
if (delColumns != null && delColumns.get(tableName) != null) { oldTabColumns.add(columnName);
List<String> delColumn = delColumns.get(tableName);
if (delColumn != null && !delColumn.isEmpty()) {
if (delColumn.contains(columnName)) {
continue;
}
} }
columnC.close();
// 旧表需要删除的字段,删除旧表有而新表没的字段
List<String> diffTab = getDiffColumn(newTabColumns, oldTabColumns);
StringBuilder params = new StringBuilder();
// 需要修改的列名映射表
Map<String, String> modifyMap = null;
if (modifyColumns != null) {
modifyMap = modifyColumns.get(tableName);
} }
params.append(columnName).append(","); for (String column : oldTabColumns) {
if (!diffTab.isEmpty() && diffTab.contains(column)
&& (modifyMap != null && !modifyMap.containsKey(column))) { // 如果旧表字段有修改,忽略这个删除
continue;
}
params.append(column).append(",");
} }
columnC.close();
String oldParamStr = params.toString(); String oldParamStr = params.toString();
oldParamStr = oldParamStr.substring(0, oldParamStr.length() - 1); oldParamStr = oldParamStr.substring(0, oldParamStr.length() - 1);
String newParamStr = oldParamStr; String newParamStr = oldParamStr;
// 处理字段名称改变 // 处理字段名称改变
if (modifyColumns != null) { if (modifyMap != null && !modifyMap.isEmpty()) {
Map<String, String> columnMap = modifyColumns.get(tableName); Set<String> keys = modifyMap.keySet();
if (columnMap != null && !columnMap.isEmpty()) {
Set<String> keys = columnMap.keySet();
for (String key : keys) { for (String key : keys) {
if (newParamStr.contains(key)) { if (newParamStr.contains(key)) {
newParamStr = newParamStr.replace(key, columnMap.get(key)); newParamStr = newParamStr.replace(key, modifyMap.get(key));
}
} }
} }
} }
//恢复数据 //恢复数据
String insertSql = String insertSql =
String.format("INSERT INTO %s (%s) SELECT %s FROM %s_temp", tableName, newParamStr, String.format("INSERT INTO %s (%s) SELECT %s FROM %s_temp", tableName, newParamStr,
oldParamStr, tableName); oldParamStr, tableName);
ALog.d(TAG, "insertSql = " + insertSql); ALog.d(TAG, "insertSql = " + insertSql);
db.execSQL(insertSql); db.execSQL(insertSql);
} }
//删除中介表 //删除中介表
@ -234,6 +243,19 @@ final class SqlHelper extends SQLiteOpenHelper {
} }
} }
/**
* 取新表差值需要删除的字段旧表有而新表没的字段
*
* @param newTab 新表字段
* @param oldTab 旧表字段
* @return 旧表有而新表没的字段
*/
private List<String> getDiffColumn(List<String> newTab, List<String> oldTab) {
List<String> temp = new ArrayList<>(oldTab); // 拷贝旧表字段
temp.removeAll(newTab);
return temp;
}
/** /**
* 删除重复的repeat数据 * 删除重复的repeat数据
*/ */
@ -256,7 +278,7 @@ final class SqlHelper extends SQLiteOpenHelper {
modifyMap.put("ThreadRecord", threadRecordModify); modifyMap.put("ThreadRecord", threadRecordModify);
// 执行升级操作 // 执行升级操作
handleDbUpdate(db, modifyMap, null); handleDbUpdate(db, modifyMap);
delRepeatThreadRecord(db); delRepeatThreadRecord(db);
} }
@ -273,7 +295,7 @@ final class SqlHelper extends SQLiteOpenHelper {
modifyMap.put("ThreadRecord", threadRecordModify); modifyMap.put("ThreadRecord", threadRecordModify);
// 执行升级操作 // 执行升级操作
handleDbUpdate(db, modifyMap, null); handleDbUpdate(db, modifyMap);
delRepeatThreadRecord(db); delRepeatThreadRecord(db);
} }
@ -307,7 +329,7 @@ final class SqlHelper extends SQLiteOpenHelper {
modifyMap.put("ThreadRecord", threadRecordModify); modifyMap.put("ThreadRecord", threadRecordModify);
// 执行升级操作 // 执行升级操作
handleDbUpdate(db, modifyMap, null); handleDbUpdate(db, modifyMap);
delRepeatThreadRecord(db); delRepeatThreadRecord(db);
} }
@ -360,15 +382,6 @@ final class SqlHelper extends SQLiteOpenHelper {
dGEntityModifyMap.put("groupName", "groupHash"); dGEntityModifyMap.put("groupName", "groupHash");
modifyMap.put("DownloadGroupEntity", dGEntityModifyMap); modifyMap.put("DownloadGroupEntity", dGEntityModifyMap);
// 删除字段 handleDbUpdate(db, modifyMap);
Map<String, List<String>> delColumnMap = new HashMap<>();
List<String> dEntityDel = new ArrayList<>();
dEntityDel.add("taskKey");
delColumnMap.put("DownloadEntity", dEntityDel);
List<String> dgEntityDel = new ArrayList<>();
dgEntityDel.add("subtask");
delColumnMap.put("DownloadGroupEntity", dgEntityDel);
handleDbUpdate(db, modifyMap, delColumnMap);
} }
} }

@ -62,7 +62,7 @@ public class CheckUtil {
public static boolean checkUploadPathConflicts(boolean isForceUpload, String filePath) { public static boolean checkUploadPathConflicts(boolean isForceUpload, String filePath) {
if (DbEntity.checkDataExist(UploadEntity.class, "filePath=?", filePath)) { if (DbEntity.checkDataExist(UploadEntity.class, "filePath=?", filePath)) {
if (!isForceUpload) { if (!isForceUpload) {
ALog.e(TAG, String.format("上传失败,文件路径【%s】已经被其它任务占用,请设置其它保存路径", filePath)); ALog.e(TAG, String.format("上传失败,文件路径【%s】已经被其它任务占用,请设置其它文件路径", filePath));
return false; return false;
} else { } else {
ALog.w(TAG, String.format("文件路径【%s】已经被其它任务占用,当前任务将覆盖该路径的文件", filePath)); ALog.w(TAG, String.format("文件路径【%s】已经被其它任务占用,当前任务将覆盖该路径的文件", filePath));

@ -38,6 +38,8 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.SequenceInputStream; import java.io.SequenceInputStream;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.Channels; import java.nio.channels.Channels;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
@ -61,6 +63,21 @@ public class FileUtil {
private static final String EXTERNAL_STORAGE_PATH = private static final String EXTERNAL_STORAGE_PATH =
Environment.getExternalStorageDirectory().getPath(); Environment.getExternalStorageDirectory().getPath();
/**
* 获取m3u8 ts文件的缓存目录
* 缓存文件夹格式父文件夹/.文件名_码率
*
* @param path m3u8 文件下载路径
* @return m3u8 ts文件的缓存目录
*/
public static String getTsCacheDir(String path, int bandWidth) {
if (TextUtils.isEmpty(path)) {
throw new NullPointerException("m3u8文保存路径为空");
}
File file = new File(path);
return String.format("%s/.%s_%s", file.getParent(), file.getName(), bandWidth);
}
/** /**
* 创建目录 当目录不存在的时候创建文件否则返回false * 创建目录 当目录不存在的时候创建文件否则返回false
*/ */
@ -409,9 +426,19 @@ public class FileUtil {
* 获取SD卡目录列表 * 获取SD卡目录列表
*/ */
public static List<String> getSDPathList(Context context) { public static List<String> getSDPathList(Context context) {
List<String> paths; List<String> paths = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
try {
paths = getVolumeList(context); paths = getVolumeList(context);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} else { } else {
List<String> mounts = readMountsFile(); List<String> mounts = readMountsFile();
List<String> volds = readVoldFile(); List<String> volds = readVoldFile();
@ -471,16 +498,26 @@ public class FileUtil {
/** /**
* getSDPathList * getSDPathList
*/ */
private static List<String> getVolumeList(final Context context) { private static List<String> getVolumeList(final Context context)
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException,
IllegalAccessException {
List<String> pathList = new ArrayList<>(); List<String> pathList = new ArrayList<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StorageManager manager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE); StorageManager manager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
List<StorageVolume> volumes = manager.getStorageVolumes(); List<StorageVolume> volumes = manager.getStorageVolumes();
Class<?> volumeClass = StorageVolume.class;
Method getPath = volumeClass.getDeclaredMethod("getPath");
//Method isRemovable = volumeClass.getDeclaredMethod("isRemovable");
getPath.setAccessible(true);
//isRemovable.setAccessible(true);
for (StorageVolume volume : volumes) { for (StorageVolume volume : volumes) {
String state = volume.getState(); String state = volume.getState();
if (state.equals(Environment.MEDIA_MOUNTED)) { if (state.equals(Environment.MEDIA_MOUNTED)) {
pathList.add(volume.toString()); pathList.add((String) getPath.invoke(volume));
} }
} }
} else { } else {

@ -39,7 +39,7 @@ public class HttpDownloadModule extends BaseViewModule {
//"http://202.98.201.103:7000/vrs/TPK/ZTC440402001Z.tpk"; //"http://202.98.201.103:7000/vrs/TPK/ZTC440402001Z.tpk";
private final String defFilePath = private final String defFilePath =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath()
+ "/tttt.apk"; + "/update.zip";
private MutableLiveData<DownloadEntity> liveData = new MutableLiveData<>(); private MutableLiveData<DownloadEntity> liveData = new MutableLiveData<>();
private DownloadEntity singDownloadInfo; private DownloadEntity singDownloadInfo;
@ -51,10 +51,15 @@ public class HttpDownloadModule extends BaseViewModule {
//String url = AppUtil.getConfigValue(context, HTTP_URL_KEY, defUrl); //String url = AppUtil.getConfigValue(context, HTTP_URL_KEY, defUrl);
//String url = //String url =
// "http://sdkdown.muzhiwan.com/openfile/2019/05/21/com.netease.tom.mzw_5ce3ef8754d05.apk"; // "http://sdkdown.muzhiwan.com/openfile/2019/05/21/com.netease.tom.mzw_5ce3ef8754d05.apk";
String url = "http://image.totwoo.com/totwoo-TOTWOO-v3.5.6.apk"; //String url = "http://image.totwoo.com/totwoo-TOTWOO-v3.5.6.apk";
//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 url = "https://ss1.baidu.com/-4o3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/sign=a9e671b9a551f3dedcb2bf64a4eff0ec/4610b912c8fcc3cef70d70409845d688d53f20f7.jpg";
String filePath = AppUtil.getConfigValue(context, HTTP_PATH_KEY, defFilePath); //String filePath = AppUtil.getConfigValue(context, HTTP_PATH_KEY, defFilePath);
String filePath = "/mnt/sdcard/gg.png";
//String filePath = "/mnt/sdcard/update.zip";
singDownloadInfo = Aria.download(context).getFirstDownloadEntity(url); singDownloadInfo = Aria.download(context).getFirstDownloadEntity(url);
if (singDownloadInfo == null) { if (singDownloadInfo == null) {

@ -39,6 +39,7 @@ import com.arialyy.aria.core.processor.IHttpFileLenAdapter;
import com.arialyy.aria.core.task.DownloadTask; import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.util.FileUtil;
import com.arialyy.frame.util.show.T; import com.arialyy.frame.util.show.T;
import com.arialyy.simple.R; import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity; import com.arialyy.simple.base.BaseActivity;
@ -274,11 +275,13 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
break; break;
} }
if (Aria.download(this).load(mTaskId).isRunning()) { if (Aria.download(this).load(mTaskId).isRunning()) {
Aria.download(this).load(mTaskId).stop(); Aria.download(this)
.load(mTaskId)
.stop();
} else { } else {
mUrl = "http://sdkdown.muzhiwan.com/openfile/2019/07/11/com.netease.syfz.mzw_5d26f8d9cee27.apk"; mUrl = "http://sdkdown.muzhiwan.com/openfile/2019/07/11/com.netease.syfz.mzw_5d26f8d9cee27.apk";
Aria.download(this).load(mTaskId) Aria.download(this).load(mTaskId)
.updateUrl(mUrl) //.updateUrl(mUrl)
.resume(); .resume();
} }
break; break;
@ -297,6 +300,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
.load(mUrl) .load(mUrl)
.setFilePath(mFilePath, true) .setFilePath(mFilePath, true)
.option(option) .option(option)
.ignoreCheckPermissions()
.create(); .create();
} }

@ -35,9 +35,9 @@ public class UploadModule extends BaseViewModule {
* 获取Ftp上传信息 * 获取Ftp上传信息
*/ */
LiveData<UploadEntity> getFtpInfo(Context context) { LiveData<UploadEntity> getFtpInfo(Context context) {
String url = AppUtil.getConfigValue(context, FTP_URL_KEY, "ftp://9.9.9.50:2121/aa/你好"); String url = AppUtil.getConfigValue(context, FTP_URL_KEY, "ftp://9.9.9.72:2121/aa/你好");
String filePath = AppUtil.getConfigValue(context, FTP_PATH_KEY, String filePath = AppUtil.getConfigValue(context, FTP_PATH_KEY,
Environment.getExternalStorageDirectory().getPath() + "/Download/Folx P58.zip"); Environment.getExternalStorageDirectory().getPath() + "/Download/AndroidAria.db");
UploadEntity entity = Aria.upload(context).getFirstUploadEntity(filePath); UploadEntity entity = Aria.upload(context).getFirstUploadEntity(filePath);
if (entity != null) { if (entity != null) {

@ -44,8 +44,8 @@ task clean(type: Delete) {
} }
ext { ext {
versionCode = 379 versionCode = 380
versionName = '3.7.9' versionName = '3.7.10_pre_3'
userOrg = 'arialyy' userOrg = 'arialyy'
groupId = 'com.arialyy.aria' groupId = 'com.arialyy.aria'
publishVersion = versionName publishVersion = versionName

@ -1,15 +0,0 @@
{
// 使 IntelliSense
//
// 访: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: 当前文件",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
]
}

@ -1,6 +0,0 @@
{
"python.linting.pylintEnabled": false,
"python.linting.pep8Enabled": true,
"python.linting.enabled": true,
"python.pythonPath": "/usr/local/bin/python3.7"
}

Binary file not shown.
Loading…
Cancel
Save