diff --git a/.gitignore b/.gitignore
index 6b0f8a6a..04f27198 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,4 +13,5 @@
/.idea
.idea
/cache
-*.log
\ No newline at end of file
+*.log
+uml
\ No newline at end of file
diff --git a/Aria/build.gradle b/Aria/build.gradle
index f95e9d8f..18b2d152 100644
--- a/Aria/build.gradle
+++ b/Aria/build.gradle
@@ -16,6 +16,9 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
+ lintOptions {
+ abortOnError false
+ }
}
dependencies {
@@ -23,8 +26,8 @@ dependencies {
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile project(':AriaAnnotations')
-// compile 'com.arialyy.aria:aria-ftp-plug:1.0.3'
+ compile 'com.arialyy.aria:aria-ftp-plug:1.0.3'
- compile project(':AriaFtpPlug')
+ // compile project(':AriaFtpPlug')
}
apply from: 'bintray-release.gradle'
diff --git a/Aria/src/main/java/com/arialyy/aria/core/Aria.java b/Aria/src/main/java/com/arialyy/aria/core/Aria.java
index d6d681b7..10a40fa2 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/Aria.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/Aria.java
@@ -17,15 +17,8 @@
package com.arialyy.aria.core;
import android.annotation.TargetApi;
-import android.app.Activity;
-import android.app.Application;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.app.Fragment;
-import android.app.Service;
import android.content.Context;
import android.os.Build;
-import android.widget.PopupWindow;
import com.arialyy.aria.core.download.DownloadReceiver;
import com.arialyy.aria.core.upload.UploadReceiver;
@@ -51,6 +44,24 @@ import com.arialyy.aria.core.upload.UploadReceiver;
* .start();
*
*
+ *
+ * 如果你需要在【Activity、Service、Application、DialogFragment、Fragment、PopupWindow、Dialog】
+ * 之外的java中使用Aria,那么你应该在Application或Activity初始化的时候调用{@link #init(Context)}对Aria进行初始化
+ * 然后才能使用{@link #download(Object)}、{@link #upload(Object)}
+ *
+ *
+ *
+ * Aria.init(getContext());
+ *
+ * Aria.download(this)
+ * .load(URL) //下载地址,必填
+ * //文件保存路径,必填
+ * .setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/test.apk")
+ * .start();
+ *
+ *
+ *
+ *
*/
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) public class Aria {
@@ -60,52 +71,53 @@ import com.arialyy.aria.core.upload.UploadReceiver;
/**
* 初始化下载
*
- * @param obj 支持类型有【Activity、Service、Application、DialogFragment、Fragment、PopupWindow、Dialog】
+ * @param context 支持类型有【Activity、Service、Application、DialogFragment、Fragment、PopupWindow、Dialog】
*/
- public static DownloadReceiver download(Object obj) {
- return get(obj).download(obj);
+ public static DownloadReceiver download(Context context) {
+ return get(context).download(context);
}
/**
* 初始化上传
*
- * @param obj 支持类型有【Activity、Service、Application、DialogFragment、Fragment、PopupWindow、Dialog】
+ * @param context 支持类型有【Activity、Service、Application、DialogFragment、Fragment、PopupWindow、Dialog】
+ */
+ public static UploadReceiver upload(Context context) {
+ return get(context).upload(context);
+ }
+
+ /**
+ * 在任意对象中初始化下载,前提是你需要在Application或Activity初始化的时候调用{@link #init(Context)}对Aria进行初始化
+ *
+ * @param obj 任意对象
+ */
+ public static DownloadReceiver download(Object obj) {
+ return AriaManager.getInstance().download(obj);
+ }
+
+ /**
+ * 在任意对象中初始化上传,前提是你需要在Application或Activity初始化的时候调用{@link #init(Context)}对Aria进行初始化
+ *
+ * @param obj 任意对象
*/
public static UploadReceiver upload(Object obj) {
- return get(obj).upload(obj);
+ return AriaManager.getInstance().upload(obj);
}
/**
* 处理通用事件
- *
- * @param obj 支持类型有【Activity、Service、Application、DialogFragment、Fragment、PopupWindow、Dialog】
*/
- public static AriaManager get(Object obj) {
- if (obj instanceof Activity || obj instanceof Service || obj instanceof Application) {
- return AriaManager.getInstance((Context) obj);
- } else if (obj instanceof DialogFragment) {
- DialogFragment dialog = (DialogFragment) obj;
- return AriaManager.getInstance(
- Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? dialog.getContext()
- : dialog.getActivity());
- } else if (obj instanceof android.support.v4.app.Fragment) {
- android.support.v4.app.Fragment fragment = (android.support.v4.app.Fragment) obj;
- return AriaManager.getInstance(
- Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? fragment.getContext()
- : fragment.getActivity());
- } else if (obj instanceof Fragment) {
- Fragment fragment = (Fragment) obj;
- return AriaManager.getInstance(
- Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? fragment.getContext()
- : fragment.getActivity());
- } else if (obj instanceof PopupWindow) {
- PopupWindow popupWindow = (PopupWindow) obj;
- return AriaManager.getInstance(popupWindow.getContentView().getContext());
- } else if (obj instanceof Dialog) {
- Dialog dialog = (Dialog) obj;
- return AriaManager.getInstance(dialog.getContext());
- } else {
- throw new IllegalArgumentException("不支持的类型");
- }
+ public static AriaManager get(Context context) {
+ return AriaManager.getInstance(context);
+ }
+
+ /**
+ * 初始化Aria,如果你需要在【Activity、Service、Application、DialogFragment、Fragment、PopupWindow、Dialog】
+ * 之外的java中使用Aria,那么你应该在Application或Activity初始化的时候调用本方法对Aria进行初始化
+ * 只需要初始化一次就可以
+ * {@link #download(Object)}、{@link #upload(Object)}
+ */
+ public static AriaManager init(Context context) {
+ return AriaManager.getInstance(context);
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
index 9f7316c5..2fe50163 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
@@ -20,13 +20,11 @@ import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Application;
import android.app.Dialog;
-import android.app.Service;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
-import android.text.TextUtils;
import android.widget.PopupWindow;
import com.arialyy.aria.core.command.ICmd;
import com.arialyy.aria.core.common.QueueMod;
@@ -41,8 +39,9 @@ import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadReceiver;
import com.arialyy.aria.core.upload.UploadTaskEntity;
import com.arialyy.aria.orm.DbEntity;
-import com.arialyy.aria.orm.DbUtil;
+import com.arialyy.aria.orm.DelegateWrapper;
import com.arialyy.aria.util.ALog;
+import com.arialyy.aria.util.AriaCrashHandler;
import com.arialyy.aria.util.CommonUtil;
import java.io.File;
import java.io.IOException;
@@ -75,12 +74,14 @@ import org.xml.sax.SAXException;
private List mCommands = new ArrayList<>();
private Configuration.DownloadConfig mDConfig;
private Configuration.UploadConfig mUConfig;
+ private Configuration.AppConfig mAConfig;
private AriaManager(Context context) {
- DbUtil.init(context.getApplicationContext());
+ DelegateWrapper.init(context.getApplicationContext());
APP = context.getApplicationContext();
regAppLifeCallback(context);
initConfig();
+ initAria();
}
public static AriaManager getInstance(Context context) {
@@ -92,34 +93,53 @@ import org.xml.sax.SAXException;
return INSTANCE;
}
- public Map getReceiver() {
- return mReceivers;
+ static AriaManager getInstance() {
+ if (INSTANCE == null) {
+ throw new NullPointerException("请在Application或Activity初始化时调用一次Aria.init(context)方法进行初始化操作");
+ }
+ return INSTANCE;
}
- /**
- * 设置Aria 日志级别
- *
- * @param level {@link ALog#LOG_LEVEL_VERBOSE}
- */
- public void setLogLevel(int level) {
- ALog.LOG_LEVEL = level;
+ private void initAria() {
+ if (mAConfig.getUseAriaCrashHandler()) {
+ Thread.setDefaultUncaughtExceptionHandler(new AriaCrashHandler());
+ }
+ mAConfig.setLogLevel(mAConfig.getLogLevel());
+ }
+
+ public Map getReceiver() {
+ return mReceivers;
}
/**
- * 设置上传任务的执行队列类型
+ * 设置上传任务的执行队列类型,后续版本会删除该api,请使用:
+ *
+ *
+ * Aria.get(this).getUploadConfig().setQueueMod(mod.tag)
+ *
+ *
*
* @param mod {@link QueueMod}
+ * @deprecated 后续版本会删除该api
*/
+ @Deprecated
public AriaManager setUploadQueueMod(QueueMod mod) {
mUConfig.setQueueMod(mod.tag);
return this;
}
/**
- * 设置下载任务的执行队列类型
+ * 设置下载任务的执行队列类型,后续版本会删除该api,请使用:
+ *
+ *
+ * Aria.get(this).getDownloadConfig().setQueueMod(mod.tag)
+ *
+ *
*
* @param mod {@link QueueMod}
+ * @deprecated 后续版本会删除该api
*/
+ @Deprecated
public AriaManager setDownloadQueueMod(QueueMod mod) {
mDConfig.setQueueMod(mod.tag);
return this;
@@ -151,6 +171,13 @@ import org.xml.sax.SAXException;
return mUConfig;
}
+ /**
+ * 获取APP配置
+ */
+ public Configuration.AppConfig getAppConfig() {
+ return mAConfig;
+ }
+
/**
* 设置命令
*/
@@ -201,22 +228,6 @@ import org.xml.sax.SAXException;
return (receiver instanceof UploadReceiver) ? (UploadReceiver) receiver : null;
}
- /**
- * 获取Aria下载错误日志
- *
- * @return 如果错误日志不存在则返回空,否则返回错误日志列表
- */
- public List getErrorLog() {
- return DbEntity.findAllData(ErrorEntity.class);
- }
-
- /**
- * 清楚错误日志
- */
- public void cleanLog() {
- DbEntity.clean(ErrorEntity.class);
- }
-
/**
* 删除任务记录
*
@@ -244,6 +255,7 @@ import org.xml.sax.SAXException;
final String key = getKey(isDownload, obj);
IReceiver receiver = mReceivers.get(key);
boolean needRmReceiver = false;
+ // 监控Dialog、fragment、popupWindow的生命周期
final WidgetLiftManager widgetLiftManager = new WidgetLiftManager();
if (obj instanceof Dialog) {
needRmReceiver = widgetLiftManager.handleDialogLift((Dialog) obj);
@@ -270,7 +282,8 @@ import org.xml.sax.SAXException;
/**
* 不允许在"onDestroy"、"finish"、"onStop"这三个方法中添加注册器
*/
- private AbsReceiver checkTarget(String key, AbsReceiver receiver, Object obj, boolean needRmReceiver) {
+ private AbsReceiver checkTarget(String key, AbsReceiver receiver, Object obj,
+ boolean needRmReceiver) {
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
int i = 0;
for (StackTraceElement e : stack) {
@@ -288,8 +301,8 @@ import org.xml.sax.SAXException;
"onStop");
if (isDestroyed) {
- ALog.w(TAG,
- "请不要在Activity或Fragment的onDestroy、finish、onStop等方法中调用Aria,Aria的unRegister会在Activity页面销毁时自动执行");
+ ALog.e(TAG,
+ "请不要在Activity或Fragment的onDestroy、finish、onStop等方法中注册Aria,Aria的unRegister会在Activity页面销毁时自动执行");
}
if (obj instanceof Activity && isDestroyed) {
@@ -309,45 +322,33 @@ import org.xml.sax.SAXException;
*/
private String getKey(boolean isDownload, Object obj) {
String clsName = obj.getClass().getName();
- String key = "";
- if (!(obj instanceof Activity)) {
- if (obj instanceof DialogFragment) {
- key = clsName + "_" + ((DialogFragment) obj).getActivity().getClass().getName();
- } else if (obj instanceof android.app.DialogFragment) {
- key = clsName + "_" + ((android.app.DialogFragment) obj).getActivity().getClass().getName();
- } else if (obj instanceof android.support.v4.app.Fragment) {
- key = clsName + "_" + ((Fragment) obj).getActivity().getClass().getName();
- } else if (obj instanceof android.app.Fragment) {
- key = clsName + "_" + ((android.app.Fragment) obj).getActivity().getClass().getName();
- } else if (obj instanceof Dialog) {
- Activity activity = ((Dialog) obj).getOwnerActivity();
- if (activity != null) {
- key = clsName + "_" + activity.getClass().getName();
- } else {
- key = clsName;
- }
- } else if (obj instanceof PopupWindow) {
- Context context = ((PopupWindow) obj).getContentView().getContext();
- if (context instanceof Activity) {
- key = clsName + "_" + context.getClass().getName();
- } else {
- key = clsName;
- }
- } else if (obj instanceof Service) {
+ String key;
+ if (obj instanceof DialogFragment) {
+ key = clsName + "_" + ((DialogFragment) obj).getActivity().getClass().getName();
+ } else if (obj instanceof android.app.DialogFragment) {
+ key = clsName + "_" + ((android.app.DialogFragment) obj).getActivity().getClass().getName();
+ } else if (obj instanceof android.support.v4.app.Fragment) {
+ key = clsName + "_" + ((Fragment) obj).getActivity().getClass().getName();
+ } else if (obj instanceof android.app.Fragment) {
+ key = clsName + "_" + ((android.app.Fragment) obj).getActivity().getClass().getName();
+ } else if (obj instanceof Dialog) {
+ Activity activity = ((Dialog) obj).getOwnerActivity();
+ if (activity != null) {
+ key = clsName + "_" + activity.getClass().getName();
+ } else {
key = clsName;
- } else if (obj instanceof Application) {
+ }
+ } else if (obj instanceof PopupWindow) {
+ Context context = ((PopupWindow) obj).getContentView().getContext();
+ if (context instanceof Activity) {
+ key = clsName + "_" + context.getClass().getName();
+ } else {
key = clsName;
}
- }
- if (obj instanceof Activity || obj instanceof Service) {
- key = clsName;
- } else if (obj instanceof Application) {
+ } else {
key = clsName;
}
- if (TextUtils.isEmpty(key)) {
- throw new IllegalArgumentException("未知类型");
- }
- key += isDownload ? DOWNLOAD : UPLOAD;
+ key += (isDownload ? DOWNLOAD : UPLOAD) + obj.hashCode();
return key;
}
@@ -377,6 +378,7 @@ import org.xml.sax.SAXException;
}
mDConfig = Configuration.DownloadConfig.getInstance();
mUConfig = Configuration.UploadConfig.getInstance();
+ mAConfig = Configuration.AppConfig.getInstance();
if (tempDir.exists()) {
File newDir = new File(APP.getFilesDir().getPath() + DOWNLOAD_TEMP_DIR);
newDir.mkdirs();
@@ -406,8 +408,8 @@ import org.xml.sax.SAXException;
private void regAppLifeCallback(Context context) {
Context app = context.getApplicationContext();
if (app instanceof Application) {
- LifeCallback mLifeCallback = new LifeCallback();
- ((Application) app).registerActivityLifecycleCallbacks(mLifeCallback);
+ LifeCallback lifeCallback = new LifeCallback();
+ ((Application) app).registerActivityLifecycleCallbacks(lifeCallback);
}
}
@@ -478,6 +480,7 @@ import org.xml.sax.SAXException;
@Override public void onActivityDestroyed(Activity activity) {
destroySchedulerListener(activity);
+ // TODO: 2018/4/11 维护一个activity堆栈,应用被kill,activity会回调onDestroy方法,需要考虑server后台情况
}
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/ConfigHelper.java b/Aria/src/main/java/com/arialyy/aria/core/ConfigHelper.java
index 1eb12427..71211cd2 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/ConfigHelper.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/ConfigHelper.java
@@ -28,9 +28,10 @@ import org.xml.sax.helpers.DefaultHandler;
class ConfigHelper extends DefaultHandler {
private final String TAG = "ConfigHelper";
- private boolean isDownloadConfig = false, isUploadConfig;
+ private boolean isDownloadConfig = false, isUploadConfig = false, isAppConfig = false;
private Configuration.DownloadConfig mDownloadConfig = Configuration.DownloadConfig.getInstance();
private Configuration.UploadConfig mUploadConfig = Configuration.UploadConfig.getInstance();
+ private Configuration.AppConfig mAppConfig = Configuration.AppConfig.getInstance();
@Override public void startDocument() throws SAXException {
super.startDocument();
@@ -43,10 +44,17 @@ class ConfigHelper extends DefaultHandler {
if (qName.equals("download")) {
isDownloadConfig = true;
isUploadConfig = false;
+ isAppConfig = false;
} else if (qName.equals("upload")) {
isUploadConfig = true;
isDownloadConfig = false;
+ isAppConfig = false;
+ } else if (qName.equals("app")) {
+ isUploadConfig = false;
+ isDownloadConfig = false;
+ isAppConfig = true;
}
+
if (isDownloadConfig || isUploadConfig) {
String value = attributes.getValue("value");
@@ -90,17 +98,46 @@ class ConfigHelper extends DefaultHandler {
loadUpdateInterval(value);
break;
}
+ } else if (isAppConfig) {
+ String value = attributes.getValue("value");
+ switch (qName) {
+ case "useAriaCrashHandler":
+ loadUseAriaCrashHandler(value);
+ break;
+ case "logLevel":
+ loadLogLevel(value);
+ break;
+ }
}
}
- private void loadUpdateInterval(String value) {
- long temp = 1000;
- if (!TextUtils.isEmpty(value)) {
- temp = Long.parseLong(value);
- if (temp <= 0) {
- temp = 1000;
- }
+ private void loadLogLevel(String value) {
+ int level;
+ try {
+ level = Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ level = ALog.LOG_LEVEL_VERBOSE;
+ }
+ if (level < ALog.LOG_LEVEL_VERBOSE || level > ALog.LOG_CLOSE) {
+ ALog.w(TAG, "level【" + level + "】错误");
+ mAppConfig.logLevel = ALog.LOG_LEVEL_VERBOSE;
+ } else {
+ mAppConfig.logLevel = level;
+ }
+ }
+
+ private void loadUseAriaCrashHandler(String value) {
+ if (checkBoolean(value)) {
+ mAppConfig.useAriaCrashHandler = Boolean.parseBoolean(value);
+ } else {
+ ALog.w(TAG, "useAriaCrashHandler【" + value + "】错误");
+ mAppConfig.useAriaCrashHandler = true;
}
+ }
+
+ private void loadUpdateInterval(String value) {
+ long temp = checkLong(value) ? Long.parseLong(value) : 1000;
if (isDownloadConfig) {
mDownloadConfig.updateInterval = temp;
}
@@ -124,17 +161,18 @@ class ConfigHelper extends DefaultHandler {
}
private void loadMaxSpeed(String value) {
- double maxSpeed = 0.0;
- if (!TextUtils.isEmpty(value)) {
- maxSpeed = Double.parseDouble(value);
- }
+ int maxSpeed = checkInt(value) ? Integer.parseInt(value) : 0;
if (isDownloadConfig) {
- mDownloadConfig.msxSpeed = maxSpeed;
+ mDownloadConfig.maxSpeed = maxSpeed;
}
}
private void loadConvertSpeed(String value) {
- boolean open = Boolean.parseBoolean(value);
+ boolean open = true;
+ if (checkBoolean(value)) {
+ open = Boolean.parseBoolean(value);
+ }
+
if (isDownloadConfig) {
mDownloadConfig.isConvertSpeed = open;
}
@@ -144,10 +182,7 @@ class ConfigHelper extends DefaultHandler {
}
private void loadReTryInterval(String value) {
- int time = 2 * 1000;
- if (!TextUtils.isEmpty(value)) {
- time = Integer.parseInt(value);
- }
+ int time = checkInt(value) ? Integer.parseInt(value) : 2 * 1000;
if (time < 2 * 1000) {
time = 2 * 1000;
@@ -166,10 +201,7 @@ class ConfigHelper extends DefaultHandler {
}
private void loadBuffSize(String value) {
- int buffSize = 8192;
- if (!TextUtils.isEmpty(value)) {
- buffSize = Integer.parseInt(value);
- }
+ int buffSize = checkInt(value) ? Integer.parseInt(value) : 8192;
if (buffSize < 2048) {
buffSize = 2048;
@@ -181,10 +213,7 @@ class ConfigHelper extends DefaultHandler {
}
private void loadIOTimeout(String value) {
- int time = 10 * 1000;
- if (!TextUtils.isEmpty(value)) {
- time = Integer.parseInt(value);
- }
+ int time = checkInt(value) ? Integer.parseInt(value) : 10 * 1000;
if (time < 10 * 1000) {
time = 10 * 1000;
@@ -196,10 +225,7 @@ class ConfigHelper extends DefaultHandler {
}
private void loadConnectTime(String value) {
- int time = 5 * 1000;
- if (!TextUtils.isEmpty(value)) {
- time = Integer.parseInt(value);
- }
+ int time = checkInt(value) ? Integer.parseInt(value) : 5 * 1000;
if (isDownloadConfig) {
mDownloadConfig.connectTimeOut = time;
@@ -210,10 +236,7 @@ class ConfigHelper extends DefaultHandler {
}
private void loadReTry(String value) {
- int num = 0;
- if (!TextUtils.isEmpty(value)) {
- num = Integer.parseInt(value);
- }
+ int num = checkInt(value) ? Integer.parseInt(value) : 0;
if (isDownloadConfig) {
mDownloadConfig.reTryNum = num;
@@ -224,10 +247,7 @@ class ConfigHelper extends DefaultHandler {
}
private void loadMaxQueue(String value) {
- int num = 2;
- if (!TextUtils.isEmpty(value)) {
- num = Integer.parseInt(value);
- }
+ int num = checkInt(value) ? Integer.parseInt(value) : 2;
if (num < 1) {
ALog.w(TAG, "任务队列数不能小于 1");
num = 2;
@@ -241,10 +261,7 @@ class ConfigHelper extends DefaultHandler {
}
private void loadThreadNum(String value) {
- int num = 3;
- if (!TextUtils.isEmpty(value)) {
- num = Integer.parseInt(value);
- }
+ int num = checkInt(value) ? Integer.parseInt(value) : 3;
if (num < 1) {
ALog.e(TAG, "下载线程数不能小于 1");
num = 1;
@@ -254,6 +271,52 @@ class ConfigHelper extends DefaultHandler {
}
}
+ /**
+ * 检查是否int值是否合法
+ *
+ * @return {@code true} 合法
+ */
+ private boolean checkInt(String value) {
+ if (TextUtils.isEmpty(value)) {
+ return false;
+ }
+ try {
+ Integer l = Integer.parseInt(value);
+ return true;
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ * 检查是否long值是否合法
+ *
+ * @return {@code true} 合法
+ */
+ private boolean checkLong(String value) {
+ if (TextUtils.isEmpty(value)) {
+ return false;
+ }
+ try {
+ Long l = Long.parseLong(value);
+ return true;
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ * 检查boolean值是否合法
+ *
+ * @return {@code true} 合法
+ */
+ private boolean checkBoolean(String value) {
+ return !TextUtils.isEmpty(value) && (value.equalsIgnoreCase("true") || value.equalsIgnoreCase(
+ "false"));
+ }
+
@Override public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
}
@@ -266,5 +329,6 @@ class ConfigHelper extends DefaultHandler {
super.endDocument();
mDownloadConfig.saveAll();
mUploadConfig.saveAll();
+ mAppConfig.saveAll();
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/ErrorEntity.java b/Aria/src/main/java/com/arialyy/aria/core/ErrorEntity.java
deleted file mode 100644
index 0ba2bbe6..00000000
--- a/Aria/src/main/java/com/arialyy/aria/core/ErrorEntity.java
+++ /dev/null
@@ -1,77 +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;
-
-import com.arialyy.aria.orm.DbEntity;
-
-/**
- * Created by Aria.Lao on 2017/8/29.
- * 错误实体
- */
-public class ErrorEntity extends DbEntity {
-
- /**
- * 插入时间
- */
- public long insertTime;
-
- /**
- * 错误信息
- */
- public String err;
-
- /**
- * 任务名
- */
- public String taskName;
-
- /**
- *任务类型
- */
- public String taskType;
-
- /**
- * 提示
- */
- public String msg;
-
- /**
- * 任务key
- */
- public String key;
-
- @Override public String toString() {
- return "ErrorEntity{"
- + "insertTime="
- + insertTime
- + ", err='"
- + err
- + '\''
- + ", taskName='"
- + taskName
- + '\''
- + ", taskType='"
- + taskType
- + '\''
- + ", msg='"
- + msg
- + '\''
- + ", key='"
- + key
- + '\''
- + '}';
- }
-}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/FtpUrlEntity.java b/Aria/src/main/java/com/arialyy/aria/core/FtpUrlEntity.java
index a684e810..da821979 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/FtpUrlEntity.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/FtpUrlEntity.java
@@ -24,7 +24,10 @@ import java.net.InetAddress;
* ftp url 信息链接实体
*/
public class FtpUrlEntity implements Cloneable {
-
+ /**
+ * 如:ftp://127.0.0.1:21/download/AriaPrj.zip
+ * remotePath便是:download/AriaPrj.zip
+ */
public String remotePath;
public String account;
@@ -35,12 +38,12 @@ public class FtpUrlEntity implements Cloneable {
public String url;
/**
- * ftp协议
+ * ftp协议:ftp
*/
public String protocol;
/**
- * 用户
+ * 登录的用户名
*/
public String user;
/**
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java
index 3f3efe11..cd0197fb 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelAllCmd.java
@@ -16,13 +16,7 @@
package com.arialyy.aria.core.command.normal;
-import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
-import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
-import com.arialyy.aria.core.upload.UploadTaskEntity;
-import com.arialyy.aria.orm.DbEntity;
-import com.arialyy.aria.util.CommonUtil;
-import java.util.List;
/**
* Created by AriaL on 2017/6/27.
@@ -44,46 +38,5 @@ public class CancelAllCmd extends AbsNormalCmd {
@Override public void executeCmd() {
removeAll();
- if (mTaskEntity instanceof DownloadTaskEntity
- || mTaskEntity instanceof DownloadGroupTaskEntity) {
- handleDownloadRemove();
- handleDownloadGroupRemove();
- } else if (mTaskEntity instanceof UploadTaskEntity) {
- handleUploadRemove();
- handleUploadRemove();
- }
- }
-
- /**
- * 处理下载任务组的删除操作
- */
- private void handleDownloadGroupRemove() {
- List allEntity = DbEntity.findAllData(DownloadGroupTaskEntity.class);
- if (allEntity == null || allEntity.size() == 0) return;
- for (DownloadGroupTaskEntity entity : allEntity) {
- CommonUtil.delDownloadGroupTaskConfig(removeFile, entity);
- }
- }
-
- /**
- * 处理上传的删除
- */
- private void handleUploadRemove() {
- List allEntity = DbEntity.findAllData(UploadTaskEntity.class);
- if (allEntity == null || allEntity.size() == 0) return;
- for (UploadTaskEntity entity : allEntity) {
- CommonUtil.delUploadTaskConfig(removeFile, entity);
- }
- }
-
- /**
- * 处理下载的删除
- */
- private void handleDownloadRemove() {
- List allEntity = DbEntity.findAllData(DownloadTaskEntity.class);
- if (allEntity == null || allEntity.size() == 0) return;
- for (DownloadTaskEntity entity : allEntity) {
- CommonUtil.delDownloadTaskConfig(removeFile, entity);
- }
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelCmd.java
index 31db4cdf..57ab73d1 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelCmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelCmd.java
@@ -42,7 +42,7 @@ public class CancelCmd extends AbsNormalCmd {
task = createTask();
}
if (task != null) {
- mTaskEntity.removeFile = removeFile;
+ mTaskEntity.setRemoveFile(removeFile);
if (!TextUtils.isEmpty(mTargetName)) {
task.setTargetName(mTargetName);
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/ResumeAllCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/ResumeAllCmd.java
index b952b205..ecdc37df 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/ResumeAllCmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/ResumeAllCmd.java
@@ -3,12 +3,15 @@ package com.arialyy.aria.core.command.normal;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
+import com.arialyy.aria.core.download.wrapper.DGTEWrapper;
+import com.arialyy.aria.core.download.wrapper.DTEWrapper;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.queue.DownloadGroupTaskQueue;
import com.arialyy.aria.core.queue.DownloadTaskQueue;
import com.arialyy.aria.core.queue.UploadTaskQueue;
import com.arialyy.aria.core.upload.UploadTaskEntity;
+import com.arialyy.aria.core.upload.wrapper.UTEWrapper;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
@@ -53,29 +56,32 @@ final class ResumeAllCmd extends AbsNormalCmd {
* @param type {@code 1}单任务下载任务;{@code 2}任务组下载任务;{@code 3} 单任务上传任务
*/
private List findTaskData(int type) {
+ // TODO: 2018/4/20 需要测试
List tempList = new ArrayList<>();
- switch (type) {
- case 1:
- List dTaskEntity =
- DbEntity.findDatas(DownloadTaskEntity.class, "isGroupTask=?", "false");
- if (dTaskEntity != null && !dTaskEntity.isEmpty()) {
- tempList.addAll(dTaskEntity);
+ if (type == 1) {
+ List wrappers = DbEntity.findRelationData(DTEWrapper.class,
+ "DownloadTaskEntity.isGroupTask=? and DownloadTaskEntity.state!=?", "false", "1");
+ if (wrappers != null && !wrappers.isEmpty()) {
+ for (DTEWrapper w : wrappers) {
+ tempList.add(w.taskEntity);
}
- break;
- case 2:
- List groupTask =
- DbEntity.findAllData(DownloadGroupTaskEntity.class);
- if (groupTask != null && !groupTask.isEmpty()) {
- tempList.addAll(groupTask);
+ }
+ } else if (type == 2) {
+ List wrappers =
+ DbEntity.findRelationData(DGTEWrapper.class, "DownloadGroupTaskEntity.state!=?", "1");
+ if (wrappers != null && !wrappers.isEmpty()) {
+ for (DGTEWrapper w : wrappers) {
+ tempList.add(w.taskEntity);
}
- break;
- case 3:
- List uTaskEntity =
- DbEntity.findDatas(UploadTaskEntity.class, "isGroupTask=?", "false");
- if (uTaskEntity != null && !uTaskEntity.isEmpty()) {
- tempList.addAll(uTaskEntity);
+ }
+ } else if (type == 3) {
+ List wrappers =
+ DbEntity.findRelationData(UTEWrapper.class, "UploadTaskEntity.state!=?", "1");
+ if (wrappers != null && !wrappers.isEmpty()) {
+ for (UTEWrapper w : wrappers) {
+ tempList.add(w.taskEntity);
}
- break;
+ }
}
return tempList;
}
@@ -123,8 +129,8 @@ final class ResumeAllCmd extends AbsNormalCmd {
*/
private void resumeEntity(AbsTaskEntity te) {
if (te instanceof DownloadTaskEntity) {
- if (te.requestType == AbsTaskEntity.D_FTP || te.requestType == AbsTaskEntity.U_FTP) {
- te.urlEntity = CommonUtil.getFtpUrlInfo(te.getEntity().getKey());
+ if (te.getRequestType() == AbsTaskEntity.D_FTP || te.getRequestType() == AbsTaskEntity.U_FTP) {
+ te.setUrlEntity(CommonUtil.getFtpUrlInfo(te.getEntity().getKey()));
}
mQueue = DownloadTaskQueue.getInstance();
} else if (te instanceof UploadTaskEntity) {
diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/normal/StartCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/normal/StartCmd.java
index 82120c32..680245a0 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/command/normal/StartCmd.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/command/normal/StartCmd.java
@@ -21,6 +21,8 @@ import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.QueueMod;
import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
+import com.arialyy.aria.core.download.wrapper.DGTEWrapper;
+import com.arialyy.aria.core.download.wrapper.DTEWrapper;
import com.arialyy.aria.core.inf.AbsTask;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IEntity;
@@ -28,6 +30,7 @@ import com.arialyy.aria.core.queue.DownloadGroupTaskQueue;
import com.arialyy.aria.core.queue.DownloadTaskQueue;
import com.arialyy.aria.core.queue.UploadTaskQueue;
import com.arialyy.aria.core.upload.UploadTaskEntity;
+import com.arialyy.aria.core.upload.wrapper.UTEWrapper;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
@@ -53,6 +56,7 @@ class StartCmd extends AbsNormalCmd {
return;
}
String mod;
+ // TODO: 2018/4/12 配置文件不存在,是否会出现wait获取不到 ?
int maxTaskNum = mQueue.getMaxTaskNum();
AriaManager manager = AriaManager.getInstance(AriaManager.APP);
if (isDownloadCmd) {
@@ -77,7 +81,6 @@ class StartCmd extends AbsNormalCmd {
|| task.getState() == IEntity.STATE_OTHER
|| task.getState() == IEntity.STATE_POST_PRE
|| task.getState() == IEntity.STATE_COMPLETE) {
- //startTask();
resumeTask();
} else {
sendWaitState();
@@ -85,7 +88,6 @@ class StartCmd extends AbsNormalCmd {
}
} else {
if (!task.isRunning()) {
- //startTask();
resumeTask();
}
}
@@ -113,29 +115,32 @@ class StartCmd extends AbsNormalCmd {
}
private List findWaitData(int type) {
+ // TODO: 2018/4/20 需要测试
List waitList = new ArrayList<>();
- switch (type) {
- case 1:
- List dEntity =
- DbEntity.findDatas(DownloadTaskEntity.class, "groupName=? and state=?", "", "3");
- if (dEntity != null && !dEntity.isEmpty()) {
- waitList.addAll(dEntity);
+ if (type == 1) {
+ List wrappers = DbEntity.findRelationData(DTEWrapper.class,
+ "DownloadTaskEntity.isGroupTask=? and DownloadTaskEntity.state=?", "false", "3");
+ if (wrappers != null && !wrappers.isEmpty()) {
+ for (DTEWrapper w : wrappers) {
+ waitList.add(w.taskEntity);
}
- break;
- case 2:
- List dgEntity =
- DbEntity.findDatas(DownloadGroupTaskEntity.class, "state=?", "3");
- if (dgEntity != null && !dgEntity.isEmpty()) {
- waitList.addAll(dgEntity);
+ }
+ } else if (type == 2) {
+ List wrappers =
+ DbEntity.findRelationData(DGTEWrapper.class, "DownloadGroupTaskEntity.state=?", "3");
+ if (wrappers != null && !wrappers.isEmpty()) {
+ for (DGTEWrapper w : wrappers) {
+ waitList.add(w.taskEntity);
}
- break;
- case 3:
- List uEntity =
- DbEntity.findDatas(UploadTaskEntity.class, "state=?", "3");
- if (uEntity != null && !uEntity.isEmpty()) {
- waitList.addAll(uEntity);
+ }
+ } else if (type == 3) {
+ List wrappers = DbEntity.findRelationData(UTEWrapper.class,
+ "UploadTaskEntity.state=?", "3");
+ if (wrappers != null && !wrappers.isEmpty()) {
+ for (UTEWrapper w : wrappers) {
+ waitList.add(w.taskEntity);
}
- break;
+ }
}
return waitList;
}
@@ -146,8 +151,8 @@ class StartCmd extends AbsNormalCmd {
AbsTask task = getTask(te.getEntity());
if (task != null) continue;
if (te instanceof DownloadTaskEntity) {
- if (te.requestType == AbsTaskEntity.D_FTP || te.requestType == AbsTaskEntity.U_FTP) {
- te.urlEntity = CommonUtil.getFtpUrlInfo(te.getEntity().getKey());
+ if (te.getRequestType() == AbsTaskEntity.D_FTP || te.getRequestType() == AbsTaskEntity.U_FTP) {
+ te.setUrlEntity(CommonUtil.getFtpUrlInfo(te.getEntity().getKey()));
}
mQueue = DownloadTaskQueue.getInstance();
} else if (te instanceof UploadTaskEntity) {
diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java b/Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java
index c7fb1145..521284f5 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java
@@ -18,11 +18,13 @@ package com.arialyy.aria.core.common;
import android.content.Context;
import android.util.SparseArray;
import com.arialyy.aria.core.AriaManager;
+import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.AbsNormalEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IDownloadListener;
import com.arialyy.aria.core.inf.IEventListener;
+import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTaskEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
@@ -36,12 +38,13 @@ import java.util.concurrent.Executors;
/**
* Created by AriaL on 2017/7/1.
- * 文件下载器
+ * 任务处理器
*/
public abstract class AbsFileer>
implements Runnable, IUtil {
public static final String STATE = "_state_";
public static final String RECORD = "_record_";
+ protected static final long SUB_LEN = 1024 * 1024;
private final String TAG = "AbsFileer";
protected IEventListener mListener;
@@ -49,7 +52,7 @@ public abstract class AbsFileer 0) {
client = new FTPClient();
InetAddress ip = InetAddress.getByName(urlEntity.hostName);
+ client.setConnectTimeout(10000); // 连接10s超时
client.connect(ip, Integer.parseInt(urlEntity.port));
- mTaskEntity.urlEntity.validAddr = ip;
+ mTaskEntity.getUrlEntity().validAddr = ip;
} else {
InetAddress[] ips = InetAddress.getAllByName(urlEntity.hostName);
client = connect(new FTPClient(), ips, 0, Integer.parseInt(urlEntity.port));
@@ -211,10 +212,10 @@ public abstract class AbsFtpInfoThread>
+ implements IFtpTarget {
+ private static final String TAG = "FtpDelegate";
+ private ENTITY mEntity;
+ private TASK_ENTITY mTaskEntity;
+ private TARGET mTarget;
+
+ public FtpDelegate(TARGET target, TASK_ENTITY taskEntity) {
+ mTarget = target;
+ mTaskEntity = taskEntity;
+ mEntity = mTaskEntity.getEntity();
+ }
+
+ @Override public TARGET charSet(String charSet) {
+ if (TextUtils.isEmpty(charSet)) return mTarget;
+ mTaskEntity.setCharSet(charSet);
+ return mTarget;
+ }
+
+ @Override public TARGET login(String userName, String password) {
+ return login(userName, password, null);
+ }
+
+ @Override public TARGET login(String userName, String password, String account) {
+ if (TextUtils.isEmpty(userName)) {
+ ALog.e(TAG, "用户名不能为null");
+ return mTarget;
+ } else if (TextUtils.isEmpty(password)) {
+ ALog.e(TAG, "密码不能为null");
+ return mTarget;
+ }
+ mTaskEntity.getUrlEntity().needLogin = true;
+ mTaskEntity.getUrlEntity().user = userName;
+ mTaskEntity.getUrlEntity().password = password;
+ mTaskEntity.getUrlEntity().account = account;
+ return mTarget;
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/delegate/HttpHeaderDelegate.java b/Aria/src/main/java/com/arialyy/aria/core/delegate/HttpHeaderDelegate.java
new file mode 100644
index 00000000..998d3858
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/delegate/HttpHeaderDelegate.java
@@ -0,0 +1,139 @@
+/*
+ * 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.delegate;
+
+import android.support.annotation.NonNull;
+import android.text.TextUtils;
+import com.arialyy.aria.core.common.RequestEnum;
+import com.arialyy.aria.core.inf.AbsEntity;
+import com.arialyy.aria.core.inf.AbsTaskEntity;
+import com.arialyy.aria.core.inf.IHttpHeaderTarget;
+import com.arialyy.aria.core.inf.ITarget;
+import com.arialyy.aria.util.ALog;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Created by laoyuyu on 2018/3/9.
+ * HTTP header参数设置委托类
+ */
+public class HttpHeaderDelegate>
+ implements IHttpHeaderTarget {
+ private static final String TAG = "HttpHeaderDelegate";
+ private ENTITY mEntity;
+ private TASK_ENTITY mTaskEntity;
+ private TARGET mTarget;
+
+ public HttpHeaderDelegate(TARGET target, TASK_ENTITY taskEntity) {
+ mTarget = target;
+ mTaskEntity = taskEntity;
+
+ mEntity = mTaskEntity.getEntity();
+ }
+
+ /**
+ * 给url请求添加Header数据
+ * 如果新的header数据和数据保存的不一致,则更新数据库中对应的header数据
+ *
+ * @param key header对应的key
+ * @param value header对应的value
+ */
+ @Override
+ public TARGET addHeader(@NonNull String key, @NonNull String value) {
+ if (TextUtils.isEmpty(key)) {
+ ALog.w(TAG, "设置header失败,header对应的key不能为null");
+ return mTarget;
+ } else if (TextUtils.isEmpty(value)) {
+ ALog.w(TAG, "设置header失败,header对应的value不能为null");
+ return mTarget;
+ }
+ if (mTaskEntity.getHeaders().get(key) == null) {
+ mTaskEntity.getHeaders().put(key, value);
+ } else if (!mTaskEntity.getHeaders().get(key).equals(value)) {
+ mTaskEntity.getHeaders().put(key, value);
+ }
+ return mTarget;
+ }
+
+ /**
+ * 给url请求添加一组header数据
+ * 如果新的header数据和数据保存的不一致,则更新数据库中对应的header数据
+ *
+ * @param headers 一组http header数据
+ */
+ @Override
+ public TARGET addHeaders(@NonNull Map headers) {
+ if (headers.size() == 0) {
+ ALog.w(TAG, "设置header失败,map没有header数据");
+ return mTarget;
+ }
+ /*
+ 两个map比较逻辑
+ 1、比对key是否相同
+ 2、如果key相同,比对value是否相同
+ 3、只有当上面两个步骤中key 和 value都相同时才能任务两个map数据一致
+ */
+ boolean mapEquals = false;
+ if (mTaskEntity.getHeaders().size() == headers.size()) {
+ int i = 0;
+ Set keys = mTaskEntity.getHeaders().keySet();
+ for (String key : keys) {
+ if (headers.containsKey(key)) {
+ i++;
+ } else {
+ break;
+ }
+ }
+ if (i == mTaskEntity.getHeaders().size()) {
+ int j = 0;
+ Collection values = mTaskEntity.getHeaders().values();
+ for (String value : values) {
+ if (headers.containsValue(value)) {
+ j++;
+ } else {
+ break;
+ }
+ }
+ if (j == mTaskEntity.getHeaders().size()) {
+ mapEquals = true;
+ }
+ }
+ }
+
+ if (!mapEquals) {
+ mTaskEntity.getHeaders().clear();
+ Set keys = headers.keySet();
+ for (String key : keys) {
+ mTaskEntity.getHeaders().put(key, headers.get(key));
+ }
+ }
+
+ return mTarget;
+ }
+
+ /**
+ * 设置请求类型,POST或GET,默认为在GET
+ * 只试用于HTTP请求
+ *
+ * @param requestEnum {@link RequestEnum}
+ */
+ @Override
+ public TARGET setRequestMode(RequestEnum requestEnum) {
+ mTaskEntity.setRequestEnum(requestEnum);
+ return mTarget;
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/AbsDownloadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/AbsDownloadTarget.java
new file mode 100644
index 00000000..c48943e3
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/AbsDownloadTarget.java
@@ -0,0 +1,97 @@
+/*
+ * 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.download;
+
+import com.arialyy.aria.core.AriaManager;
+import com.arialyy.aria.core.command.normal.NormalCmdFactory;
+import com.arialyy.aria.core.inf.AbsEntity;
+import com.arialyy.aria.core.inf.AbsTarget;
+import com.arialyy.aria.core.inf.AbsTaskEntity;
+import com.arialyy.aria.util.CommonUtil;
+
+/**
+ * Created by lyy on 2017/2/28.
+ */
+abstract class AbsDownloadTarget
+ extends AbsTarget {
+
+ static final int HTTP = 1;
+ static final int FTP = 2;
+ //HTTP任务组
+ static final int GROUP_HTTP = 3;
+ //FTP文件夹
+ static final int GROUP_FTP_DIR = 4;
+
+ /**
+ * 设置的文件保存路径的临时变量
+ */
+ String mTempFilePath;
+
+ /**
+ * 将任务设置为最高优先级任务,最高优先级任务有以下特点:
+ * 1、在下载队列中,有且只有一个最高优先级任务
+ * 2、最高优先级任务会一直存在,直到用户手动暂停或任务完成
+ * 3、任务调度器不会暂停最高优先级任务
+ * 4、用户手动暂停或任务完成后,第二次重新执行该任务,该命令将失效
+ * 5、如果下载队列中已经满了,则会停止队尾的任务,当高优先级任务完成后,该队尾任务将自动执行
+ * 6、把任务设置为最高优先级任务后,将自动执行任务,不需要重新调用start()启动任务
+ */
+ protected void setHighestPriority() {
+ if (checkEntity()) {
+ AriaManager.getInstance(AriaManager.APP)
+ .setCmd(CommonUtil.createNormalCmd(mTargetName, mTaskEntity,
+ NormalCmdFactory.TASK_HIGHEST_PRIORITY, checkTaskType()))
+ .exe();
+ }
+ }
+
+ /**
+ * 添加任务
+ */
+ public void add() {
+ if (checkEntity()) {
+ AriaManager.getInstance(AriaManager.APP)
+ .setCmd(CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_CREATE,
+ checkTaskType()))
+ .exe();
+ }
+ }
+
+ /**
+ * 获取任务文件大小
+ *
+ * @return 文件大小
+ */
+ public long getFileSize() {
+ return getSize();
+ }
+
+ /**
+ * 获取单位转换后的文件大小
+ *
+ * @return 文件大小{@code xxx mb}
+ */
+ public String getConvertFileSize() {
+ return getConvertSize();
+ }
+
+ /**
+ * 设置target类型
+ *
+ * @return {@link #HTTP}、{@link #FTP}、{@link #GROUP_HTTP}、{@link #GROUP_FTP_DIR}
+ */
+ protected abstract int getTargetType();
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/BaseDListener.java b/Aria/src/main/java/com/arialyy/aria/core/download/BaseDListener.java
index 04b6d44f..30d6388f 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/BaseDListener.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/BaseDListener.java
@@ -150,11 +150,11 @@ class BaseDListener
- extends AbsDownloadTarget {
+abstract class BaseGroupTarget
+ extends AbsDownloadTarget {
- List mUrls = new ArrayList<>();
+ /**
+ * 组任务名
+ */
String mGroupName;
/**
- * 子任务文件名
+ * 文件夹临时路径
*/
- private List mSubTaskFileName = new ArrayList<>();
+ String mDirPathTemp;
/**
- * 是否已经设置了文件路径
+ * 是否需要修改路径
*/
- private boolean isSetDirPathed = false;
+ boolean needModifyPath = false;
private SubTaskManager mSubTaskManager;
@@ -63,10 +62,24 @@ abstract class BaseGroupTarget
*
- * @param groupDirPath 任务组保存文件夹路径
+ * @param dirPath 任务组保存文件夹路径
*/
- public TARGET setDownloadDirPath(String groupDirPath) {
- if (TextUtils.isEmpty(groupDirPath)) {
- throw new NullPointerException("任务组文件夹保存路径不能为null");
- }
-
- isSetDirPathed = true;
- if (mEntity.getDirPath().equals(groupDirPath)) return (TARGET) this;
-
- File file = new File(groupDirPath);
- if (file.exists() && file.isFile()) {
- throw new IllegalArgumentException("路径不能为文件");
- }
- if (!file.exists()) {
- file.mkdirs();
- }
-
- mEntity.setDirPath(groupDirPath);
- if (!TextUtils.isEmpty(mEntity.getDirPath())) {
- reChangeDirPath(groupDirPath);
- } else {
- mEntity.setSubTasks(createSubTask());
- }
- mEntity.update();
+ public TARGET setDirPath(String dirPath) {
+ mDirPathTemp = dirPath;
return (TARGET) this;
}
+ @Override public boolean isRunning() {
+ DownloadGroupTask task = DownloadGroupTaskQueue.getInstance().getTask(mEntity.getKey());
+ return task != null && task.isRunning();
+ }
+
/**
* 改变任务组文件夹路径,修改文件夹路径会将子任务所有路径更换
*
* @param newDirPath 新的文件夹路径
*/
- private void reChangeDirPath(String newDirPath) {
- List subTask = mEntity.getSubTask();
- if (subTask != null && !subTask.isEmpty()) {
- for (DownloadEntity entity : subTask) {
- String oldPath = entity.getDownloadPath();
- String newPath = newDirPath + "/" + entity.getFileName();
+ void reChangeDirPath(String newDirPath) {
+ List subTasks = mTaskEntity.getSubTaskEntities();
+ if (subTasks != null && !subTasks.isEmpty()) {
+ for (DownloadTaskEntity dte : subTasks) {
+ DownloadEntity de = dte.getEntity();
+ String oldPath = de.getDownloadPath();
+ String newPath = newDirPath + "/" + de.getFileName();
File file = new File(oldPath);
- file.renameTo(new File(newPath));
- DbEntity.exeSql("UPDATE DownloadEntity SET downloadPath='"
- + newPath
- + "' WHERE downloadPath='"
- + oldPath
- + "'");
- DbEntity.exeSql(
- "UPDATE DownloadTaskEntity SET key='" + newPath + "' WHERE key='" + oldPath + "'");
+ if (file.exists()) {
+ file.renameTo(new File(newPath));
+ }
+ de.setDownloadPath(newPath);
+ dte.setKey(newPath);
+ de.save();
+ dte.save();
}
- } else {
- mEntity.setSubTasks(createSubTask());
}
}
/**
- * 设置子任务文件名,该方法必须在{@link #setDownloadDirPath(String)}之后调用,否则不生效
+ * 检查并设置文件夹路径
*
- * @see #setSubFileName(List)
- */
- @Deprecated public TARGET setSubTaskFileName(List subTaskFileName) {
-
- return setSubFileName(subTaskFileName);
- }
-
- /**
- * 设置子任务文件名,该方法必须在{@link #setDownloadDirPath(String)}之后调用,否则不生效
+ * @return {@code true} 合法
*/
- public TARGET setSubFileName(List subTaskFileName) {
- if (subTaskFileName == null || subTaskFileName.isEmpty()) return (TARGET) this;
- mSubTaskFileName.addAll(subTaskFileName);
- if (mUrls.size() != subTaskFileName.size()) {
- throw new IllegalArgumentException("下载链接数必须要和保存路径的数量一致");
+ boolean checkDirPath() {
+ if (TextUtils.isEmpty(mDirPathTemp)) {
+ ALog.e(TAG, "文件夹路径不能为null");
+ return false;
+ } else if (!mDirPathTemp.startsWith("/")) {
+ ALog.e(TAG, "文件夹路径【" + mDirPathTemp + "】错误");
+ return false;
}
- if (isSetDirPathed) {
- List entities = mEntity.getSubTask();
- int i = 0;
- for (DownloadEntity entity : entities) {
- if (i < mSubTaskFileName.size()) {
- String newName = mSubTaskFileName.get(i);
- updateSubFileName(entity, newName);
- }
- i++;
- }
+ File file = new File(mDirPathTemp);
+ if (file.isFile()) {
+ ALog.e(TAG, "路径【" + mDirPathTemp + "】是文件,请设置文件夹路径");
+ return false;
}
- return (TARGET) this;
- }
- /**
- * 更新子任务文件名
- */
- private void updateSubFileName(DownloadEntity entity, String newName) {
- if (!newName.equals(entity.getFileName())) {
- String oldPath = mEntity.getDirPath() + "/" + entity.getFileName();
- String newPath = mEntity.getDirPath() + "/" + newName;
- File oldFile = new File(oldPath);
- if (oldFile.exists()) {
- oldFile.renameTo(new File(newPath));
+ if (TextUtils.isEmpty(mEntity.getDirPath()) || !mEntity.getDirPath().equals(mDirPathTemp)) {
+ if (!file.exists()) {
+ file.mkdirs();
}
- CommonUtil.renameDownloadConfig(oldFile.getName(), newName);
- DbEntity.exeSql(
- "UPDATE DownloadTaskEntity SET key='" + newPath + "' WHERE key='" + oldPath + "'");
- entity.setDownloadPath(newPath);
- entity.setFileName(newName);
- entity.update();
+ needModifyPath = true;
+ mEntity.setDirPath(mDirPathTemp);
}
- }
- /**
- * 创建子任务
- */
- private List createSubTask() {
- List list = new ArrayList<>();
- for (int i = 0, len = mUrls.size(); i < len; i++) {
- DownloadEntity entity = new DownloadEntity();
- entity.setUrl(mUrls.get(i));
- String fileName =
- mSubTaskFileName.isEmpty() ? createFileName(entity.getUrl()) : mSubTaskFileName.get(i);
- entity.setDownloadPath(mEntity.getDirPath() + "/" + fileName);
- entity.setGroupName(mGroupName);
- entity.setGroupChild(true);
- entity.setFileName(fileName);
- entity.insert();
- list.add(entity);
- }
- return list;
+ return true;
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/BaseNormalTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/BaseNormalTarget.java
new file mode 100644
index 00000000..c0b39569
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/BaseNormalTarget.java
@@ -0,0 +1,183 @@
+/*
+ * 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.download;
+
+import android.text.TextUtils;
+import com.arialyy.aria.core.manager.TEManager;
+import com.arialyy.aria.core.queue.DownloadTaskQueue;
+import com.arialyy.aria.orm.DbEntity;
+import com.arialyy.aria.util.ALog;
+import com.arialyy.aria.util.CommonUtil;
+import java.io.File;
+
+/**
+ * Created by Aria.Lao on 2017/7/26.
+ */
+abstract class BaseNormalTarget
+ extends AbsDownloadTarget {
+
+ /**
+ * 资源地址
+ */
+ protected String url;
+
+ /**
+ * 通过地址初始化target
+ */
+ void initTarget(String url, String targetName, boolean refreshInfo) {
+ this.url = url;
+ mTargetName = targetName;
+ mTaskEntity = TEManager.getInstance().getTEntity(DownloadTaskEntity.class, url);
+ mEntity = mTaskEntity.getEntity();
+ mTaskEntity.setRefreshInfo(refreshInfo);
+ if (mEntity != null) {
+ mTempFilePath = mEntity.getDownloadPath();
+ }
+ }
+
+ /**
+ * 将任务设置为最高优先级任务,最高优先级任务有以下特点:
+ * 1、在下载队列中,有且只有一个最高优先级任务
+ * 2、最高优先级任务会一直存在,直到用户手动暂停或任务完成
+ * 3、任务调度器不会暂停最高优先级任务
+ * 4、用户手动暂停或任务完成后,第二次重新执行该任务,该命令将失效
+ * 5、如果下载队列中已经满了,则会停止队尾的任务,当高优先级任务完成后,该队尾任务将自动执行
+ * 6、把任务设置为最高优先级任务后,将自动执行任务,不需要重新调用start()启动任务
+ */
+ @Override public void setHighestPriority() {
+ super.setHighestPriority();
+ }
+
+ /**
+ * 下载任务是否存在
+ *
+ * @return {@code true}任务存在
+ */
+ @Override public boolean taskExists() {
+ return DownloadTaskQueue.getInstance().getTask(mEntity.getUrl()) != null;
+ }
+
+ /**
+ * 获取下载实体
+ */
+ public DownloadEntity getDownloadEntity() {
+ return mEntity;
+ }
+
+ /**
+ * 是否在下载,该api后续版本会删除
+ *
+ * @deprecated {@link #isRunning()}
+ */
+ @Deprecated public boolean isDownloading() {
+ return isRunning();
+ }
+
+ /**
+ * 是否在下载
+ *
+ * @return {@code true}任务正在下载
+ */
+ @Override public boolean isRunning() {
+ DownloadTask task = DownloadTaskQueue.getInstance().getTask(mEntity.getKey());
+ return task != null && task.isRunning();
+ }
+
+ /**
+ * 检查下载实体,判断实体是否合法
+ * 合法标准为:
+ * 1、下载路径不为null,并且下载路径是正常的http或ftp路径
+ * 2、保存路径不为null,并且保存路径是android文件系统路径
+ * 3、保存路径不能重复
+ *
+ * @return {@code true}合法
+ */
+ @Override protected boolean checkEntity() {
+ boolean b = getTargetType() < GROUP_HTTP && checkUrl() && checkFilePath();
+ if (b) {
+ mEntity.save();
+ mTaskEntity.save();
+ }
+ return b;
+ }
+
+ /**
+ * 检查并设置普通任务的文件保存路径
+ *
+ * @return {@code true}保存路径合法
+ */
+ private boolean checkFilePath() {
+ String filePath = mTempFilePath;
+ if (TextUtils.isEmpty(filePath)) {
+ ALog.e(TAG, "下载失败,文件保存路径为null");
+ return false;
+ } else if (!filePath.startsWith("/")) {
+ ALog.e(TAG, "下载失败,文件保存路径【" + filePath + "】错误");
+ return false;
+ }
+ File file = new File(filePath);
+ if (file.isDirectory()) {
+ if (getTargetType() == HTTP) {
+ ALog.e(TAG, "下载失败,保存路径【" + filePath + "】不能为文件夹,路径需要是完整的文件路径,如:/mnt/sdcard/game.zip");
+ return false;
+ } else if (getTargetType() == FTP) {
+ filePath += mEntity.getFileName();
+ }
+ }
+ mEntity.setFileName(file.getName());
+
+ //设置文件保存路径,如果新文件路径和就文件路径不同,则修改路径
+ if (!filePath.equals(mEntity.getDownloadPath())) {
+ if (DbEntity.checkDataExist(DownloadEntity.class, "downloadPath=?", filePath)) {
+ ALog.e(TAG, "下载失败,保存路径【" + filePath + "】已经被其它任务占用,请设置其它保存路径");
+ return false;
+ }
+ File oldFile = new File(mEntity.getDownloadPath());
+ File newFile = new File(filePath);
+ mEntity.setDownloadPath(filePath);
+ mEntity.setFileName(newFile.getName());
+ mTaskEntity.setKey(filePath);
+ //mTaskEntity.update();
+ if (oldFile.exists()) {
+ oldFile.renameTo(newFile);
+ CommonUtil.renameDownloadConfig(oldFile.getName(), newFile.getName());
+ }
+ }
+ return true;
+ }
+
+ /**
+ * 检查普通任务的下载地址
+ *
+ * @return {@code true}地址合法
+ */
+ private boolean checkUrl() {
+ final String url = mEntity.getUrl();
+ if (TextUtils.isEmpty(url)) {
+ ALog.e(TAG, "下载失败,url为null");
+ return false;
+ } else if (!url.startsWith("http") && !url.startsWith("ftp")) {
+ ALog.e(TAG, "下载失败,url【" + url + "】错误");
+ return false;
+ }
+ int index = url.indexOf("://");
+ if (index == -1) {
+ ALog.e(TAG, "下载失败,url【" + url + "】不合法");
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java
index 91f11d1c..b22ae995 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadEntity.java
@@ -21,8 +21,9 @@ import android.os.Parcelable;
import android.text.TextUtils;
import com.arialyy.aria.core.inf.AbsNormalEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
-import com.arialyy.aria.orm.Foreign;
-import com.arialyy.aria.orm.Primary;
+import com.arialyy.aria.orm.ActionPolicy;
+import com.arialyy.aria.orm.annotation.Foreign;
+import com.arialyy.aria.orm.annotation.Primary;
import com.arialyy.aria.util.CommonUtil;
/**
@@ -30,33 +31,30 @@ import com.arialyy.aria.util.CommonUtil;
* 下载实体
*/
public class DownloadEntity extends AbsNormalEntity implements Parcelable {
- @Primary private String downloadPath = ""; //保存路径
+ @Primary private String downloadPath; //保存路径
/**
* 所属任务组
*/
- @Foreign(table = DownloadGroupEntity.class, column = "groupName") private String groupName = "";
+ @Foreign(parent = DownloadGroupEntity.class, column = "groupName",
+ onUpdate = ActionPolicy.CASCADE, onDelete = ActionPolicy.CASCADE)
+ private String groupName;
/**
- * 下载任务实体的key
- */
- @Foreign(table = DownloadTaskEntity.class, column = "key") private String taskKey = "";
-
- /**
- * 通过{@link AbsTaskEntity#md5Key}从服务器的返回信息中获取的文件md5信息,如果服务器没有返回,则不会设置该信息
+ * 从服务器的返回信息中获取的文件md5信息,如果服务器没有返回,则不会设置该信息
* 如果你已经设置了该任务的MD5信息,Aria也不会从服务器返回的信息中获取该信息
*/
- private String md5Code = "";
+ private String md5Code;
/**
- * 通过{@link AbsTaskEntity#dispositionKey}从服务器的返回信息中获取的文件描述信息
+ * 从服务器的返回信息中获取的文件描述信息
*/
- private String disposition = "";
+ private String disposition;
/**
* 从disposition获取到的文件名,如果可以获取到,则会赋值到这个字段
*/
- private String serverFileName = "";
+ private String serverFileName;
@Override public String getKey() {
return getUrl();
@@ -101,13 +99,6 @@ public class DownloadEntity extends AbsNormalEntity implements Parcelable {
this.groupName = groupName;
}
- /**
- * {@link #getUrl()}
- */
- @Deprecated public String getDownloadUrl() {
- return getUrl();
- }
-
public String getDownloadPath() {
return downloadPath;
}
@@ -117,8 +108,6 @@ public class DownloadEntity extends AbsNormalEntity implements Parcelable {
return this;
}
-
-
@Override public DownloadEntity clone() throws CloneNotSupportedException {
return (DownloadEntity) super.clone();
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java
index cb714c38..800a5974 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java
@@ -18,8 +18,7 @@ package com.arialyy.aria.core.download;
import android.os.Parcel;
import com.arialyy.aria.core.inf.AbsGroupEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
-import com.arialyy.aria.orm.OneToMany;
-import java.util.ArrayList;
+import com.arialyy.aria.orm.annotation.Ignore;
import java.util.List;
/**
@@ -28,22 +27,24 @@ import java.util.List;
*/
public class DownloadGroupEntity extends AbsGroupEntity {
- @OneToMany(table = DownloadEntity.class, key = "groupName") private List subtask =
- new ArrayList<>();
+ @Ignore private List subEntities;
/**
* 任务组下载文件的文件夹地址
*
- * @see DownloadGroupTarget#setDownloadDirPath(String)
+ * @see DownloadGroupTarget#setDirPath(String)
*/
- private String dirPath = "";
+ private String dirPath;
- public List getSubTask() {
- return subtask;
+ /**
+ * 子任务实体列表
+ */
+ public List getSubEntities() {
+ return subEntities;
}
- public void setSubTasks(List subTasks) {
- this.subtask = subTasks;
+ public void setSubEntities(List subTasks) {
+ this.subEntities = subTasks;
}
public String getDirPath() {
@@ -71,13 +72,13 @@ public class DownloadGroupEntity extends AbsGroupEntity {
@Override public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
- dest.writeTypedList(this.subtask);
+ dest.writeTypedList(this.subEntities);
dest.writeString(this.dirPath);
}
protected DownloadGroupEntity(Parcel in) {
super(in);
- this.subtask = in.createTypedArrayList(DownloadEntity.CREATOR);
+ this.subEntities = in.createTypedArrayList(DownloadEntity.CREATOR);
this.dirPath = in.readString();
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupListener.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupListener.java
index 321a8311..806d341f 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupListener.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupListener.java
@@ -86,7 +86,7 @@ class DownloadGroupListener
private void saveCurrentLocation() {
long location = 0;
- for (DownloadEntity e : mEntity.getSubTask()) {
+ for (DownloadEntity e : mEntity.getSubEntities()) {
location += e.getCurrentProgress();
}
mEntity.setCurrentProgress(location);
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java
index 9bd63dd7..7de286cb 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java
@@ -15,45 +15,53 @@
*/
package com.arialyy.aria.core.download;
-import com.arialyy.aria.core.inf.IEntity;
+import android.text.TextUtils;
import com.arialyy.aria.core.manager.TEManager;
-import com.arialyy.aria.core.queue.DownloadGroupTaskQueue;
import com.arialyy.aria.util.ALog;
-import com.arialyy.aria.util.CheckUtil;
import com.arialyy.aria.util.CommonUtil;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
/**
* Created by AriaL on 2017/6/29.
* 下载任务组
*/
-public class DownloadGroupTarget
- extends BaseGroupTarget {
- private final String TAG = "DownloadGroupTarget";
+public class DownloadGroupTarget extends BaseGroupTarget {
+ /**
+ * 子任务下载地址,
+ */
+ private List mUrls = new ArrayList<>();
+
+ /**
+ * 子任务文件名
+ */
+ private List mSubNameTemp = new ArrayList<>();
DownloadGroupTarget(DownloadGroupEntity groupEntity, String targetName) {
this.mTargetName = targetName;
if (groupEntity.getUrls() != null && !groupEntity.getUrls().isEmpty()) {
this.mUrls.addAll(groupEntity.getUrls());
}
- mGroupName = CommonUtil.getMd5Code(groupEntity.getUrls());
- mTaskEntity = TEManager.getInstance().getTEntity(DownloadGroupTaskEntity.class, mGroupName);
- if (mTaskEntity == null) {
- mTaskEntity =
- TEManager.getInstance().createTEntity(DownloadGroupTaskEntity.class, groupEntity);
- }
- mEntity = mTaskEntity.entity;
+ init();
}
DownloadGroupTarget(List urls, String targetName) {
this.mTargetName = targetName;
this.mUrls = urls;
- mGroupName = CommonUtil.getMd5Code(urls);
- mTaskEntity = TEManager.getInstance().getTEntity(DownloadGroupTaskEntity.class, mGroupName);
- if (mTaskEntity == null) {
- mTaskEntity = TEManager.getInstance().createGTEntity(DownloadGroupTaskEntity.class, mUrls);
+ init();
+ }
+
+ private void init() {
+ mGroupName = CommonUtil.getMd5Code(mUrls);
+ mTaskEntity = TEManager.getInstance().getGTEntity(DownloadGroupTaskEntity.class, mUrls);
+ mEntity = mTaskEntity.getEntity();
+
+ if (mEntity != null) {
+ mDirPathTemp = mEntity.getDirPath();
}
- mEntity = mTaskEntity.entity;
}
/**
@@ -71,7 +79,6 @@ public class DownloadGroupTarget
}
if (mEntity.getFileSize() <= 1 || mEntity.getFileSize() != fileSize) {
mEntity.setFileSize(fileSize);
- mEntity.update();
}
return this;
}
@@ -80,16 +87,165 @@ public class DownloadGroupTarget
* 如果你是使用{@link DownloadReceiver#load(DownloadGroupEntity)}进行下载操作,那么你需要设置任务组的下载地址
*/
public DownloadGroupTarget setGroupUrl(List urls) {
- CheckUtil.checkDownloadUrls(urls);
mUrls.clear();
mUrls.addAll(urls);
- mEntity.setGroupName(CommonUtil.getMd5Code(urls));
- mEntity.update();
return this;
}
- @Override public boolean isRunning() {
- DownloadGroupTask task = DownloadGroupTaskQueue.getInstance().getTask(mEntity.getKey());
- return task != null && task.isRunning();
+ /**
+ * 设置子任务文件名,该方法必须在{@link #setDirPath(String)}之后调用,否则不生效
+ *
+ * @deprecated {@link #setSubFileName(List)} 请使用该api
+ */
+ @Deprecated public DownloadGroupTarget setSubTaskFileName(List subTaskFileName) {
+ return setSubFileName(subTaskFileName);
+ }
+
+ /**
+ * 设置子任务文件名,该方法必须在{@link #setDirPath(String)}之后调用,否则不生效
+ */
+ public DownloadGroupTarget setSubFileName(List subTaskFileName) {
+ if (subTaskFileName == null || subTaskFileName.isEmpty()) {
+ ALog.e(TAG, "修改子任务的文件名失败:列表为null");
+ return this;
+ }
+ if (subTaskFileName.size() != mTaskEntity.getSubTaskEntities().size()) {
+ ALog.e(TAG, "修改子任务的文件名失败:子任务文件名列表数量和子任务的数量不匹配");
+ return this;
+ }
+ mSubNameTemp.clear();
+ mSubNameTemp.addAll(subTaskFileName);
+ return this;
+ }
+
+ @Override protected int getTargetType() {
+ return GROUP_HTTP;
+ }
+
+ @Override protected boolean checkEntity() {
+ if (getTargetType() == GROUP_HTTP) {
+ if (!checkDirPath()) {
+ return false;
+ }
+
+ if (!checkSubName()) {
+ return false;
+ }
+
+ if (!checkUrls()) {
+ return false;
+ }
+
+ mEntity.save();
+ mTaskEntity.save();
+
+ if (needModifyPath) {
+ reChangeDirPath(mDirPathTemp);
+ }
+
+ if (!mSubNameTemp.isEmpty()) {
+ updateSingleSubFileName();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * 更新所有改动的子任务文件名
+ */
+ private void updateSingleSubFileName() {
+ List entities = mTaskEntity.getSubTaskEntities();
+ int i = 0;
+ for (DownloadTaskEntity entity : entities) {
+ if (i < mSubNameTemp.size()) {
+ String newName = mSubNameTemp.get(i);
+ updateSingleSubFileName(entity, newName);
+ }
+ i++;
+ }
+ }
+
+ /**
+ * 检查urls是否合法,并删除不合法的子任务
+ *
+ * @return {@code true} 合法
+ */
+ private boolean checkUrls() {
+ if (mUrls.isEmpty()) {
+ ALog.e(TAG, "下载失败,子任务下载列表为null");
+ return false;
+ }
+ Set delItem = new HashSet<>();
+
+ int i = 0;
+ for (String url : mUrls) {
+ if (TextUtils.isEmpty(url)) {
+ ALog.e(TAG, "子任务url为null,即将删除该子任务。");
+ delItem.add(i);
+ continue;
+ } else if (!url.startsWith("http")) {
+ //} else if (!url.startsWith("http") && !url.startsWith("ftp")) {
+ ALog.e(TAG, "子任务url【" + url + "】错误,即将删除该子任务。");
+ delItem.add(i);
+ continue;
+ }
+ int index = url.indexOf("://");
+ if (index == -1) {
+ ALog.e(TAG, "子任务url【" + url + "】不合法,即将删除该子任务。");
+ delItem.add(i);
+ continue;
+ }
+
+ i++;
+ }
+
+ for (int index : delItem) {
+ mUrls.remove(index);
+ if (mSubNameTemp != null && !mSubNameTemp.isEmpty()) {
+ mSubNameTemp.remove(index);
+ }
+ }
+
+ mEntity.setGroupName(CommonUtil.getMd5Code(mUrls));
+
+ return true;
+ }
+
+ /**
+ * 更新单个子任务文件名
+ */
+ private void updateSingleSubFileName(DownloadTaskEntity taskEntity, String newName) {
+ DownloadEntity entity = taskEntity.getEntity();
+ if (!newName.equals(entity.getFileName())) {
+ String oldPath = mEntity.getDirPath() + "/" + entity.getFileName();
+ String newPath = mEntity.getDirPath() + "/" + newName;
+ File oldFile = new File(oldPath);
+ if (oldFile.exists()) {
+ oldFile.renameTo(new File(newPath));
+ }
+ CommonUtil.renameDownloadConfig(oldFile.getName(), newName);
+ entity.setDownloadPath(newPath);
+ taskEntity.setKey(newPath);
+ entity.setFileName(newName);
+ entity.update();
+ }
+ }
+
+ /**
+ * 如果用户设置了子任务文件名,检查子任务文件名
+ *
+ * @return {@code true} 合法
+ */
+ private boolean checkSubName() {
+ if (mSubNameTemp == null || mSubNameTemp.isEmpty()) {
+ return true;
+ }
+ if (mUrls.size() != mSubNameTemp.size()) {
+ ALog.e(TAG, "子任务文件名必须和子任务数量一致");
+ return false;
+ }
+
+ return true;
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java
index ee2b44b4..6977202a 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java
@@ -41,7 +41,7 @@ public class DownloadGroupTask extends AbsGroupTask {
mOutHandler = outHandler;
mContext = AriaManager.APP;
mListener = new DownloadGroupListener(this, mOutHandler);
- switch (taskEntity.requestType) {
+ switch (taskEntity.getRequestType()) {
case AbsTaskEntity.D_HTTP:
mUtil = new DownloadGroupUtil(mListener, mTaskEntity);
break;
@@ -71,15 +71,17 @@ public class DownloadGroupTask extends AbsGroupTask {
@Override public void stop() {
if (!mUtil.isRunning()) {
mListener.onStop(getCurrentProgress());
+ } else {
+ mUtil.stop();
}
- mUtil.stop();
}
@Override public void cancel() {
if (!mUtil.isRunning()) {
mListener.onCancel();
+ } else {
+ mUtil.cancel();
}
- mUtil.cancel();
}
@Override public String getTaskName() {
@@ -116,7 +118,6 @@ public class DownloadGroupTask extends AbsGroupTask {
public DownloadGroupTask build() {
DownloadGroupTask task = new DownloadGroupTask(taskEntity, outHandler);
task.setTargetName(targetName);
- taskEntity.save();
return task;
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTaskEntity.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTaskEntity.java
index 72ecdc31..0fff9682 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTaskEntity.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTaskEntity.java
@@ -16,24 +16,48 @@
package com.arialyy.aria.core.download;
import com.arialyy.aria.core.inf.AbsGroupTaskEntity;
-import com.arialyy.aria.orm.OneToOne;
+import com.arialyy.aria.orm.ActionPolicy;
+import com.arialyy.aria.orm.annotation.Foreign;
+import com.arialyy.aria.orm.annotation.Ignore;
+import com.arialyy.aria.orm.annotation.Primary;
+import java.util.List;
/**
* Created by AriaL on 2017/7/1.
+ * 任务组的任务实体
*/
public class DownloadGroupTaskEntity extends AbsGroupTaskEntity {
- @OneToOne(table = DownloadGroupEntity.class, key = "groupName") public DownloadGroupEntity entity;
+ @Ignore private DownloadGroupEntity entity;
+
+ @Ignore private List subTaskEntities;
+
+ @Primary
+ @Foreign(parent = DownloadGroupEntity.class, column = "groupName",
+ onUpdate = ActionPolicy.CASCADE, onDelete = ActionPolicy.CASCADE)
+ private String key;
@Override public DownloadGroupEntity getEntity() {
return entity;
}
+ public void setEntity(DownloadGroupEntity entity) {
+ this.entity = entity;
+ }
+
+ public List getSubTaskEntities() {
+ return subTaskEntities;
+ }
+
+ public void setSubTaskEntities(List subTaskEntities) {
+ this.subTaskEntities = subTaskEntities;
+ }
+
+ @Override public String getKey() {
+ return key;
+ }
- public void save(DownloadGroupEntity groupEntity){
- key = groupEntity.getKey();
- entity = groupEntity;
- groupEntity.save();
- save();
+ public void setKey(String key) {
+ this.key = key;
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java
index 21ca515b..9fccd6d5 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java
@@ -22,13 +22,15 @@ import com.arialyy.aria.core.command.ICmd;
import com.arialyy.aria.core.command.normal.CancelAllCmd;
import com.arialyy.aria.core.command.normal.NormalCmdFactory;
import com.arialyy.aria.core.common.ProxyHelper;
+import com.arialyy.aria.core.download.wrapper.DGEWrapper;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.AbsReceiver;
import com.arialyy.aria.core.inf.AbsTarget;
+import com.arialyy.aria.core.manager.TEManager;
import com.arialyy.aria.core.scheduler.DownloadGroupSchedulers;
import com.arialyy.aria.core.scheduler.DownloadSchedulers;
-import com.arialyy.aria.core.scheduler.ISchedulerListener;
import com.arialyy.aria.orm.DbEntity;
+import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CheckUtil;
import com.arialyy.aria.util.CommonUtil;
import java.util.ArrayList;
@@ -41,7 +43,6 @@ import java.util.Set;
*/
public class DownloadReceiver extends AbsReceiver {
private final String TAG = "DownloadReceiver";
- public ISchedulerListener listener;
/**
* 设置最大下载速度,单位:kb
@@ -49,8 +50,8 @@ public class DownloadReceiver extends AbsReceiver {
*
* @param maxSpeed 为0表示不限速
*/
- @Deprecated public void setMaxSpeed(double maxSpeed) {
- AriaManager.getInstance(AriaManager.APP).getDownloadConfig().setMsxSpeed(maxSpeed);
+ @Deprecated public void setMaxSpeed(int maxSpeed) {
+ AriaManager.getInstance(AriaManager.APP).getDownloadConfig().setMaxSpeed(maxSpeed);
}
/**
@@ -108,14 +109,25 @@ public class DownloadReceiver extends AbsReceiver {
*
*/
@Deprecated public DownloadTarget load(@NonNull String url, boolean refreshInfo) {
- url = CheckUtil.checkUrl(url);
+ CheckUtil.checkUrlInvalidThrow(url);
return new DownloadTarget(url, targetName, refreshInfo);
}
/**
* 加载下载地址,如果任务组的中的下载地址改变了,则任务从新的一个任务组
+ *
+ * @param urls 任务组子任务下载地址列表
+ * @deprecated {@link #loadGroup(DownloadGroupEntity)}
*/
+ @Deprecated
public DownloadGroupTarget load(List urls) {
+ return loadGroup(urls);
+ }
+
+ /**
+ * 加载下载地址,如果任务组的中的下载地址改变了,则任务从新的一个任务组
+ */
+ public DownloadGroupTarget loadGroup(List urls) {
CheckUtil.checkDownloadUrls(urls);
return new DownloadGroupTarget(urls, targetName);
}
@@ -165,17 +177,29 @@ public class DownloadReceiver extends AbsReceiver {
* @param refreshInfo 是否刷新下载信息
*/
public FtpDownloadTarget loadFtp(@NonNull String url, boolean refreshInfo) {
- url = CheckUtil.checkUrl(url);
+ CheckUtil.checkUrlInvalidThrow(url);
return new FtpDownloadTarget(url, targetName, refreshInfo);
}
/**
- * 使用任务组实体执行任务组的实体执行任务组的下载操作
+ * 使用任务组实体执行任务组的实体执行任务组的下载操作,后续版本会删除该api
*
* @param groupEntity 如果加载的任务实体没有子项的下载地址,
* 那么你需要使用{@link DownloadGroupTarget#setGroupUrl(List)}设置子项的下载地址
+ * @deprecated 请使用 {@link #loadGroup(DownloadGroupEntity)}
*/
+ @Deprecated
public DownloadGroupTarget load(DownloadGroupEntity groupEntity) {
+ return loadGroup(groupEntity);
+ }
+
+ /**
+ * 使用任务组实体执行任务组的实体执行任务组的下载操作
+ *
+ * @param groupEntity 如果加载的任务实体没有子项的下载地址,
+ * 那么你需要使用{@link DownloadGroupTarget#setGroupUrl(List)}设置子项的下载地址
+ */
+ public DownloadGroupTarget loadGroup(DownloadGroupEntity groupEntity) {
return new DownloadGroupTarget(groupEntity, targetName);
}
@@ -183,7 +207,7 @@ public class DownloadReceiver extends AbsReceiver {
* 加载ftp文件夹下载地址
*/
public FtpDirDownloadTarget loadFtpDir(@NonNull String dirUrl) {
- dirUrl = CheckUtil.checkUrl(dirUrl);
+ CheckUtil.checkUrlInvalidThrow(dirUrl);
return new FtpDirDownloadTarget(dirUrl, targetName);
}
@@ -207,6 +231,7 @@ public class DownloadReceiver extends AbsReceiver {
/**
* 取消注册,如果是Activity或fragment,Aria会界面销毁时自动调用该方法。
+ * 如果在activity中一定要调用该方法,那么请在onDestroy()中调用
* 如果是Dialog或popupwindow,需要你在撤销界面时调用该方法
*/
@Override public void unRegister() {
@@ -232,44 +257,59 @@ public class DownloadReceiver extends AbsReceiver {
@Override public void destroy() {
targetName = null;
- listener = null;
}
/**
* 通过下载链接获取下载实体
+ *
+ * @return 如果url错误或查找不到数据,则返回null
*/
public DownloadEntity getDownloadEntity(String downloadUrl) {
- downloadUrl = CheckUtil.checkUrl(downloadUrl);
+ if (CheckUtil.checkUrl(downloadUrl)) {
+ return null;
+ }
return DbEntity.findFirst(DownloadEntity.class, "url=? and isGroupChild='false'", downloadUrl);
}
/**
- * 通过下载链接获取保存在数据库的下载任务实体
+ * 通过下载地址和文件保存路径获取下载任务实体
+ *
+ * @param downloadUrl 下载地址
+ * @return 如果url错误或查找不到数据,则返回null
*/
public DownloadTaskEntity getDownloadTask(String downloadUrl) {
- downloadUrl = CheckUtil.checkUrl(downloadUrl);
- DownloadEntity entity = getDownloadEntity(downloadUrl);
- if (entity == null || TextUtils.isEmpty(entity.getDownloadPath())) return null;
- return DbEntity.findFirst(DownloadTaskEntity.class, "key=? and isGroupTask='false'",
- entity.getDownloadPath());
+ if (CheckUtil.checkUrl(downloadUrl)) {
+ return null;
+ }
+ return TEManager.getInstance().getTEntity(DownloadTaskEntity.class, downloadUrl);
}
/**
* 通过下载链接获取保存在数据库的下载任务组实体
+ *
+ * @param urls 任务组子任务下载地址列表
+ * @return 返回对应的任务组实体;如果查找不到对应的数据或子任务列表为null,返回null
*/
- public DownloadGroupTaskEntity getDownloadGroupTask(List urls) {
- CheckUtil.checkDownloadUrls(urls);
- String hashCode = CommonUtil.getMd5Code(urls);
- return DbEntity.findFirst(DownloadGroupTaskEntity.class, "key=?", hashCode);
+ public DownloadGroupTaskEntity getGroupTask(List urls) {
+ if (urls == null || urls.isEmpty()) {
+ ALog.e(TAG, "获取任务组实体失败:任务组子任务下载地址列表为null");
+ return null;
+ }
+ return TEManager.getInstance().getGTEntity(DownloadGroupTaskEntity.class, urls);
}
/**
- * 通过任务组key,获取任务组实体
- * 如果是http,key为所有子任务下载地址拼接后取md5
- * 如果是ftp,key为ftp服务器的文件夹路径
+ * 获取FTP文件夹下载任务实体
+ *
+ * @param dirUrl FTP文件夹本地下载路径
+ * @return 返回对应的任务组实体;如果查找不到对应的数据或路径为null,返回null
*/
- public DownloadGroupTaskEntity getDownloadGroupTask(String key) {
- return DbEntity.findFirst(DownloadGroupTaskEntity.class, "key=?", key);
+ public DownloadGroupTaskEntity getFtpDirTask(String dirUrl) {
+ if (TextUtils.isEmpty(dirUrl)) {
+ ALog.e(TAG, "获取FTP文件夹实体失败:下载路径为null");
+ return null;
+ }
+ return TEManager.getInstance().getFDTEntity(DownloadGroupTaskEntity.class, dirUrl);
}
/**
@@ -307,15 +347,25 @@ public class DownloadReceiver extends AbsReceiver {
/**
* 获取任务组列表
+ *
+ * @return 如果没有任务组列表,则返回null
*/
public List getGroupTaskList() {
- return DownloadEntity.findAllData(DownloadGroupEntity.class);
+ List wrappers = DbEntity.findRelationData(DGEWrapper.class);
+ if (wrappers == null || wrappers.isEmpty()) {
+ return null;
+ }
+ List entities = new ArrayList<>();
+ for (DGEWrapper wrapper : wrappers) {
+ entities.add(wrapper.groupEntity);
+ }
+ return entities;
}
/**
* 获取普通任务和任务组的任务列表
*/
- public List getTotleTaskList() {
+ public List getTotalTaskList() {
List list = new ArrayList<>();
List simpleTask = getTaskList();
List groupTask = getGroupTaskList();
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java
index 5a8b20ed..cba839aa 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTarget.java
@@ -16,35 +16,25 @@
package com.arialyy.aria.core.download;
import android.support.annotation.NonNull;
-import android.text.TextUtils;
-import com.arialyy.aria.core.inf.AbsDownloadTarget;
-import com.arialyy.aria.core.manager.TEManager;
-import com.arialyy.aria.core.queue.DownloadTaskQueue;
-import com.arialyy.aria.orm.DbEntity;
-import com.arialyy.aria.util.CommonUtil;
-import java.io.File;
+import com.arialyy.aria.core.common.RequestEnum;
+import com.arialyy.aria.core.delegate.HttpHeaderDelegate;
+import com.arialyy.aria.core.inf.IHttpHeaderTarget;
+import java.util.Map;
/**
* Created by lyy on 2016/12/5.
* https://github.com/AriaLyy/Aria
*/
-public class DownloadTarget
- extends AbsDownloadTarget {
- protected String url;
+public class DownloadTarget extends BaseNormalTarget
+ implements IHttpHeaderTarget {
+ private HttpHeaderDelegate mDelegate;
DownloadTarget(DownloadEntity entity, String targetName) {
this(entity, targetName, false);
}
DownloadTarget(DownloadEntity entity, String targetName, boolean refreshInfo) {
- this.url = entity.getUrl();
- mTargetName = targetName;
- mTaskEntity = TEManager.getInstance().getTEntity(DownloadTaskEntity.class, url);
- if (mTaskEntity == null) {
- mTaskEntity = TEManager.getInstance().createTEntity(DownloadTaskEntity.class, entity);
- }
- mEntity = mTaskEntity.entity;
- mTaskEntity.refreshInfo = refreshInfo;
+ this(entity.getUrl(), targetName, refreshInfo);
}
DownloadTarget(String url, String targetName) {
@@ -52,14 +42,8 @@ public class DownloadTarget
}
DownloadTarget(String url, String targetName, boolean refreshInfo) {
- this.url = url;
- mTargetName = targetName;
- mTaskEntity = TEManager.getInstance().getTEntity(DownloadTaskEntity.class, url);
- if (mTaskEntity == null) {
- mTaskEntity = TEManager.getInstance().createTEntity(DownloadTaskEntity.class, url);
- }
- mEntity = mTaskEntity.entity;
- mTaskEntity.refreshInfo = refreshInfo;
+ initTarget(url, targetName, refreshInfo);
+ mDelegate = new HttpHeaderDelegate<>(this, mTaskEntity);
}
/**
@@ -69,31 +53,20 @@ public class DownloadTarget
*
* @param use {@code true} 使用
*/
- @Deprecated public DownloadTarget useServerFileName(boolean use) {
- mTaskEntity.useServerFileName = use;
+ public DownloadTarget useServerFileName(boolean use) {
+ mTaskEntity.setUseServerFileName(use);
return this;
}
/**
- * 将任务设置为最高优先级任务,最高优先级任务有以下特点:
- * 1、在下载队列中,有且只有一个最高优先级任务
- * 2、最高优先级任务会一直存在,直到用户手动暂停或任务完成
- * 3、任务调度器不会暂停最高优先级任务
- * 4、用户手动暂停或任务完成后,第二次重新执行该任务,该命令将失效
- * 5、如果下载队列中已经满了,则会停止队尾的任务,当高优先级任务完成后,该队尾任务将自动执行
- * 6、把任务设置为最高优先级任务后,将自动执行任务,不需要重新调用start()启动任务
- */
- @Override public void setHighestPriority() {
- super.setHighestPriority();
- }
-
- /**
- * 下载任务是否存在
+ * 设置文件存储路径
+ * 该api后续版本会删除
*
- * @return {@code true}任务存在
+ * @param downloadPath 文件保存路径
+ * @deprecated {@link #setFilePath(String)} 请使用这个api
*/
- @Override public boolean taskExists() {
- return DownloadTaskQueue.getInstance().getTask(mEntity.getUrl()) != null;
+ @Deprecated public DownloadTarget setDownloadPath(@NonNull String downloadPath) {
+ return setFilePath(downloadPath);
}
/**
@@ -101,38 +74,13 @@ public class DownloadTarget
* 如:原文件路径 /mnt/sdcard/test.zip
* 如果需要将test.zip改为game.zip,只需要重新设置文件路径为:/mnt/sdcard/game.zip
*
- * @param downloadPath 路径必须为文件路径,不能为文件夹路径
+ * @param filePath 路径必须为文件路径,不能为文件夹路径
*/
- public DownloadTarget setDownloadPath(@NonNull String downloadPath) {
- if (TextUtils.isEmpty(downloadPath)) {
- throw new IllegalArgumentException("文件保持路径不能为null");
- }
- File file = new File(downloadPath);
- if (file.isDirectory()) {
- throw new IllegalArgumentException("保存路径不能为文件夹,路径需要是完整的文件路径,如:/mnt/sdcard/game.zip");
- }
- if (!downloadPath.equals(mEntity.getDownloadPath())) {
- if (!mTaskEntity.refreshInfo && DbEntity.checkDataExist(DownloadEntity.class,
- "downloadPath=?", downloadPath)) {
- throw new IllegalArgumentException("保存路径【" + downloadPath + "】已经被其它任务占用,请设置其它保存路径");
- }
- File oldFile = new File(mEntity.getDownloadPath());
- File newFile = new File(downloadPath);
- if (TextUtils.isEmpty(mEntity.getDownloadPath()) || oldFile.renameTo(newFile)) {
- mEntity.setDownloadPath(downloadPath);
- mEntity.setFileName(newFile.getName());
- mTaskEntity.key = downloadPath;
- mTaskEntity.update();
- CommonUtil.renameDownloadConfig(oldFile.getName(), newFile.getName());
- }
- }
+ public DownloadTarget setFilePath(@NonNull String filePath) {
+ mTempFilePath = filePath;
return this;
}
- public DownloadEntity getDownloadEntity() {
- return mEntity;
- }
-
/**
* 从header中获取文件描述信息
*/
@@ -140,17 +88,19 @@ public class DownloadTarget
return mEntity.getDisposition();
}
- /**
- * 是否在下载
- *
- * @deprecated {@link #isRunning()}
- */
- public boolean isDownloading() {
- return isRunning();
+ @Override protected int getTargetType() {
+ return HTTP;
+ }
+
+ @Override public DownloadTarget addHeader(@NonNull String key, @NonNull String value) {
+ return mDelegate.addHeader(key, value);
+ }
+
+ @Override public DownloadTarget addHeaders(Map headers) {
+ return mDelegate.addHeaders(headers);
}
- @Override public boolean isRunning() {
- DownloadTask task = DownloadTaskQueue.getInstance().getTask(mEntity.getKey());
- return task != null && task.isRunning();
+ @Override public DownloadTarget setRequestMode(RequestEnum requestEnum) {
+ return mDelegate.setRequestMode(requestEnum);
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java
index b45a9478..ea770433 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java
@@ -18,7 +18,6 @@ package com.arialyy.aria.core.download;
import android.os.Handler;
import android.os.Looper;
-import android.util.Log;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.IUtil;
import com.arialyy.aria.core.download.downloader.SimpleDownloadUtil;
@@ -78,16 +77,12 @@ public class DownloadTask extends AbsNormalTask {
}
/**
- * 任务下载状态
+ * 是否真正下载
*
- * @see DownloadTask#isRunning()
+ * @return {@code true} 真正下载
*/
- @Deprecated public boolean isDownloading() {
- return mUtil.isRunning();
- }
-
@Override public boolean isRunning() {
- return isDownloading();
+ return mUtil.isRunning();
}
public DownloadEntity getDownloadEntity() {
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java
index f7d84ad5..9803d604 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java
@@ -16,31 +16,51 @@
package com.arialyy.aria.core.download;
import com.arialyy.aria.core.inf.AbsNormalTaskEntity;
-import com.arialyy.aria.orm.NoNull;
-import com.arialyy.aria.orm.OneToOne;
+import com.arialyy.aria.orm.ActionPolicy;
+import com.arialyy.aria.orm.annotation.Foreign;
+import com.arialyy.aria.orm.annotation.Ignore;
+import com.arialyy.aria.orm.annotation.NoNull;
+import com.arialyy.aria.orm.annotation.Primary;
/**
* Created by lyy on 2017/1/23.
- * 下载任务实体
+ * 下载任务实体和下载实体为一对一关系,下载实体删除,任务实体自动删除
*/
public class DownloadTaskEntity extends AbsNormalTaskEntity {
- @OneToOne(table = DownloadEntity.class, key = "downloadPath") public DownloadEntity entity;
+ @Ignore private DownloadEntity entity;
/**
* 任务的url
*/
- @NoNull public String url = "";
+ @NoNull private String url;
/**
* 所属的任务组组名,如果不属于任务组,则为null
*/
- public String groupName = "";
+ @Foreign(parent = DownloadGroupTaskEntity.class, column = "key",
+ onUpdate = ActionPolicy.CASCADE, onDelete = ActionPolicy.CASCADE)
+ private String groupName;
+
+ /**
+ * 是否是chunk模式
+ */
+ private boolean isChunked = false;
/**
* 该任务是否属于任务组
*/
- public boolean isGroupTask = false;
+ private boolean isGroupTask = false;
+
+ /**
+ * Task实体对应的key
+ */
+ @Primary
+ @Foreign(parent = DownloadEntity.class, column = "downloadPath",
+ onUpdate = ActionPolicy.CASCADE, onDelete = ActionPolicy.CASCADE)
+ private String key;
+
+
public DownloadTaskEntity() {
}
@@ -49,13 +69,47 @@ public class DownloadTaskEntity extends AbsNormalTaskEntity {
return entity;
}
- public void save(DownloadEntity entity) {
+ @Override public String getKey() {
+ return key;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public String getGroupName() {
+ return groupName;
+ }
+
+ public boolean isChunked() {
+ return isChunked;
+ }
+
+ public boolean isGroupTask() {
+ return isGroupTask;
+ }
+
+ public void setEntity(DownloadEntity entity) {
this.entity = entity;
- if (entity != null) {
- url = entity.getUrl();
- key = entity.getDownloadPath();
- entity.save();
- }
- save();
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public void setGroupName(String groupName) {
+ this.groupName = groupName;
+ }
+
+ public void setChunked(boolean chunked) {
+ isChunked = chunked;
+ }
+
+ public void setGroupTask(boolean groupTask) {
+ isGroupTask = groupTask;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/FtpDirDownloadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/FtpDirDownloadTarget.java
index f7c51df7..60f99319 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/FtpDirDownloadTarget.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/FtpDirDownloadTarget.java
@@ -16,18 +16,19 @@
package com.arialyy.aria.core.download;
import android.text.TextUtils;
+import com.arialyy.aria.core.delegate.FtpDelegate;
import com.arialyy.aria.core.inf.AbsTaskEntity;
+import com.arialyy.aria.core.inf.IFtpTarget;
import com.arialyy.aria.core.manager.TEManager;
-import com.arialyy.aria.core.queue.DownloadGroupTaskQueue;
import com.arialyy.aria.util.ALog;
/**
* Created by Aria.Lao on 2017/7/26.
* ftp文件夹下载
*/
-public class FtpDirDownloadTarget
- extends BaseGroupTarget {
- private final String TAG = "FtpDirDownloadTarget";
+public class FtpDirDownloadTarget extends BaseGroupTarget
+ implements IFtpTarget {
+ private FtpDelegate mDelegate;
FtpDirDownloadTarget(String url, String targetName) {
mTargetName = targetName;
@@ -36,57 +37,68 @@ public class FtpDirDownloadTarget
private void init(String key) {
mGroupName = key;
- mTaskEntity = TEManager.getInstance().getTEntity(DownloadGroupTaskEntity.class, key);
- if (mTaskEntity == null) {
- mTaskEntity = TEManager.getInstance().createTEntity(DownloadGroupTaskEntity.class, key);
+ mTaskEntity = TEManager.getInstance().getFDTEntity(DownloadGroupTaskEntity.class, key);
+ mTaskEntity.setRequestType(AbsTaskEntity.D_FTP_DIR);
+ mEntity = mTaskEntity.getEntity();
+ if (mEntity != null) {
+ mDirPathTemp = mEntity.getDirPath();
}
- mTaskEntity.requestType = AbsTaskEntity.D_FTP_DIR;
- mEntity = mTaskEntity.entity;
+ mDelegate = new FtpDelegate<>(this, mTaskEntity);
}
- /**
- * 设置字符编码
- */
- public FtpDirDownloadTarget charSet(String charSet) {
- if (TextUtils.isEmpty(charSet)) return this;
- mTaskEntity.charSet = charSet;
- return this;
+ @Override protected int getTargetType() {
+ return GROUP_FTP_DIR;
}
- /**
- * ftp 用户登录信息
- *
- * @param userName ftp用户名
- * @param password ftp用户密码
- */
- public FtpDirDownloadTarget login(String userName, String password) {
- return login(userName, password, null);
+ @Override protected boolean checkEntity() {
+ boolean b = getTargetType() == GROUP_FTP_DIR && checkDirPath() && checkUrl();
+ if (b) {
+ mEntity.save();
+ mTaskEntity.save();
+ if (mTaskEntity.getSubTaskEntities() != null) {
+ //初始化子项的登录信息
+ for (DownloadTaskEntity entity : mTaskEntity.getSubTaskEntities()) {
+ entity.getUrlEntity().needLogin = mTaskEntity.getUrlEntity().needLogin;
+ entity.getUrlEntity().account = mTaskEntity.getUrlEntity().account;
+ entity.getUrlEntity().user = mTaskEntity.getUrlEntity().user;
+ entity.getUrlEntity().password = mTaskEntity.getUrlEntity().password;
+ }
+ }
+ }
+ return b;
}
/**
- * ftp 用户登录信息
+ * 检查普通任务的下载地址
*
- * @param userName ftp用户名
- * @param password ftp用户密码
- * @param account ftp账号
+ * @return {@code true}地址合法
*/
- public FtpDirDownloadTarget login(String userName, String password, String account) {
- if (TextUtils.isEmpty(userName)) {
- ALog.e(TAG, "用户名不能为null");
- return this;
- } else if (TextUtils.isEmpty(password)) {
- ALog.e(TAG, "密码不能为null");
- return this;
+ private boolean checkUrl() {
+ final String url = mGroupName;
+ if (TextUtils.isEmpty(url)) {
+ ALog.e(TAG, "下载失败,url为null");
+ return false;
+ } else if (!url.startsWith("ftp")) {
+ ALog.e(TAG, "下载失败,url【" + url + "】错误");
+ return false;
}
- mTaskEntity.urlEntity.needLogin = true;
- mTaskEntity.urlEntity.user = userName;
- mTaskEntity.urlEntity.password = password;
- mTaskEntity.urlEntity.account = account;
- return this;
+ int index = url.indexOf("://");
+ if (index == -1) {
+ ALog.e(TAG, "下载失败,url【" + url + "】不合法");
+ return false;
+ }
+ return true;
+ }
+
+ @Override public FtpDirDownloadTarget charSet(String charSet) {
+ return mDelegate.charSet(charSet);
+ }
+
+ @Override public FtpDirDownloadTarget login(String userName, String password) {
+ return mDelegate.login(userName, password);
}
- @Override public boolean isRunning() {
- DownloadGroupTask task = DownloadGroupTaskQueue.getInstance().getTask(mEntity.getKey());
- return task != null && task.isRunning();
+ @Override public FtpDirDownloadTarget login(String userName, String password, String account) {
+ return mDelegate.login(userName, password, account);
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/FtpDownloadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/download/FtpDownloadTarget.java
index ccc18455..81ae6413 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/FtpDownloadTarget.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/FtpDownloadTarget.java
@@ -16,22 +16,21 @@
package com.arialyy.aria.core.download;
import android.support.annotation.NonNull;
-import android.text.TextUtils;
+import com.arialyy.aria.core.delegate.FtpDelegate;
import com.arialyy.aria.core.inf.AbsTaskEntity;
-import com.arialyy.aria.util.ALog;
+import com.arialyy.aria.core.inf.IFtpTarget;
import com.arialyy.aria.util.CommonUtil;
-import java.io.File;
/**
* Created by lyy on 2016/12/5.
* https://github.com/AriaLyy/Aria
*/
-public class FtpDownloadTarget extends DownloadTarget {
- private final String TAG = "FtpDownloadTarget";
+public class FtpDownloadTarget extends BaseNormalTarget
+ implements IFtpTarget {
+ private FtpDelegate mDelegate;
FtpDownloadTarget(DownloadEntity entity, String targetName, boolean refreshInfo) {
- super(entity, targetName, refreshInfo);
- init(refreshInfo);
+ this(entity.getUrl(), targetName, refreshInfo);
}
FtpDownloadTarget(String url, String targetName) {
@@ -39,16 +38,29 @@ public class FtpDownloadTarget extends DownloadTarget {
}
FtpDownloadTarget(String url, String targetName, boolean refreshInfo) {
- super(url, targetName);
+ initTarget(url, targetName, refreshInfo);
init(refreshInfo);
}
private void init(boolean refreshInfo) {
int lastIndex = url.lastIndexOf("/");
mEntity.setFileName(url.substring(lastIndex + 1, url.length()));
- mTaskEntity.urlEntity = CommonUtil.getFtpUrlInfo(url);
- mTaskEntity.refreshInfo = refreshInfo;
- mTaskEntity.requestType = AbsTaskEntity.D_FTP;
+ mTaskEntity.setUrlEntity(CommonUtil.getFtpUrlInfo(url));
+ mTaskEntity.setRefreshInfo(refreshInfo);
+ mTaskEntity.setRequestType(AbsTaskEntity.D_FTP);
+
+ mDelegate = new FtpDelegate<>(this, mTaskEntity);
+ }
+
+ /**
+ * 设置文件保存文件夹路径
+ *
+ * @param filePath 文件保存路径
+ * @deprecated {@link #setFilePath(String)} 请使用这个api
+ */
+ @Deprecated
+ public FtpDownloadTarget setDownloadPath(@NonNull String filePath) {
+ return setFilePath(filePath);
}
/**
@@ -57,69 +69,26 @@ public class FtpDownloadTarget extends DownloadTarget {
* 1、如果保存路径是该文件的保存路径,如:/mnt/sdcard/file.zip,则使用路径中的文件名file.zip
* 2、如果保存路径是文件夹路径,如:/mnt/sdcard/,则使用FTP服务器该文件的文件名
*
- * @param downloadPath 路径必须为文件路径,不能为文件夹路径
+ * @param filePath 路径必须为文件路径,不能为文件夹路径
*/
- @Override public FtpDownloadTarget setDownloadPath(@NonNull String downloadPath) {
- if (TextUtils.isEmpty(downloadPath)) {
- throw new IllegalArgumentException("文件保持路径不能为null");
- }
- File file = new File(downloadPath);
- if (file.isDirectory()) {
- downloadPath += mEntity.getFileName();
- }
- if (!downloadPath.equals(mEntity.getDownloadPath())) {
- File oldFile = new File(mEntity.getDownloadPath());
- File newFile = new File(downloadPath);
- if (TextUtils.isEmpty(mEntity.getDownloadPath()) || oldFile.renameTo(newFile)) {
- mEntity.setDownloadPath(downloadPath);
- mEntity.setFileName(newFile.getName());
- mTaskEntity.key = downloadPath;
- mEntity.update();
- mTaskEntity.update();
- CommonUtil.renameDownloadConfig(oldFile.getName(), newFile.getName());
- }
- }
+ public FtpDownloadTarget setFilePath(@NonNull String filePath) {
+ mTempFilePath = filePath;
return this;
}
- /**
- * 设置字符编码
- */
- public FtpDownloadTarget charSet(String charSet) {
- if (TextUtils.isEmpty(charSet)) return this;
- mTaskEntity.charSet = charSet;
- return this;
+ @Override protected int getTargetType() {
+ return FTP;
}
- /**
- * ftp 用户登录信息
- *
- * @param userName ftp用户名
- * @param password ftp用户密码
- */
- public FtpDownloadTarget login(String userName, String password) {
- return login(userName, password, null);
+ @Override public FtpDownloadTarget charSet(String charSet) {
+ return mDelegate.charSet(charSet);
}
- /**
- * ftp 用户登录信息
- *
- * @param userName ftp用户名
- * @param password ftp用户密码
- * @param account ftp账号
- */
- public FtpDownloadTarget login(String userName, String password, String account) {
- if (TextUtils.isEmpty(userName)) {
- ALog.e(TAG, "用户名不能为null");
- return this;
- } else if (TextUtils.isEmpty(password)) {
- ALog.e(TAG, "密码不能为null");
- return this;
- }
- mTaskEntity.urlEntity.needLogin = true;
- mTaskEntity.urlEntity.user = userName;
- mTaskEntity.urlEntity.password = password;
- mTaskEntity.urlEntity.account = account;
- return this;
+ @Override public FtpDownloadTarget login(String userName, String password) {
+ return mDelegate.login(userName, password);
+ }
+
+ @Override public FtpDownloadTarget login(String userName, String password, String account) {
+ return mDelegate.login(userName, password, account);
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/AbsGroupUtil.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/AbsGroupUtil.java
index 7bd318c5..8880a09d 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/AbsGroupUtil.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/AbsGroupUtil.java
@@ -16,20 +16,17 @@
package com.arialyy.aria.core.download.downloader;
import com.arialyy.aria.core.AriaManager;
-import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.common.IUtil;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.IDownloadListener;
import com.arialyy.aria.core.inf.IEntity;
-import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.util.NetUtils;
import java.io.File;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
@@ -73,65 +70,31 @@ public abstract class AbsGroupUtil implements IUtil {
Map mFailMap = new HashMap<>();
/**
- * 下载器映射表,key为下载地址
+ * 该任务组对应的所有任务
*/
- private Map mDownloaderMap = new HashMap<>();
+ private Map mTasksMap = new HashMap<>();
/**
- * 该任务组对应的所有任务
+ * 下载器映射表,key为下载地址
*/
- private Map mTasksMap = new HashMap<>();
+ private Map mDownloaderMap = new HashMap<>();
+
/**
* 是否需要读取文件长度,{@code true}需要
*/
boolean isNeedLoadFileSize = true;
//已经完成的任务数
- private int mCompleteNum = 0;
- //失败的任务数
- private int mFailNum = 0;
+ int mCompleteNum = 0;
//停止的任务数
private int mStopNum = 0;
- //实际的下载任务数
- int mActualTaskNum = 0;
- //初始化完成的任务数
- int mInitNum = 0;
- // 初始化失败的任务数
- int mInitFailNum = 0;
//任务组大小
int mGroupSize = 0;
- long mUpdateInterval = 1000;
+ private long mUpdateInterval = 1000;
AbsGroupUtil(IDownloadGroupListener listener, DownloadGroupTaskEntity groupEntity) {
mListener = listener;
mGTEntity = groupEntity;
mExePool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
- List tasks =
- DbEntity.findDatas(DownloadTaskEntity.class, "groupName=?", mGTEntity.key);
- if (tasks != null && !tasks.isEmpty()) {
- for (DownloadTaskEntity te : tasks) {
- te.removeFile = mGTEntity.removeFile;
- if (te.getEntity() == null) continue;
- mTasksMap.put(te.getEntity().getUrl(), te);
- }
- }
- mGroupSize = mGTEntity.entity.getSubTask().size();
- mTotalLen = groupEntity.getEntity().getFileSize();
- isNeedLoadFileSize = mTotalLen <= 1;
- for (DownloadEntity entity : mGTEntity.entity.getSubTask()) {
- File file = new File(entity.getDownloadPath());
- if (entity.getState() == IEntity.STATE_COMPLETE && file.exists()) {
- mCompleteNum++;
- mCurrentLocation += entity.getFileSize();
- } else {
- mExeMap.put(entity.getUrl(), createChildDownloadTask(entity));
- mCurrentLocation += file.exists() ? entity.getCurrentProgress() : 0;
- mActualTaskNum++;
- }
- if (isNeedLoadFileSize) {
- mTotalLen += entity.getFileSize();
- }
- }
- updateFileSize();
mUpdateInterval =
AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getUpdateInterval();
}
@@ -190,11 +153,9 @@ public abstract class AbsGroupUtil implements IUtil {
* @param url 子任务下载地址
*/
public void cancelSubTask(String url) {
- List urls = mGTEntity.entity.getUrls();
- if (urls != null && !urls.isEmpty() && urls.contains(url)) {
- urls.remove(url);
- DownloadTaskEntity det =
- DbEntity.findFirst(DownloadTaskEntity.class, "url=? and isGroupTask='true'", url);
+ Set urls = mTasksMap.keySet();
+ if (!urls.isEmpty() && urls.contains(url)) {
+ DownloadTaskEntity det = mTasksMap.get(url);
if (det != null) {
mTotalLen -= det.getEntity().getFileSize();
mGroupSize--;
@@ -260,7 +221,6 @@ public abstract class AbsGroupUtil implements IUtil {
@Override public void cancel() {
closeTimer(false);
- mListener.onCancel();
onCancel();
if (!mExePool.isShutdown()) {
mExePool.shutdown();
@@ -273,38 +233,15 @@ public abstract class AbsGroupUtil implements IUtil {
dt.cancel();
}
}
- delDownloadInfo();
- mGTEntity.deleteData();
+ clearState();
+ CommonUtil.delDownloadGroupTaskConfig(mGTEntity.isRemoveFile(), mGTEntity.getEntity());
+ mListener.onCancel();
}
public void onCancel() {
}
- /**
- * 删除所有子任务的下载信息
- */
- private void delDownloadInfo() {
- List tasks =
- DbEntity.findDatas(DownloadTaskEntity.class, "groupName=?", mGTEntity.key);
- if (tasks != null && !tasks.isEmpty()) {
- for (DownloadTaskEntity taskEntity : tasks) {
- CommonUtil.delDownloadTaskConfig(mGTEntity.removeFile, taskEntity);
- }
- }
-
- File dir = new File(mGTEntity.getEntity().getDirPath());
- if (mGTEntity.removeFile) {
- if (dir.exists()) {
- dir.delete();
- }
- } else {
- if (!mGTEntity.getEntity().isComplete()) {
- dir.delete();
- }
- }
- }
-
@Override public void stop() {
closeTimer(false);
onStop();
@@ -325,10 +262,35 @@ public abstract class AbsGroupUtil implements IUtil {
}
+ /**
+ * 预处理操作,由于属性的不同,http任务组在构造函数中就可以完成了
+ * 而FTP文件夹的,需要获取完成所有子任务信息才算预处理完成
+ */
+ protected void onPre() {
+ mListener.onPre();
+ mGroupSize = mGTEntity.getSubTaskEntities().size();
+ mTotalLen = mGTEntity.getEntity().getFileSize();
+ isNeedLoadFileSize = mTotalLen <= 1;
+ for (DownloadTaskEntity te : mGTEntity.getSubTaskEntities()) {
+ File file = new File(te.getKey());
+ if (te.getState() == IEntity.STATE_COMPLETE && file.exists()) {
+ mCompleteNum++;
+ mCurrentLocation += te.getEntity().getFileSize();
+ } else {
+ mExeMap.put(te.getUrl(), te);
+ mCurrentLocation += file.exists() ? te.getEntity().getCurrentProgress() : 0;
+ }
+ if (isNeedLoadFileSize) {
+ mTotalLen += te.getEntity().getFileSize();
+ }
+ mTasksMap.put(te.getUrl(), te);
+ }
+ updateFileSize();
+ }
+
@Override public void start() {
isRunning = true;
- mFailNum = 0;
- mListener.onPre();
+ clearState();
onStart();
}
@@ -345,6 +307,11 @@ public abstract class AbsGroupUtil implements IUtil {
}
+ private void clearState(){
+ mDownloaderMap.clear();
+ mFailMap.clear();
+ }
+
private void closeTimer(boolean isRunning) {
this.isRunning = isRunning;
if (mTimer != null) {
@@ -389,7 +356,7 @@ public abstract class AbsGroupUtil implements IUtil {
*
* @param start 是否启动下载
*/
- Downloader createChildDownload(DownloadTaskEntity taskEntity, boolean start) {
+ private Downloader createChildDownload(DownloadTaskEntity taskEntity, boolean start) {
ChildDownloadListener listener = new ChildDownloadListener(taskEntity);
Downloader dt = new Downloader(listener, taskEntity);
mDownloaderMap.put(taskEntity.getEntity().getUrl(), dt);
@@ -400,44 +367,6 @@ public abstract class AbsGroupUtil implements IUtil {
return dt;
}
- /**
- * 创建子任务下载信息
- */
- DownloadTaskEntity createChildDownloadTask(DownloadEntity entity) {
- DownloadTaskEntity taskEntity = mTasksMap.get(entity.getUrl());
- if (taskEntity != null) {
- taskEntity.entity = entity;
- if (getTaskType() == FTP_DIR) {
- taskEntity.urlEntity = createFtpUrlEntity(entity);
- }
- mTasksMap.put(entity.getUrl(), taskEntity);
- return taskEntity;
- }
- taskEntity = new DownloadTaskEntity();
- taskEntity.entity = entity;
- taskEntity.headers = mGTEntity.headers;
- taskEntity.requestEnum = mGTEntity.requestEnum;
- taskEntity.redirectUrlKey = mGTEntity.redirectUrlKey;
- taskEntity.removeFile = mGTEntity.removeFile;
- taskEntity.groupName = mGTEntity.key;
- taskEntity.isGroupTask = true;
- taskEntity.requestType = mGTEntity.requestType;
- taskEntity.key = entity.getDownloadPath();
- if (getTaskType() == FTP_DIR) {
- taskEntity.urlEntity = createFtpUrlEntity(entity);
- }
- taskEntity.save();
- mTasksMap.put(entity.getUrl(), taskEntity);
- return taskEntity;
- }
-
- private FtpUrlEntity createFtpUrlEntity(DownloadEntity entity) {
- FtpUrlEntity urlEntity = mGTEntity.urlEntity.clone();
- urlEntity.url = entity.getUrl();
- urlEntity.remotePath = CommonUtil.getRemotePath(entity.getUrl());
- return urlEntity;
- }
-
/**
* 子任务事件监听
*/
@@ -498,7 +427,7 @@ public abstract class AbsGroupUtil implements IUtil {
mListener.onSubStop(subEntity);
synchronized (AbsGroupUtil.class) {
mStopNum++;
- if (mStopNum + mCompleteNum + mInitFailNum + mFailNum >= mGroupSize) {
+ if (mStopNum + mCompleteNum + mFailMap.size() == mGroupSize) {
closeTimer(false);
mListener.onStop(mCurrentLocation);
}
@@ -515,13 +444,13 @@ public abstract class AbsGroupUtil implements IUtil {
saveData(IEntity.STATE_COMPLETE, subEntity.getFileSize());
handleSpeed(0);
mListener.onSubComplete(subEntity);
- synchronized (AbsGroupUtil.class) {
+ synchronized (ChildDownloadListener.class) {
mCompleteNum++;
//如果子任务完成的数量和总任务数一致,表示任务组任务已经完成
if (mCompleteNum >= mGroupSize) {
closeTimer(false);
mListener.onComplete();
- } else if (mStopNum + mCompleteNum + mInitFailNum + mFailNum >= mGroupSize) {
+ } else if (mFailMap.size() > 0 && mStopNum + mCompleteNum + mFailMap.size() >= mGroupSize) {
//如果子任务完成数量加上失败的数量和总任务数一致,则任务组停止下载
closeTimer(false);
mListener.onStop(mCurrentLocation);
@@ -537,20 +466,23 @@ public abstract class AbsGroupUtil implements IUtil {
}
/**
- * 失败后重试下载,如果失败次数超过5次,不再重试
+ * 重试下载
*/
private void reTry(boolean needRetry) {
- synchronized (AriaManager.LOCK) {
- if (subEntity.getFailNum() < 5 && isRunning && needRetry && NetUtils.isConnected(
- AriaManager.APP)) {
+ synchronized (ChildDownloadListener.class) {
+ if (subEntity.getFailNum() < 5 && needRetry && NetUtils.isConnected(AriaManager.APP)) {
reStartTask();
} else {
- mFailNum++;
+ mFailMap.put(subTaskEntity.getUrl(), subTaskEntity);
mListener.onSubFail(subEntity);
//如果失败的任务数大于实际的下载任务数,任务组停止下载
- if (mFailNum >= mActualTaskNum) {
+ if (mFailMap.size() >= mExeMap.size()) {
closeTimer(false);
- mListener.onStop(mCurrentLocation);
+ if (mFailMap.size() == mGroupSize) { //所有任务都失败了,则认为该任务组已经失败
+ mListener.onFail(true);
+ } else {
+ mListener.onStop(mCurrentLocation);
+ }
}
}
}
@@ -574,11 +506,11 @@ public abstract class AbsGroupUtil implements IUtil {
}
private void saveData(int state, long location) {
- subTaskEntity.state = state;
+ subTaskEntity.setState(state);
subEntity.setState(state);
subEntity.setComplete(state == IEntity.STATE_COMPLETE);
if (state == IEntity.STATE_CANCEL) {
- subTaskEntity.deleteData();
+ subEntity.deleteData();
return;
} else if (subEntity.isComplete()) {
subEntity.setCompleteTime(System.currentTimeMillis());
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/ConnectionHelp.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/ConnectionHelp.java
index a4a2dfd4..0803249a 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/ConnectionHelp.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/ConnectionHelp.java
@@ -15,18 +15,21 @@
*/
package com.arialyy.aria.core.download.downloader;
+import android.text.TextUtils;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.util.SSLContextUtil;
import java.io.IOException;
+import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Set;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.InflaterInputStream;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
-import org.apache.commons.net.ftp.FTPClient;
/**
* Created by lyy on 2017/1/18.
@@ -34,6 +37,26 @@ import org.apache.commons.net.ftp.FTPClient;
*/
class ConnectionHelp {
+ /**
+ * 转换HttpUrlConnect的inputStream流
+ *
+ * @return {@link GZIPInputStream}、{@link InflaterInputStream}
+ * @throws IOException
+ */
+ static InputStream convertInputStream(HttpURLConnection connection) throws IOException {
+ String encoding = connection.getContentEncoding();
+ if (TextUtils.isEmpty(encoding)) {
+ return connection.getInputStream();
+ }
+ if (encoding.contains("gzip")) {
+ return new GZIPInputStream(connection.getInputStream());
+ } else if (encoding.contains("deflate")) {
+ return new InflaterInputStream(connection.getInputStream());
+ } else {
+ return connection.getInputStream();
+ }
+ }
+
/**
* 处理链接
*
@@ -65,12 +88,12 @@ class ConnectionHelp {
*/
static HttpURLConnection setConnectParam(DownloadTaskEntity entity, HttpURLConnection conn)
throws ProtocolException {
- conn.setRequestMethod(entity.requestEnum.name);
+ conn.setRequestMethod(entity.getRequestEnum().name);
Set keys = null;
- if (entity.headers != null && entity.headers.size() > 0) {
- keys = entity.headers.keySet();
+ if (entity.getHeaders() != null && entity.getHeaders().size() > 0) {
+ keys = entity.getHeaders().keySet();
for (String key : keys) {
- conn.setRequestProperty(key, entity.headers.get(key));
+ conn.setRequestProperty(key, entity.getHeaders().get(key));
}
}
if (keys == null || !keys.contains("Charset")) {
@@ -86,6 +109,7 @@ class ConnectionHelp {
.append("image/jpeg, ")
.append("image/pjpeg, ")
.append("image/webp, ")
+ .append("image/apng, ")
.append("application/xml, ")
.append("application/xaml+xml, ")
.append("application/xhtml+xml, ")
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadGroupUtil.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadGroupUtil.java
index 937f535f..32949d9f 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadGroupUtil.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadGroupUtil.java
@@ -16,6 +16,7 @@
package com.arialyy.aria.core.download.downloader;
import android.util.SparseArray;
+import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.common.IUtil;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
@@ -33,6 +34,7 @@ import java.util.concurrent.Executors;
public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
private final String TAG = "DownloadGroupUtil";
private ExecutorService mInfoPool;
+ private int mInitCompleteNum, mInitFailNum;
/**
* 文件信息回调组
@@ -42,6 +44,7 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
public DownloadGroupUtil(IDownloadGroupListener listener, DownloadGroupTaskEntity taskEntity) {
super(listener, taskEntity);
mInfoPool = Executors.newCachedThreadPool();
+ onPre();
}
@Override int getTaskType() {
@@ -64,26 +67,28 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
@Override protected void onStart() {
super.onStart();
- if (mExeMap.size() == 0){
+ if (mCompleteNum == mGroupSize) {
+ mListener.onComplete();
+ return;
+ }
+
+ if (mExeMap.size() == 0) {
ALog.e(TAG, "任务组无可执行任务");
mListener.onFail(false);
return;
}
Set keys = mExeMap.keySet();
- int i = 0;
for (String key : keys) {
DownloadTaskEntity taskEntity = mExeMap.get(key);
if (taskEntity != null) {
if (taskEntity.getState() != IEntity.STATE_FAIL
&& taskEntity.getState() != IEntity.STATE_WAIT) {
createChildDownload(taskEntity);
- i++;
} else {
mInfoPool.execute(createFileInfoThread(taskEntity));
}
}
}
- if (i != 0 && i == mExeMap.size()) startRunningFlow();
if (mCurrentLocation == mTotalLen) {
mListener.onComplete();
}
@@ -99,7 +104,7 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
callback = new OnFileInfoCallback() {
int failNum = 0;
- @Override public void onComplete(String url, int code) {
+ @Override public void onComplete(String url, CompleteInfo info) {
DownloadTaskEntity te = mExeMap.get(url);
if (te != null) {
if (isNeedLoadFileSize) {
@@ -107,32 +112,32 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
}
createChildDownload(te);
}
- mInitNum++;
- if (mInitNum + mInitFailNum >= mGTEntity.getEntity().getSubTask().size()
- || !isNeedLoadFileSize) {
+ mInitCompleteNum ++;
+
+ if (mInitCompleteNum + mInitFailNum >= mGroupSize || !isNeedLoadFileSize) {
startRunningFlow();
updateFileSize();
}
}
@Override public void onFail(String url, String errorMsg, boolean needRetry) {
+ ALog.e(TAG, "任务【" + url + "】初始化失败。");
DownloadTaskEntity te = mExeMap.get(url);
if (te != null) {
mFailMap.put(url, te);
mFileInfoCallbacks.put(te.hashCode(), this);
+ mExeMap.remove(url);
}
//404链接不重试下载
- if (failNum < 10 && !errorMsg.contains("错误码:404") && !errorMsg.contains(
- "UnknownHostException")) {
- mInfoPool.execute(createFileInfoThread(te));
- } else {
- mInitFailNum++;
- mActualTaskNum--;
- if (mActualTaskNum < 0) mActualTaskNum = 0;
- }
- failNum++;
- if (mInitNum + mInitFailNum >= mGTEntity.getEntity().getSubTask().size()
- || !isNeedLoadFileSize) {
+ //if (failNum < 3 && !errorMsg.contains("错误码:404") && !errorMsg.contains(
+ // "UnknownHostException")) {
+ // mInfoPool.execute(createFileInfoThread(te));
+ //} else {
+ // mInitFailNum++;
+ //}
+ //failNum++;
+ mInitFailNum ++;
+ if (mInitCompleteNum + mInitFailNum >= mGroupSize || !isNeedLoadFileSize) {
startRunningFlow();
updateFileSize();
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java
index e72c97bd..de1780e1 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java
@@ -44,14 +44,20 @@ class Downloader extends AbsFileer {
AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getUpdateInterval());
}
+ @Override protected int setNewTaskThreadNum() {
+ return mEntity.getFileSize() <= SUB_LEN || mTaskEntity.getRequestType() == AbsTaskEntity.D_FTP_DIR
+ ? 1
+ : AriaManager.getInstance(mContext).getDownloadConfig().getThreadNum();
+ }
+
@Override protected void checkTask() {
mConfigFile = new File(CommonUtil.getFileConfigPath(true, mEntity.getFileName()));
mTempFile = new File(mEntity.getDownloadPath());
- if (!mTaskEntity.isSupportBP) {
+ if (!mTaskEntity.isSupportBP()) {
isNewTask = true;
return;
}
- if (mTaskEntity.isNewTask) {
+ if (mTaskEntity.isNewTask()) {
isNewTask = true;
return;
}
@@ -67,20 +73,21 @@ class Downloader extends AbsFileer {
}
}
- @Override protected void handleNewTask() {
+ @Override protected boolean handleNewTask() {
CommonUtil.createFile(mTempFile.getPath());
BufferedRandomAccessFile file = null;
try {
file = new BufferedRandomAccessFile(new File(mTempFile.getPath()), "rwd", 8192);
//设置文件长度
file.setLength(mEntity.getFileSize());
+ return true;
} catch (IOException e) {
failDownload("下载失败【downloadUrl:"
+ mEntity.getUrl()
+ "】\n【filePath:"
+ mEntity.getDownloadPath()
+ "】\n"
- + CommonUtil.getPrintException(e));
+ + ALog.getExceptionString(e));
} finally {
if (file != null) {
try {
@@ -90,10 +97,11 @@ class Downloader extends AbsFileer {
}
}
}
+ return false;
}
@Override protected AbsThreadTask selectThreadTask(SubThreadConfig config) {
- switch (mTaskEntity.requestType) {
+ switch (mTaskEntity.getRequestType()) {
case AbsTaskEntity.D_FTP:
case AbsTaskEntity.D_FTP_DIR:
return new FtpThreadTask(mConstance, (IDownloadListener) mListener, config);
@@ -108,6 +116,6 @@ class Downloader extends AbsFileer {
ALog.e(TAG, errorMsg);
mConstance.isRunning = false;
mListener.onFail(false);
- ErrorHelp.saveError("", mEntity, "", errorMsg);
+ ErrorHelp.saveError(TAG, "", errorMsg);
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirDownloadUtil.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirDownloadUtil.java
index cba16bd5..00ec7df8 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirDownloadUtil.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirDownloadUtil.java
@@ -15,8 +15,8 @@
*/
package com.arialyy.aria.core.download.downloader;
+import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.common.OnFileInfoCallback;
-import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.util.ErrorHelp;
@@ -27,6 +27,8 @@ import java.util.Set;
* ftp文件夹下载工具
*/
public class FtpDirDownloadUtil extends AbsGroupUtil {
+ private String TAG = "FtpDirDownloadUtil";
+
public FtpDirDownloadUtil(IDownloadGroupListener listener, DownloadGroupTaskEntity taskEntity) {
super(listener, taskEntity);
}
@@ -38,30 +40,35 @@ public class FtpDirDownloadUtil extends AbsGroupUtil {
@Override protected void onStart() {
super.onStart();
if (mGTEntity.getEntity().getFileSize() > 1) {
+ onPre();
startDownload();
} else {
new FtpDirInfoThread(mGTEntity, new OnFileInfoCallback() {
- @Override public void onComplete(String url, int code) {
- if (code >= 200 && code < 300) {
- for (DownloadEntity entity : mGTEntity.entity.getSubTask()) {
- mExeMap.put(entity.getUrl(), createChildDownloadTask(entity));
- }
- mActualTaskNum = mGTEntity.entity.getSubTask().size();
- mGroupSize = mActualTaskNum;
- mTotalLen = mGTEntity.entity.getFileSize();
+ @Override public void onComplete(String url, CompleteInfo info) {
+ if (info.code >= 200 && info.code < 300) {
+ onPre();
startDownload();
}
}
@Override public void onFail(String url, String errorMsg, boolean needRetry) {
+ DownloadTaskEntity te = mExeMap.get(url);
+ if (te != null) {
+ mFailMap.put(url, te);
+ mExeMap.remove(url);
+ }
mListener.onFail(needRetry);
- ErrorHelp.saveError("D_FTP_DIR", mGTEntity.getEntity(), "", errorMsg);
+ ErrorHelp.saveError(TAG, "", errorMsg);
}
}).start();
}
}
private void startDownload() {
+ if (mCompleteNum == mGroupSize) {
+ mListener.onComplete();
+ return;
+ }
int i = 0;
Set keys = mExeMap.keySet();
for (String key : keys) {
@@ -71,6 +78,10 @@ public class FtpDirDownloadUtil extends AbsGroupUtil {
i++;
}
}
- if (i == mExeMap.size()) startRunningFlow();
+ if (mExeMap.size() == 0) {
+ mListener.onComplete();
+ } else if (i == mExeMap.size()) {
+ startRunningFlow();
+ }
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirInfoThread.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirInfoThread.java
index caec83c6..7c6ab6eb 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirInfoThread.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirInfoThread.java
@@ -17,10 +17,13 @@ package com.arialyy.aria.core.download.downloader;
import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.common.AbsFtpInfoThread;
+import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
+import com.arialyy.aria.core.download.DownloadTaskEntity;
+import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.util.CommonUtil;
import java.nio.charset.Charset;
import java.util.ArrayList;
@@ -37,7 +40,7 @@ class FtpDirInfoThread extends AbsFtpInfoThread());
}
- if (mEntity.getSubTask() == null) {
- mEntity.setSubTasks(new ArrayList());
- }
- mEntity.getSubTask().add(entity);
+ mEntity.getSubEntities().add(entity);
+ mTaskEntity.getSubTaskEntities().add(taskEntity);
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpFileInfoThread.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpFileInfoThread.java
index 42dc1900..acb3371a 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpFileInfoThread.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpFileInfoThread.java
@@ -16,6 +16,7 @@
package com.arialyy.aria.core.download.downloader;
import com.arialyy.aria.core.common.AbsFtpInfoThread;
+import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
@@ -31,15 +32,15 @@ class FtpFileInfoThread extends AbsFtpInfoThread {
- private final String TAG = "FtpDownloadThreadTask";
+ private final String TAG = "FtpThreadTask";
FtpThreadTask(StateConstance constance, IDownloadListener listener,
SubThreadConfig downloadInfo) {
@@ -71,7 +71,7 @@ class FtpThreadTask extends AbsFtpThreadTask
return;
}
String remotePath =
- new String(mTaskEntity.urlEntity.remotePath.getBytes(charSet), SERVER_CHARSET);
+ new String(mTaskEntity.getUrlEntity().remotePath.getBytes(charSet), SERVER_CHARSET);
ALog.i(TAG, "remotePath【" + remotePath + "】");
is = client.retrieveFileStream(remotePath);
reply = client.getReplyCode();
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpFileInfoThread.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpFileInfoThread.java
index c2cdafd0..63634d0f 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpFileInfoThread.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpFileInfoThread.java
@@ -17,13 +17,17 @@ package com.arialyy.aria.core.download.downloader;
import android.text.TextUtils;
import com.arialyy.aria.core.AriaManager;
+import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CheckUtil;
import com.arialyy.aria.util.CommonUtil;
+import java.io.BufferedReader;
+import java.io.File;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
@@ -54,7 +58,7 @@ class HttpFileInfoThread implements Runnable {
conn = ConnectionHelp.setConnectParam(mTaskEntity, conn);
conn.setRequestProperty("Range", "bytes=" + 0 + "-");
conn.setConnectTimeout(mConnectTimeOut);
- conn.setRequestMethod(mTaskEntity.requestEnum.name);
+ //conn.setChunkedStreamingMode(0);
conn.connect();
handleConnect(conn);
} catch (IOException e) {
@@ -63,7 +67,7 @@ class HttpFileInfoThread implements Runnable {
+ "】\n【filePath:"
+ mEntity.getDownloadPath()
+ "】\n"
- + CommonUtil.getPrintException(e), true);
+ + ALog.getExceptionString(e), true);
} finally {
if (conn != null) {
conn.disconnect();
@@ -74,62 +78,122 @@ class HttpFileInfoThread implements Runnable {
private void handleConnect(HttpURLConnection conn) throws IOException {
long len = conn.getContentLength();
if (len < 0) {
- String temp = conn.getHeaderField(mTaskEntity.contentLength);
+ String temp = conn.getHeaderField("Content-Length");
len = TextUtils.isEmpty(temp) ? -1 : Long.parseLong(temp);
+ // 某些服务,如果设置了conn.setRequestProperty("Range", "bytes=" + 0 + "-");
+ // 会返回 Content-Range: bytes 0-225427911/225427913
+ if (len < 0) {
+ temp = conn.getHeaderField("Content-Range");
+ if (TextUtils.isEmpty(temp)) {
+ len = -1;
+ } else {
+ int start = temp.indexOf("/");
+ len = Long.parseLong(temp.substring(start + 1, temp.length()));
+ }
+ }
}
int code = conn.getResponseCode();
- boolean isComplete = false;
+ boolean end = false;
if (TextUtils.isEmpty(mEntity.getMd5Code())) {
- String md5Code = conn.getHeaderField(mTaskEntity.md5Key);
+ String md5Code = conn.getHeaderField("Content-MD5");
mEntity.setMd5Code(md5Code);
}
- String disposition = conn.getHeaderField(mTaskEntity.dispositionKey);
+
+ boolean isChunked = false;
+ final String str = conn.getHeaderField("Transfer-Encoding");
+ if (!TextUtils.isEmpty(str) && str.equals("chunked")) {
+ isChunked = true;
+ }
//Map> headers = conn.getHeaderFields();
- if (!TextUtils.isEmpty(disposition)) {
+ String disposition = conn.getHeaderField("Content-Disposition");
+ if (mTaskEntity.isUseServerFileName() && !TextUtils.isEmpty(disposition)) {
mEntity.setDisposition(CommonUtil.encryptBASE64(disposition));
- if (disposition.contains(mTaskEntity.dispositionFileKey)) {
- String[] infos = disposition.split("=");
- mEntity.setServerFileName(URLDecoder.decode(infos[1], "utf-8"));
+ if (disposition.contains(";")) {
+ String[] infos = disposition.split(";");
+ for (String info : infos) {
+ if (info.startsWith("filename") && info.contains("=")) {
+ String[] temp = info.split("=");
+ if (temp.length > 1) {
+ String newName = URLDecoder.decode(temp[1], "utf-8");
+ mEntity.setServerFileName(newName);
+ fileRename(newName);
+ break;
+ }
+ }
+ }
}
}
- mTaskEntity.code = code;
+ mTaskEntity.setCode(code);
if (code == HttpURLConnection.HTTP_PARTIAL) {
- if (!checkLen(len)) return;
+ if (!checkLen(len) && !isChunked) {
+ return;
+ }
mEntity.setFileSize(len);
- mTaskEntity.isSupportBP = true;
- isComplete = true;
+ mTaskEntity.setSupportBP(true);
+ end = true;
} else if (code == HttpURLConnection.HTTP_OK) {
- if (!checkLen(len)) return;
+ if (conn.getHeaderField("Content-Type").equals("text/html")) {
+ BufferedReader reader =
+ new BufferedReader(new InputStreamReader(ConnectionHelp.convertInputStream(conn)));
+ StringBuilder sb = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ sb.append(line);
+ }
+ reader.close();
+ handleUrlReTurn(conn, CommonUtil.getWindowReplaceUrl(sb.toString()));
+ return;
+ } else if (!checkLen(len) && !isChunked) {
+ return;
+ }
mEntity.setFileSize(len);
- mTaskEntity.isSupportBP = false;
- isComplete = true;
+ mTaskEntity.setSupportBP(false);
+ end = true;
} else if (code == HttpURLConnection.HTTP_NOT_FOUND) {
failDownload("任务【" + mEntity.getUrl() + "】下载失败,错误码:404", true);
} else if (code == HttpURLConnection.HTTP_MOVED_TEMP
|| code == HttpURLConnection.HTTP_MOVED_PERM
|| code == HttpURLConnection.HTTP_SEE_OTHER) {
- mTaskEntity.redirectUrl = conn.getHeaderField(mTaskEntity.redirectUrlKey);
- mEntity.setRedirect(true);
- mEntity.setRedirectUrl(mTaskEntity.redirectUrl);
- handle302Turn(conn);
+ handleUrlReTurn(conn, conn.getHeaderField("Location"));
} else {
failDownload("任务【" + mEntity.getUrl() + "】下载失败,错误码:" + code, true);
}
- if (isComplete) {
+ if (end) {
+ mTaskEntity.setChunked(isChunked);
+ mTaskEntity.update();
if (onFileInfoListener != null) {
- onFileInfoListener.onComplete(mEntity.getUrl(), code);
+ CompleteInfo info = new CompleteInfo(code);
+ onFileInfoListener.onComplete(mEntity.getUrl(), info);
}
- mTaskEntity.update();
}
}
+ /**
+ * 重命名文件
+ */
+ private void fileRename(String newName) {
+ if (TextUtils.isEmpty(newName)) {
+ ALog.w(TAG, "重命名失败【服务器返回的文件名为空】");
+ return;
+ }
+ File oldFile = new File(mEntity.getDownloadPath());
+ String oldName = oldFile.getName();
+ String newPath = oldFile.getParent() + "/" + newName;
+ if (oldFile.exists()){
+ oldFile.renameTo(new File(newPath));
+ }
+ mEntity.setFileName(newName);
+ mEntity.setDownloadPath(newPath);
+ mTaskEntity.setKey(newPath);
+ CommonUtil.renameDownloadConfig(oldName, newName);
+ }
+
/**
* 处理30x跳转
*/
- private void handle302Turn(HttpURLConnection conn) throws IOException {
- String newUrl = conn.getHeaderField(mTaskEntity.redirectUrlKey);
- ALog.d(TAG, "30x跳转,location【 " + mTaskEntity.redirectUrlKey + "】" + "新url为【" + newUrl + "】");
+ private void handleUrlReTurn(HttpURLConnection conn, String newUrl) throws IOException {
+ ALog.d(TAG, "30x跳转,新url为【" + newUrl + "】");
if (TextUtils.isEmpty(newUrl) || newUrl.equalsIgnoreCase("null") || !newUrl.startsWith(
"http")) {
if (onFileInfoListener != null) {
@@ -137,7 +201,13 @@ class HttpFileInfoThread implements Runnable {
}
return;
}
- newUrl = CheckUtil.checkUrl(newUrl);
+ if (!CheckUtil.checkUrl(newUrl)) {
+ failDownload("下载失败,重定向url错误", false);
+ return;
+ }
+ mTaskEntity.setRedirectUrl(newUrl);
+ mEntity.setRedirect(true);
+ mEntity.setRedirectUrl(newUrl);
String cookies = conn.getHeaderField("Set-Cookie");
conn = (HttpURLConnection) new URL(newUrl).openConnection();
conn = ConnectionHelp.setConnectParam(mTaskEntity, conn);
@@ -157,7 +227,7 @@ class HttpFileInfoThread implements Runnable {
*/
private boolean checkLen(long len) {
if (len != mEntity.getFileSize()) {
- mTaskEntity.isNewTask = true;
+ mTaskEntity.setNewTask(true);
}
if (len < 0) {
failDownload("任务【" + mEntity.getUrl() + "】下载失败,文件长度小于0", true);
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java
index 8b6f09c5..333dfff7 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java
@@ -27,6 +27,8 @@ import com.arialyy.aria.util.CommonUtil;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
@@ -71,49 +73,23 @@ final class HttpThreadTask extends AbsThreadTask 0) {
- Thread.sleep(mSleepTime);
- }
- file.write(buffer, 0, len);
- progress(len);
+
+ if (mTaskEntity.isChunked()) {
+ readChunk(is, file);
+ } else {
+ readNormal(is, file);
}
- if (STATE.isCancel || STATE.isStop){
+
+ if (STATE.isCancel || STATE.isStop) {
return;
}
- //支持断点的处理
- if (mConfig.SUPPORT_BP) {
- ALog.i(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】线程__" + mConfig.THREAD_ID + "__下载完毕");
- writeConfig(true, 1);
- STATE.COMPLETE_THREAD_NUM++;
- if (STATE.isComplete()) {
- File configFile = new File(mConfigFPath);
- if (configFile.exists()) {
- configFile.delete();
- }
- STATE.isRunning = false;
- mListener.onComplete();
- }
- if (STATE.isFail()){
- STATE.isRunning = false;
- mListener.onFail(false);
- }
- } else {
- ALog.i(TAG, "任务下载完成");
- STATE.isRunning = false;
- mListener.onComplete();
- }
+ handleComplete();
} catch (MalformedURLException e) {
fail(mChildCurrentLocation, "下载链接异常", e);
} catch (IOException e) {
@@ -137,6 +113,69 @@ final class HttpThreadTask extends AbsThreadTask 0) {
+ Thread.sleep(mSleepTime);
+ }
+ file.write(buffer, 0, len);
+ progress(len);
+ }
+ }
+
+ /**
+ * 处理完成配置文件的更新或事件回调
+ *
+ * @throws IOException
+ */
+ private void handleComplete() throws IOException {
+ //支持断点的处理
+ if (mConfig.SUPPORT_BP) {
+ if (mChildCurrentLocation == mConfig.END_LOCATION) {
+ ALog.i(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】线程__" + mConfig.THREAD_ID + "__下载完毕");
+ writeConfig(true, 1);
+ STATE.COMPLETE_THREAD_NUM++;
+ if (STATE.isComplete()) {
+ File configFile = new File(mConfigFPath);
+ if (configFile.exists()) {
+ configFile.delete();
+ }
+ STATE.isRunning = false;
+ mListener.onComplete();
+ }
+ } else {
+ STATE.FAIL_NUM++;
+ }
+ if (STATE.isFail()) {
+ STATE.isRunning = false;
+ mListener.onFail(false);
+ }
+ } else {
+ ALog.i(TAG, "任务下载完成");
+ STATE.isRunning = false;
+ mListener.onComplete();
+ }
+ }
+
@Override protected String getTaskType() {
return "HTTP_DOWNLOAD";
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SimpleDownloadUtil.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SimpleDownloadUtil.java
index ee99b3a5..9d43adac 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SimpleDownloadUtil.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/SimpleDownloadUtil.java
@@ -16,6 +16,7 @@
package com.arialyy.aria.core.download.downloader;
+import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.common.IUtil;
import com.arialyy.aria.core.common.OnFileInfoCallback;
import com.arialyy.aria.core.download.DownloadTaskEntity;
@@ -28,7 +29,7 @@ import com.arialyy.aria.util.ErrorHelp;
* D_HTTP\FTP单任务下载工具
*/
public class SimpleDownloadUtil implements IUtil, Runnable {
- private static final String TAG = "SimpleDownloadUtil";
+ private String TAG = "SimpleDownloadUtil";
private IDownloadListener mListener;
private Downloader mDownloader;
private DownloadTaskEntity mTaskEntity;
@@ -85,14 +86,14 @@ public class SimpleDownloadUtil implements IUtil, Runnable {
private void failDownload(String msg, boolean needRetry) {
mListener.onFail(needRetry);
- ErrorHelp.saveError("HTTP_DOWNLOAD", mTaskEntity.getEntity(), msg, "");
+ ErrorHelp.saveError(TAG, msg, "");
}
@Override public void run() {
mListener.onPre();
if (mTaskEntity.getEntity().getFileSize() <= 1
- || mTaskEntity.refreshInfo
- || mTaskEntity.requestType == AbsTaskEntity.D_FTP) {
+ || mTaskEntity.isRefreshInfo()
+ || mTaskEntity.getRequestType() == AbsTaskEntity.D_FTP) {
new Thread(createInfoThread()).start();
} else {
mDownloader.start();
@@ -103,10 +104,10 @@ public class SimpleDownloadUtil implements IUtil, Runnable {
* 通过链接类型创建不同的获取文件信息的线程
*/
private Runnable createInfoThread() {
- switch (mTaskEntity.requestType) {
+ switch (mTaskEntity.getRequestType()) {
case AbsTaskEntity.D_FTP:
return new FtpFileInfoThread(mTaskEntity, new OnFileInfoCallback() {
- @Override public void onComplete(String url, int code) {
+ @Override public void onComplete(String url, CompleteInfo info) {
mDownloader.start();
}
@@ -116,7 +117,7 @@ public class SimpleDownloadUtil implements IUtil, Runnable {
});
case AbsTaskEntity.D_HTTP:
return new HttpFileInfoThread(mTaskEntity, new OnFileInfoCallback() {
- @Override public void onComplete(String url, int code) {
+ @Override public void onComplete(String url, CompleteInfo info) {
mDownloader.start();
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/wrapper/DGEWrapper.java b/Aria/src/main/java/com/arialyy/aria/core/download/wrapper/DGEWrapper.java
new file mode 100644
index 00000000..0c50181d
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/wrapper/DGEWrapper.java
@@ -0,0 +1,44 @@
+/*
+ * 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.download.wrapper;
+
+import com.arialyy.aria.core.download.DownloadEntity;
+import com.arialyy.aria.core.download.DownloadGroupEntity;
+import com.arialyy.aria.orm.AbsWrapper;
+import com.arialyy.aria.orm.annotation.Many;
+import com.arialyy.aria.orm.annotation.One;
+import com.arialyy.aria.orm.annotation.Wrapper;
+import java.util.List;
+
+/**
+ * Created by laoyuyu on 2018/3/30.
+ * 任务组实体和子任务实体的关系
+ */
+@Wrapper
+public class DGEWrapper extends AbsWrapper {
+
+ @One
+ public DownloadGroupEntity groupEntity;
+
+ @Many(parentColumn = "groupName", entityColumn = "groupName")
+ public List subEntity;
+
+ @Override protected void handleConvert() {
+ if (subEntity != null && !subEntity.isEmpty()) {
+ groupEntity.setSubEntities(subEntity);
+ }
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/wrapper/DGSTEWrapper.java b/Aria/src/main/java/com/arialyy/aria/core/download/wrapper/DGSTEWrapper.java
new file mode 100644
index 00000000..447c33f0
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/wrapper/DGSTEWrapper.java
@@ -0,0 +1,44 @@
+/*
+ * 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.download.wrapper;
+
+import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
+import com.arialyy.aria.core.download.DownloadTaskEntity;
+import com.arialyy.aria.orm.AbsWrapper;
+import com.arialyy.aria.orm.annotation.Many;
+import com.arialyy.aria.orm.annotation.One;
+import com.arialyy.aria.orm.annotation.Wrapper;
+import java.util.List;
+
+/**
+ * Created by laoyuyu on 2018/4/11.
+ * 任务组任务实体和任务组任务实体的子任务实体对应关系
+ */
+@Wrapper
+public class DGSTEWrapper extends AbsWrapper {
+
+ @One
+ public DownloadGroupTaskEntity dgTaskEntity;
+
+ @Many(parentColumn = "key", entityColumn = "groupName")
+ public List subTaskEntity;
+
+ @Override protected void handleConvert() {
+ if (subTaskEntity != null && !subTaskEntity.isEmpty()) {
+ dgTaskEntity.setSubTaskEntities(subTaskEntity);
+ }
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/wrapper/DGTEWrapper.java b/Aria/src/main/java/com/arialyy/aria/core/download/wrapper/DGTEWrapper.java
new file mode 100644
index 00000000..680585ac
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/wrapper/DGTEWrapper.java
@@ -0,0 +1,65 @@
+/*
+ * 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.download.wrapper;
+
+import com.arialyy.aria.core.download.DownloadGroupEntity;
+import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
+import com.arialyy.aria.core.download.DownloadTaskEntity;
+import com.arialyy.aria.core.inf.AbsTaskEntity;
+import com.arialyy.aria.orm.AbsWrapper;
+import com.arialyy.aria.orm.DbEntity;
+import com.arialyy.aria.orm.annotation.Many;
+import com.arialyy.aria.orm.annotation.One;
+import com.arialyy.aria.orm.annotation.Wrapper;
+import com.arialyy.aria.util.CommonUtil;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by laoyuyu on 2018/3/30.
+ * 任务组实体和任务组任务实体的关系
+ */
+@Wrapper
+public class DGTEWrapper extends AbsWrapper {
+
+ @One
+ public DownloadGroupEntity entity;
+
+ @Many(parentColumn = "groupName", entityColumn = "key")
+ private List taskEntitys;
+
+ public DownloadGroupTaskEntity taskEntity;
+
+ @Override protected void handleConvert() {
+ taskEntity = (taskEntitys == null || taskEntitys.isEmpty()) ? null : taskEntitys.get(0);
+ if (taskEntity != null) {
+ taskEntity.setEntity(entity);
+ List subWrappers =
+ DbEntity.findRelationData(DTEWrapper.class, "DownloadTaskEntity.groupName=?",
+ taskEntity.getKey());
+ if (subWrappers != null && !subWrappers.isEmpty()) {
+ List temp = new ArrayList<>();
+ for (DTEWrapper dw : subWrappers) {
+ if (dw.taskEntity.getRequestType() == AbsTaskEntity.D_FTP) {
+ dw.taskEntity.setUrlEntity(CommonUtil.getFtpUrlInfo(dw.taskEntity.getUrl()));
+ }
+ temp.add(dw.taskEntity);
+ }
+ taskEntity.setSubTaskEntities(temp);
+ }
+ }
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/wrapper/DTEWrapper.java b/Aria/src/main/java/com/arialyy/aria/core/download/wrapper/DTEWrapper.java
new file mode 100644
index 00000000..d2062f98
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/download/wrapper/DTEWrapper.java
@@ -0,0 +1,46 @@
+/*
+ * 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.download.wrapper;
+
+import com.arialyy.aria.core.download.DownloadEntity;
+import com.arialyy.aria.core.download.DownloadTaskEntity;
+import com.arialyy.aria.orm.AbsWrapper;
+import com.arialyy.aria.orm.annotation.Many;
+import com.arialyy.aria.orm.annotation.One;
+import com.arialyy.aria.orm.annotation.Wrapper;
+import java.util.List;
+
+/**
+ * Created by laoyuyu on 2018/3/30.
+ */
+@Wrapper
+public class DTEWrapper extends AbsWrapper {
+
+ @One
+ public DownloadEntity entity;
+
+ @Many(parentColumn = "downloadPath", entityColumn = "key")
+ private List taskEntitys = null;
+
+ public DownloadTaskEntity taskEntity;
+
+ @Override public void handleConvert() {
+ taskEntity = (taskEntitys == null || taskEntitys.isEmpty()) ? null : taskEntitys.get(0);
+ if (taskEntity != null) {
+ taskEntity.setEntity(entity);
+ }
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsDownloadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsDownloadTarget.java
deleted file mode 100644
index f5909a1f..00000000
--- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsDownloadTarget.java
+++ /dev/null
@@ -1,151 +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.inf;
-
-import android.text.TextUtils;
-import com.arialyy.aria.core.AriaManager;
-import com.arialyy.aria.core.command.normal.NormalCmdFactory;
-import com.arialyy.aria.core.download.DownloadEntity;
-import com.arialyy.aria.util.ALog;
-import com.arialyy.aria.util.CommonUtil;
-
-/**
- * Created by lyy on 2017/2/28.
- */
-public abstract class AbsDownloadTarget
- extends AbsTarget {
-
- /**
- * 如果你的下载链接的header中含有md5码信息,那么你可以通过设置key,来获取从header获取该md5码信息。
- * key默认值为:Content-MD5
- * 获取md5信息:{@link DownloadEntity#getMd5Code()}
- */
- public TARGET setHeaderMd5Key(String md5Key) {
- if (TextUtils.isEmpty(md5Key)) return (TARGET) this;
- mTaskEntity.md5Key = md5Key;
- if (TextUtils.isEmpty(mTaskEntity.md5Key) || !mTaskEntity.md5Key.equals(md5Key)) {
- mTaskEntity.update();
- }
- return (TARGET) this;
- }
-
- /**
- * 如果你的文件长度是放在header中,那么你需要配置key来让Aria知道正确的文件长度
- * key默认值为:Content-Length
- */
- public TARGET setHeaderContentLengthKey(String contentLength) {
- if (TextUtils.isEmpty(contentLength)) return (TARGET) this;
- mTaskEntity.contentLength = contentLength;
- if (TextUtils.isEmpty(mTaskEntity.contentLength) || !mTaskEntity.contentLength.equals(
- contentLength)) {
- mTaskEntity.update();
- }
- return (TARGET) this;
- }
-
- /**
- * 如果你的下载链接的header中含有文件描述信息,那么你可以通过设置key,来获取从header获取该文件描述信息。
- * key默认值为:Content-Disposition
- * 获取文件描述信息:{@link DownloadEntity#getDisposition()}
- */
- public TARGET setHeaderDispositionKey(String dispositionKey) {
- if (TextUtils.isEmpty(dispositionKey)) return (TARGET) this;
- mTaskEntity.dispositionKey = dispositionKey;
- if (TextUtils.isEmpty(mTaskEntity.dispositionKey) || !mTaskEntity.dispositionKey.equals(
- dispositionKey)) {
- mTaskEntity.save();
- }
- return (TARGET) this;
- }
-
- /**
- * 从文件描述信息{@link #setHeaderDispositionKey(String)}中含有文件名信息,你可以通过设置key来获取header中的文件名
- * key默认值为:attachment;filename
- * 获取文件名信息:{@link DownloadEntity#getServerFileName()}
- */
- public TARGET setHeaderDispositionFileKey(String dispositionFileKey) {
- if (TextUtils.isEmpty(dispositionFileKey)) return (TARGET) this;
- mTaskEntity.dispositionFileKey = dispositionFileKey;
- if (TextUtils.isEmpty(mTaskEntity.dispositionFileKey) || !mTaskEntity.dispositionFileKey.equals(
- dispositionFileKey)) {
- mTaskEntity.save();
- }
- return (TARGET) this;
- }
-
- /**
- * 将任务设置为最高优先级任务,最高优先级任务有以下特点:
- * 1、在下载队列中,有且只有一个最高优先级任务
- * 2、最高优先级任务会一直存在,直到用户手动暂停或任务完成
- * 3、任务调度器不会暂停最高优先级任务
- * 4、用户手动暂停或任务完成后,第二次重新执行该任务,该命令将失效
- * 5、如果下载队列中已经满了,则会停止队尾的任务,当高优先级任务完成后,该队尾任务将自动执行
- * 6、把任务设置为最高优先级任务后,将自动执行任务,不需要重新调用start()启动任务
- */
- protected void setHighestPriority() {
- AriaManager.getInstance(AriaManager.APP)
- .setCmd(CommonUtil.createNormalCmd(mTargetName, mTaskEntity,
- NormalCmdFactory.TASK_HIGHEST_PRIORITY, checkTaskType()))
- .exe();
- }
-
- /**
- * 重定向后,新url的key,默认为location
- */
- public void setRedirectUrlKey(String redirectUrlKey) {
- if (TextUtils.isEmpty(redirectUrlKey)) {
- ALog.e("AbsDownloadTarget", "重定向后,新url的key不能为null");
- return;
- }
- mTaskEntity.redirectUrlKey = redirectUrlKey;
- }
-
- /**
- * 获取任务文件大小
- *
- * @return 文件大小
- */
- public long getFileSize() {
- return getSize();
- }
-
- /**
- * 获取单位转换后的文件大小
- *
- * @return 文件大小{@code xxx mb}
- */
- public String getConvertFileSize() {
- return getConvertSize();
- }
-
- /**
- * 添加任务
- */
- public void add() {
- AriaManager.getInstance(AriaManager.APP)
- .setCmd(CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_CREATE,
- checkTaskType()))
- .exe();
- }
-
- /**
- * 重新下载
- */
- public void reStart() {
- cancel();
- start();
- }
-}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsEntity.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsEntity.java
index cfb731bc..c4a10c5c 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsEntity.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsEntity.java
@@ -18,7 +18,7 @@ package com.arialyy.aria.core.inf;
import android.os.Parcel;
import android.os.Parcelable;
import com.arialyy.aria.orm.DbEntity;
-import com.arialyy.aria.orm.Ignore;
+import com.arialyy.aria.orm.annotation.Ignore;
/**
* Created by AriaL on 2017/6/29.
@@ -31,7 +31,7 @@ public abstract class AbsEntity extends DbEntity implements IEntity, Parcelable
/**
* 单位转换后的速度
*/
- @Ignore private String convertSpeed = "";
+ @Ignore private String convertSpeed;
/**
* 下载失败计数,每次开始都重置为0
*/
@@ -40,7 +40,7 @@ public abstract class AbsEntity extends DbEntity implements IEntity, Parcelable
/**
* 扩展字段
*/
- private String str = "";
+ private String str;
/**
* 文件大小
*/
@@ -48,7 +48,7 @@ public abstract class AbsEntity extends DbEntity implements IEntity, Parcelable
/**
* 转换后的文件大小
*/
- private String convertFileSize = "";
+ private String convertFileSize;
private int state = STATE_WAIT;
/**
diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsGroupEntity.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsGroupEntity.java
index 132b78f7..ad7f6abc 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsGroupEntity.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsGroupEntity.java
@@ -17,10 +17,7 @@ package com.arialyy.aria.core.inf;
import android.os.Parcel;
import android.os.Parcelable;
-import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
-import com.arialyy.aria.orm.Foreign;
-import com.arialyy.aria.orm.NormalList;
-import com.arialyy.aria.orm.Primary;
+import com.arialyy.aria.orm.annotation.Primary;
import java.util.ArrayList;
import java.util.List;
@@ -29,20 +26,16 @@ import java.util.List;
*/
public abstract class AbsGroupEntity extends AbsEntity implements Parcelable {
/**
- * 组名,组名为任务地址相加的urlMd5
+ * 组名,组名为任务地址相加的url的Md5
*/
- @Primary @Foreign(table = DownloadGroupTaskEntity.class, column = "key") protected String
- groupName = "";
+ @Primary protected String groupName;
/**
* 任务组别名
*/
- private String alias = "";
+ private String alias;
- /**
- * 子任务链接组
- */
- @NormalList(clazz = String.class) private List urls = new ArrayList<>();
+ private List urls = new ArrayList<>();
public List getUrls() {
return urls;
diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalEntity.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalEntity.java
index 5f03f29a..86e6ed12 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalEntity.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalEntity.java
@@ -17,8 +17,6 @@ package com.arialyy.aria.core.inf;
import android.os.Parcel;
import android.os.Parcelable;
-import com.arialyy.aria.orm.DbEntity;
-import com.arialyy.aria.orm.Ignore;
/**
* Created by AriaL on 2017/6/3.
@@ -28,12 +26,12 @@ public abstract class AbsNormalEntity extends AbsEntity implements Parcelable {
/**
* 服务器地址
*/
- private String url = "";
+ private String url;
/**
* 文件名
*/
- private String fileName = "";
+ private String fileName;
/**
* 是否是任务组里面的下载实体
@@ -41,7 +39,7 @@ public abstract class AbsNormalEntity extends AbsEntity implements Parcelable {
private boolean isGroupChild = false;
private boolean isRedirect = false; //是否重定向
- private String redirectUrl = ""; //重定向链接
+ private String redirectUrl; //重定向链接
public String getUrl() {
return url;
diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java
index 6e2d69c4..1a27a943 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java
@@ -15,13 +15,11 @@
*/
package com.arialyy.aria.core.inf;
-import android.support.annotation.NonNull;
import android.text.TextUtils;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.command.ICmd;
import com.arialyy.aria.core.command.normal.CancelCmd;
import com.arialyy.aria.core.command.normal.NormalCmdFactory;
-import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.manager.TEManager;
@@ -30,25 +28,29 @@ import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
-import java.util.Set;
/**
* Created by AriaL on 2017/7/3.
*/
public abstract class AbsTarget
implements ITarget {
+ protected String TAG = "";
protected ENTITY mEntity;
protected TASK_ENTITY mTaskEntity;
protected String mTargetName;
+ protected AbsTarget() {
+ TAG = CommonUtil.getClassName(this);
+ }
+
/**
- * 重置下载状态,将任务状态设置为未开始状态
+ * 重置状态,将任务状态设置为未开始状态
+ * 注意:如果在后续方法调用链中没有调用 {@link #start()}、{@link #stop()}、{@link #cancel()}、{@link #resume()}
+ * 等操作任务的方法,那么你需要调用{@link #save()}才能将修改保存到数据库
*/
public TARGET resetState() {
mTaskEntity.getEntity().setState(IEntity.STATE_WAIT);
- mTaskEntity.refreshInfo = true;
- mTaskEntity.update();
+ mTaskEntity.setRefreshInfo(true);
return (TARGET) this;
}
@@ -60,32 +62,17 @@ public abstract class AbsTarget headers) {
- return addHeaders(headers, false);
- }
-
- /**
- * 给url请求添加头部
- *
- * @param refreshHeader 更新数据库中保存的头部信息
- */
- public TARGET addHeaders(Map headers, boolean refreshHeader) {
- if (headers != null && headers.size() > 0) {
- Set keys = headers.keySet();
- for (String key : keys) {
- mTaskEntity.headers.put(key, headers.get(key));
- }
- }
- if (refreshHeader) {
- mTaskEntity.update();
+ public void save() {
+ if (!checkEntity()) {
+ ALog.e(TAG, "保存修改失败");
}
- return (TARGET) this;
- }
-
- /**
- * 设置请求类型,POST或GET,默认为在GET
- * 只试用于HTTP请求
- *
- * @param requestEnum {@link RequestEnum}
- */
- public TARGET setRequestMode(RequestEnum requestEnum) {
- mTaskEntity.requestEnum = requestEnum;
- return (TARGET) this;
}
/**
* 开始任务
*/
@Override public void start() {
- AriaManager.getInstance(AriaManager.APP)
- .setCmd(CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_START,
- checkTaskType()))
- .exe();
- }
-
- protected int checkTaskType() {
- int taskType = 0;
- if (mTaskEntity instanceof DownloadTaskEntity) {
- taskType = ICmd.TASK_TYPE_DOWNLOAD;
- } else if (mTaskEntity instanceof DownloadGroupTaskEntity) {
- taskType = ICmd.TASK_TYPE_DOWNLOAD_GROUP;
- } else if (mTaskEntity instanceof UploadTaskEntity) {
- taskType = ICmd.TASK_TYPE_UPLOAD;
+ if (checkEntity()) {
+ AriaManager.getInstance(AriaManager.APP)
+ .setCmd(CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_START,
+ checkTaskType()))
+ .exe();
}
- return taskType;
}
/**
@@ -244,47 +193,58 @@ public abstract class AbsTarget cmds = new ArrayList<>();
- int taskType = checkTaskType();
- cmds.add(
- CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_STOP, taskType));
- cmds.add(CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_START,
- taskType));
- AriaManager.getInstance(AriaManager.APP).setCmds(cmds).exe();
+ if (checkEntity()) {
+ List cmds = new ArrayList<>();
+ int taskType = checkTaskType();
+ cmds.add(
+ CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_STOP,
+ taskType));
+ cmds.add(CommonUtil.createNormalCmd(mTargetName, mTaskEntity, NormalCmdFactory.TASK_START,
+ taskType));
+ AriaManager.getInstance(AriaManager.APP).setCmds(cmds).exe();
+ }
}
/**
@@ -294,35 +254,21 @@ public abstract class AbsTarget 0) {
- tempUrl = url.substring(0, end);
- int tempEnd = tempUrl.lastIndexOf("/");
- if (tempEnd > 0) {
- fileName = tempUrl.substring(tempEnd + 1, tempUrl.length());
- }
- } else {
- int tempEnd = url.lastIndexOf("/");
- if (tempEnd > 0) {
- fileName = url.substring(tempEnd + 1, url.length());
- }
- }
- if (TextUtils.isEmpty(fileName)) {
- fileName = CommonUtil.keyToHashKey(url);
+ public void reStart() {
+ if (checkEntity()) {
+ cancel();
+ start();
}
- return fileName;
}
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java
index b63fad34..9407a302 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java
@@ -18,8 +18,7 @@ package com.arialyy.aria.core.inf;
import com.arialyy.aria.core.FtpUrlEntity;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.orm.DbEntity;
-import com.arialyy.aria.orm.Ignore;
-import com.arialyy.aria.orm.Primary;
+import com.arialyy.aria.orm.annotation.Ignore;
import java.util.HashMap;
import java.util.Map;
@@ -55,103 +54,75 @@ public abstract class AbsTaskEntity extends DbEntity {
*/
public static final int U_FTP = 0xA2;
- /**
- * Task实体对应的key
- */
- @Primary public String key = "";
-
/**
* 账号和密码
*/
- @Ignore public FtpUrlEntity urlEntity;
+ @Ignore private FtpUrlEntity urlEntity;
/**
* 刷新信息 {@code true} 重新刷新下载信息
*/
- @Ignore public boolean refreshInfo = false;
+ @Ignore private boolean refreshInfo = false;
/**
* 是否是新任务,{@code true} 新任务
*/
- @Ignore public boolean isNewTask = false;
+ @Ignore private boolean isNewTask = false;
/**
* 任务状态,和Entity的state同步
*/
- public int state = IEntity.STATE_WAIT;
+ private int state = IEntity.STATE_WAIT;
/**
* 请求类型
* {@link AbsTaskEntity#D_HTTP}、{@link AbsTaskEntity#D_FTP}、{@link AbsTaskEntity#D_FTP_DIR}。。。
*/
- public int requestType = D_HTTP;
+ private int requestType = D_HTTP;
/**
* http 请求头
*/
- public Map headers = new HashMap<>();
+ private Map headers = new HashMap<>();
/**
* 字符编码,默认为"utf-8"
*/
- public String charSet = "utf-8";
+ private String charSet = "utf-8";
/**
* 网络请求类型
*/
- public RequestEnum requestEnum = RequestEnum.GET;
+ private RequestEnum requestEnum = RequestEnum.GET;
/**
- * 从header中含有的文件md5码信息所需要的key
- */
- public String md5Key = "Content-MD5";
-
- /**
- * 是否使用服务器通过content-disposition传递的文件名,内容格式{@code attachment;filename=***}
+ * 是否使用服务器通过content-disposition传递的文件名,内容格式{@code attachment; filename="filename.jpg"}
* {@code true} 使用
*/
- public boolean useServerFileName = false;
-
- /**
- * 从header中获取文件描述信息所需要的key
- */
- public String dispositionKey = "Content-Disposition";
-
- /**
- * 重定向后,从header中获取新url所需要的key
- */
- public String redirectUrlKey = "location";
-
- /**
- * 从Disposition获取的文件名说需要的key
- */
- public String dispositionFileKey = "attachment;filename";
-
- /**
- * 从header中含有的文件长度信息所需要的key
- */
- public String contentLength = "Content-Length";
+ private boolean useServerFileName = false;
/**
* 重定向链接
*/
- public String redirectUrl = "";
+ private String redirectUrl = "";
/**
+ * 删除任务时,是否删除已下载完成的文件
+ * 未完成的任务,不管true还是false,都会删除文件
* {@code true} 删除任务数据库记录,并且删除已经下载完成的文件
* {@code false} 如果任务已经完成,只删除任务数据库记录
*/
- @Ignore public boolean removeFile = false;
+ @Ignore private boolean removeFile = false;
/**
* 是否支持断点, {@code true} 为支持断点
*/
- public boolean isSupportBP = true;
+ private boolean isSupportBP = true;
/**
* 状态码
*/
- public int code;
+ private int code;
public abstract ENTITY getEntity();
@@ -164,12 +135,7 @@ public abstract class AbsTaskEntity extends DbEntity {
return getEntity().getState();
}
- @Override public void deleteData() {
- if (getEntity() != null) {
- getEntity().deleteData();
- }
- super.deleteData();
- }
+ public abstract String getKey();
@Override public void update() {
if (getEntity() != null) {
@@ -177,4 +143,104 @@ public abstract class AbsTaskEntity extends DbEntity {
}
super.update();
}
+
+ public FtpUrlEntity getUrlEntity() {
+ return urlEntity;
+ }
+
+ public void setUrlEntity(FtpUrlEntity urlEntity) {
+ this.urlEntity = urlEntity;
+ }
+
+ public boolean isRefreshInfo() {
+ return refreshInfo;
+ }
+
+ public void setRefreshInfo(boolean refreshInfo) {
+ this.refreshInfo = refreshInfo;
+ }
+
+ public boolean isNewTask() {
+ return isNewTask;
+ }
+
+ public void setNewTask(boolean newTask) {
+ isNewTask = newTask;
+ }
+
+ public void setState(int state) {
+ this.state = state;
+ }
+
+ public int getRequestType() {
+ return requestType;
+ }
+
+ public void setRequestType(int requestType) {
+ this.requestType = requestType;
+ }
+
+ public Map getHeaders() {
+ return headers;
+ }
+
+ public void setHeaders(Map headers) {
+ this.headers = headers;
+ }
+
+ public String getCharSet() {
+ return charSet;
+ }
+
+ public void setCharSet(String charSet) {
+ this.charSet = charSet;
+ }
+
+ public RequestEnum getRequestEnum() {
+ return requestEnum;
+ }
+
+ public void setRequestEnum(RequestEnum requestEnum) {
+ this.requestEnum = requestEnum;
+ }
+
+ public boolean isUseServerFileName() {
+ return useServerFileName;
+ }
+
+ public void setUseServerFileName(boolean useServerFileName) {
+ this.useServerFileName = useServerFileName;
+ }
+
+ public String getRedirectUrl() {
+ return redirectUrl;
+ }
+
+ public void setRedirectUrl(String redirectUrl) {
+ this.redirectUrl = redirectUrl;
+ }
+
+ public boolean isRemoveFile() {
+ return removeFile;
+ }
+
+ public void setRemoveFile(boolean removeFile) {
+ this.removeFile = removeFile;
+ }
+
+ public boolean isSupportBP() {
+ return isSupportBP;
+ }
+
+ public void setSupportBP(boolean supportBP) {
+ isSupportBP = supportBP;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsUploadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/inf/AbsUploadTarget.java
deleted file mode 100644
index be6541f1..00000000
--- a/Aria/src/main/java/com/arialyy/aria/core/inf/AbsUploadTarget.java
+++ /dev/null
@@ -1,65 +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.inf;
-
-import android.support.annotation.NonNull;
-import com.arialyy.aria.core.queue.UploadTaskQueue;
-import com.arialyy.aria.core.upload.UploadEntity;
-import com.arialyy.aria.core.upload.UploadTask;
-import com.arialyy.aria.core.upload.UploadTaskEntity;
-import com.arialyy.aria.util.CheckUtil;
-
-/**
- * Created by AriaL on 2017/6/29.
- * 任务组超类
- */
-public abstract class AbsUploadTarget
- extends AbsTarget {
-
- /**
- * 设置上传路径
- *
- * @param uploadUrl 上传路径
- */
- public TARGET setUploadUrl(@NonNull String uploadUrl) {
- uploadUrl = CheckUtil.checkUrl(uploadUrl);
- if (mEntity.getUrl().equals(uploadUrl)) return (TARGET) this;
- mEntity.setUrl(uploadUrl);
- mEntity.update();
- return (TARGET) this;
- }
-
- /**
- * 下载任务是否存在
- */
- @Override public boolean taskExists() {
- return UploadTaskQueue.getInstance().getTask(mEntity.getFilePath()) != null;
- }
-
- /**
- * 是否在下载
- *
- * @deprecated {@link #isRunning()}
- */
- public boolean isUploading() {
- return isRunning();
- }
-
- @Override public boolean isRunning() {
- UploadTask task = UploadTaskQueue.getInstance().getTask(mEntity.getKey());
- return task != null && task.isRunning();
- }
-}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/IEntity.java b/Aria/src/main/java/com/arialyy/aria/core/inf/IEntity.java
index 156a01ce..5fdfe079 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/inf/IEntity.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/inf/IEntity.java
@@ -15,7 +15,7 @@
*/
package com.arialyy.aria.core.inf;
-import com.arialyy.aria.orm.Ignore;
+import com.arialyy.aria.orm.annotation.Ignore;
/**
* Created by lyy on 2017/2/23.
@@ -42,7 +42,7 @@ public interface IEntity {
*/
@Ignore int STATE_WAIT = 3;
/**
- * 下载中
+ * 正在执行
*/
@Ignore int STATE_RUNNING = 4;
/**
@@ -54,7 +54,7 @@ public interface IEntity {
*/
@Ignore int STATE_POST_PRE = 6;
/**
- * 取消下载
+ * 删除任务
*/
@Ignore int STATE_CANCEL = 7;
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/IFtpTarget.java b/Aria/src/main/java/com/arialyy/aria/core/inf/IFtpTarget.java
new file mode 100644
index 00000000..519b4393
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/inf/IFtpTarget.java
@@ -0,0 +1,43 @@
+/*
+ * 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.inf;
+
+/**
+ * Created by laoyuyu on 2018/3/9.
+ */
+public interface IFtpTarget {
+ /**
+ * 设置字符编码
+ */
+ TARGET charSet(String charSet);
+
+ /**
+ * ftp 用户登录信。
+ *
+ * @param userName ftp用户名
+ * @param password ftp用户密码
+ */
+ TARGET login(String userName, String password);
+
+ /**
+ * ftp 用户登录信息
+ *
+ * @param userName ftp用户名
+ * @param password ftp用户密码
+ * @param account ftp账号
+ */
+ TARGET login(String userName, String password, String account);
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/IHttpHeaderTarget.java b/Aria/src/main/java/com/arialyy/aria/core/inf/IHttpHeaderTarget.java
new file mode 100644
index 00000000..72b5aa47
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/inf/IHttpHeaderTarget.java
@@ -0,0 +1,52 @@
+/*
+ * 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.inf;
+
+import android.support.annotation.NonNull;
+import com.arialyy.aria.core.common.RequestEnum;
+import com.arialyy.aria.core.download.DownloadEntity;
+import java.util.Map;
+
+/**
+ * Created by laoyuyu on 2018/3/9.
+ * HTTP Header功能接口
+ */
+public interface IHttpHeaderTarget {
+
+ /**
+ * 给url请求添加Header数据
+ * 如果新的header数据和数据保存的不一致,则更新数据库中对应的header数据
+ *
+ * @param key header对应的key
+ * @param value header对应的value
+ */
+ TARGET addHeader(@NonNull String key, @NonNull String value);
+
+ /**
+ * 给url请求添加一组header数据
+ * 如果新的header数据和数据保存的不一致,则更新数据库中对应的header数据
+ *
+ * @param headers 一组http header数据
+ */
+ TARGET addHeaders(Map headers);
+
+ /**
+ * 设置HTTP请求类型
+ *
+ * @param requestEnum {@link RequestEnum}
+ */
+ TARGET setRequestMode(RequestEnum requestEnum);
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/ITarget.java b/Aria/src/main/java/com/arialyy/aria/core/inf/ITarget.java
index 527e8078..8b4b998a 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/inf/ITarget.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/inf/ITarget.java
@@ -15,53 +15,50 @@
*/
package com.arialyy.aria.core.inf;
-import android.support.annotation.NonNull;
-import com.arialyy.aria.core.common.RequestEnum;
-import java.util.Map;
-
/**
* Created by AriaL on 2017/6/29.
*/
public interface ITarget {
/**
- * 任务文件大小
+ * 获取任务状态
+ *
+ * @return {@link IEntity}
*/
- long getSize();
+ int getTaskState();
/**
- * 转换后的大小
+ * 任务是否在执行
+ *
+ * @return {@code true} 任务正在执行
*/
- String getConvertSize();
+ boolean isRunning();
/**
- * 获取任务进度百分比
+ * 任务是否存在
+ *
+ * @return {@code true} 任务存在
*/
- int getPercent();
+ boolean taskExists();
/**
- * 获取任务进度,如果任务存在,则返回当前进度
+ * 任务文件大小
*/
- long getCurrentProgress();
+ long getSize();
/**
- * 给url请求添加头部
- *
- * @param key 头部key
- * @param header 头部value
+ * 转换后的大小
*/
- TARGET addHeader(@NonNull String key, @NonNull String header) ;
+ String getConvertSize();
/**
- * 给url请求添加头部
+ * 获取任务进度百分比
*/
- TARGET addHeaders(Map headers);
+ int getPercent();
/**
- * 设置请求类型
- *
- * @param requestEnum {@link RequestEnum}
+ * 获取任务进度,如果任务存在,则返回当前进度
*/
- TARGET setRequestMode(RequestEnum requestEnum);
+ long getCurrentProgress();
/**
* 开始下载
@@ -82,5 +79,4 @@ public interface ITarget {
* 取消下载
*/
void cancel();
-
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/inf/IUploadListener.java b/Aria/src/main/java/com/arialyy/aria/core/inf/IUploadListener.java
index 3387c49d..e6196375 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/inf/IUploadListener.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/inf/IUploadListener.java
@@ -15,8 +15,6 @@
*/
package com.arialyy.aria.core.inf;
-import com.arialyy.aria.core.inf.IEventListener;
-
/**
* Created by lyy on 2017/2/9.
* 上传监听
diff --git a/Aria/src/main/java/com/arialyy/aria/core/manager/DGTEFactory.java b/Aria/src/main/java/com/arialyy/aria/core/manager/DGTEFactory.java
new file mode 100644
index 00000000..61104545
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/manager/DGTEFactory.java
@@ -0,0 +1,169 @@
+/*
+ * 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.manager;
+
+import com.arialyy.aria.core.download.DownloadEntity;
+import com.arialyy.aria.core.download.DownloadGroupEntity;
+import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
+import com.arialyy.aria.core.download.DownloadTaskEntity;
+import com.arialyy.aria.core.download.wrapper.DGEWrapper;
+import com.arialyy.aria.core.download.wrapper.DGTEWrapper;
+import com.arialyy.aria.orm.DbEntity;
+import com.arialyy.aria.util.CommonUtil;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by Aria.Lao on 2017/11/1.
+ * 任务实体工厂
+ */
+class DGTEFactory implements IGTEFactory {
+ private static final String TAG = "DTEFactory";
+ private static volatile DGTEFactory INSTANCE = null;
+
+ private DGTEFactory() {
+ }
+
+ public static DGTEFactory getInstance() {
+ if (INSTANCE == null) {
+ synchronized (DGTEFactory.class) {
+ INSTANCE = new DGTEFactory();
+ }
+ }
+ return INSTANCE;
+ }
+
+ @Override public DownloadGroupTaskEntity getGTE(String groupName, List urls) {
+ DownloadGroupEntity entity = createDGroupEntity(groupName, urls);
+ List wrapper =
+ DbEntity.findRelationData(DGTEWrapper.class, "DownloadGroupTaskEntity.key=?",
+ entity.getGroupName());
+ DownloadGroupTaskEntity gte;
+
+ if (wrapper != null && !wrapper.isEmpty()) {
+ gte = wrapper.get(0).taskEntity;
+ if (gte == null) {
+ // 创建新的任务组任务实体
+ gte = new DownloadGroupTaskEntity();
+ //创建子任务的任务实体
+ gte.setSubTaskEntities(createDGSubTaskEntity(entity));
+ } else if (gte.getSubTaskEntities() == null || gte.getSubTaskEntities().isEmpty()) {
+ gte.setSubTaskEntities(createDGSubTaskEntity(entity));
+ }
+ } else {
+ gte = new DownloadGroupTaskEntity();
+ gte.setSubTaskEntities(createDGSubTaskEntity(entity));
+ }
+ gte.setKey(entity.getGroupName());
+ gte.setEntity(entity);
+
+ return gte;
+ }
+
+ @Override public DownloadGroupTaskEntity getFTE(String ftpUrl) {
+ List wrapper =
+ DbEntity.findRelationData(DGTEWrapper.class, "DownloadGroupTaskEntity.key=?",
+ ftpUrl);
+ DownloadGroupTaskEntity fte;
+
+ if (wrapper != null && !wrapper.isEmpty()) {
+ fte = wrapper.get(0).taskEntity;
+ if (fte == null) {
+ fte = new DownloadGroupTaskEntity();
+ DownloadGroupEntity dge = new DownloadGroupEntity();
+ dge.setGroupName(ftpUrl);
+ fte.setEntity(dge);
+ } else if (fte.getEntity() == null) {
+ DownloadGroupEntity dge = new DownloadGroupEntity();
+ dge.setGroupName(ftpUrl);
+ fte.setEntity(dge);
+ }
+ } else {
+ fte = new DownloadGroupTaskEntity();
+ DownloadGroupEntity dge = new DownloadGroupEntity();
+ dge.setGroupName(ftpUrl);
+ fte.setEntity(dge);
+ }
+ fte.setKey(ftpUrl);
+ fte.setUrlEntity(CommonUtil.getFtpUrlInfo(ftpUrl));
+
+ if (fte.getEntity().getSubEntities() == null) {
+ fte.getEntity().setSubEntities(new ArrayList());
+ }
+ if (fte.getSubTaskEntities() == null) {
+ fte.setSubTaskEntities(new ArrayList());
+ }
+ return fte;
+ }
+
+ /**
+ * 创建任务组子任务的任务实体
+ */
+ private List createDGSubTaskEntity(DownloadGroupEntity dge) {
+ List list = new ArrayList<>();
+ for (DownloadEntity entity : dge.getSubEntities()) {
+ DownloadTaskEntity taskEntity = new DownloadTaskEntity();
+ taskEntity.setEntity(entity);
+ taskEntity.setKey(entity.getDownloadPath());
+ taskEntity.setGroupName(dge.getKey());
+ taskEntity.setGroupTask(true);
+ taskEntity.setUrl(entity.getUrl());
+ list.add(taskEntity);
+ }
+ return list;
+ }
+
+ /**
+ * 查询任务组实体,如果数据库不存在该实体,则新创建一个新的任务组实体
+ */
+ private DownloadGroupEntity createDGroupEntity(String groupName, List urls) {
+ List wrapper =
+ DbEntity.findRelationData(DGEWrapper.class, "DownloadGroupEntity.groupName=?",
+ groupName);
+
+ DownloadGroupEntity groupEntity;
+ if (wrapper != null && !wrapper.isEmpty()) {
+ groupEntity = wrapper.get(0).groupEntity;
+ if (groupEntity == null) {
+ groupEntity = new DownloadGroupEntity();
+ groupEntity.setSubEntities(createSubTask(groupName, urls));
+ }
+ } else {
+ groupEntity = new DownloadGroupEntity();
+ groupEntity.setSubEntities(createSubTask(groupName, urls));
+ }
+ groupEntity.setGroupName(groupName);
+ groupEntity.setUrls(urls);
+ return groupEntity;
+ }
+
+ /**
+ * 创建子任务
+ */
+ private List createSubTask(String groupName, List urls) {
+ List list = new ArrayList<>();
+ for (int i = 0, len = urls.size(); i < len; i++) {
+ DownloadEntity entity = new DownloadEntity();
+ entity.setUrl(urls.get(i));
+ entity.setDownloadPath(groupName + "_" + i);
+ entity.setFileName(groupName + "_" + i);
+ entity.setGroupName(groupName);
+ entity.setGroupChild(true);
+ list.add(entity);
+ }
+ return list;
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/manager/DGTEntityFactory.java b/Aria/src/main/java/com/arialyy/aria/core/manager/DGTEntityFactory.java
deleted file mode 100644
index f68d7bad..00000000
--- a/Aria/src/main/java/com/arialyy/aria/core/manager/DGTEntityFactory.java
+++ /dev/null
@@ -1,98 +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.manager;
-
-import android.text.TextUtils;
-import com.arialyy.aria.core.download.DownloadGroupEntity;
-import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
-import com.arialyy.aria.orm.DbEntity;
-import com.arialyy.aria.util.CommonUtil;
-import java.util.List;
-
-/**
- * Created by Aria.Lao on 2017/11/1.
- * 任务实体工厂
- */
-class DGTEntityFactory implements ITEntityFactory,
- IGTEntityFactory {
- private static final String TAG = "DTEntityFactory";
- private static volatile DGTEntityFactory INSTANCE = null;
-
- private DGTEntityFactory() {
- }
-
- public static DGTEntityFactory getInstance() {
- if (INSTANCE == null) {
- synchronized (DGTEntityFactory.class) {
- INSTANCE = new DGTEntityFactory();
- }
- }
- return INSTANCE;
- }
-
- /**
- * 通过下载实体创建任务实体
- */
- @Override public DownloadGroupTaskEntity create(DownloadGroupEntity entity) {
- DownloadGroupTaskEntity dgTaskEntity =
- DbEntity.findFirst(DownloadGroupTaskEntity.class, "key=?", entity.getGroupName());
- if (dgTaskEntity == null) {
- dgTaskEntity = new DownloadGroupTaskEntity();
- dgTaskEntity.save(entity);
- }
- if (dgTaskEntity.entity == null || TextUtils.isEmpty(dgTaskEntity.entity.getKey())) {
- dgTaskEntity.save(entity);
- }
- return dgTaskEntity;
- }
-
- /**
- * 对于任务组,不能使用这个,可用于FTP文件夹下载
- *
- * @deprecated {@link #create(String, List)}
- */
- @Override @Deprecated public DownloadGroupTaskEntity create(String key) {
- DownloadGroupTaskEntity dgTaskEntity =
- DbEntity.findFirst(DownloadGroupTaskEntity.class, "key=?", key);
- if (dgTaskEntity == null) {
- dgTaskEntity = new DownloadGroupTaskEntity();
- dgTaskEntity.save(getDownloadGroupEntity(key, null));
- }
- if (dgTaskEntity.entity == null || TextUtils.isEmpty(dgTaskEntity.entity.getKey())) {
- dgTaskEntity.save(getDownloadGroupEntity(key, null));
- }
- dgTaskEntity.urlEntity = CommonUtil.getFtpUrlInfo(key);
- return dgTaskEntity;
- }
-
- @Override public DownloadGroupTaskEntity create(String groupName, List urls) {
- return create(getDownloadGroupEntity(groupName, urls));
- }
-
- /**
- * 查询任务组实体,如果数据库不存在该实体,则新创建一个新的任务组实体
- */
- private DownloadGroupEntity getDownloadGroupEntity(String groupName, List urls) {
- DownloadGroupEntity entity =
- DbEntity.findFirst(DownloadGroupEntity.class, "groupName=?", groupName);
- if (entity == null) {
- entity = new DownloadGroupEntity();
- entity.setGroupName(groupName);
- entity.setUrls(urls);
- }
- return entity;
- }
-}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/manager/DTEntityFactory.java b/Aria/src/main/java/com/arialyy/aria/core/manager/DTEFactory.java
similarity index 59%
rename from Aria/src/main/java/com/arialyy/aria/core/manager/DTEntityFactory.java
rename to Aria/src/main/java/com/arialyy/aria/core/manager/DTEFactory.java
index 437b4171..16a5c84d 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/manager/DTEntityFactory.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/manager/DTEFactory.java
@@ -18,25 +18,28 @@ package com.arialyy.aria.core.manager;
import android.text.TextUtils;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
+import com.arialyy.aria.core.download.wrapper.DTEWrapper;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.orm.DbEntity;
import java.io.File;
+import java.util.List;
+import java.util.UUID;
/**
* Created by Aria.Lao on 2017/11/1.
* 任务实体工厂
*/
-class DTEntityFactory implements ITEntityFactory {
- private static final String TAG = "DTEntityFactory";
- private static volatile DTEntityFactory INSTANCE = null;
+class DTEFactory implements INormalTEFactory {
+ private static final String TAG = "DTEFactory";
+ private static volatile DTEFactory INSTANCE = null;
- private DTEntityFactory() {
+ private DTEFactory() {
}
- public static DTEntityFactory getInstance() {
+ public static DTEFactory getInstance() {
if (INSTANCE == null) {
- synchronized (DTEntityFactory.class) {
- INSTANCE = new DTEntityFactory();
+ synchronized (DTEFactory.class) {
+ INSTANCE = new DTEFactory();
}
}
return INSTANCE;
@@ -45,18 +48,24 @@ class DTEntityFactory implements ITEntityFactory wrapper = DbEntity.findRelationData(DTEWrapper.class,
+ "DownloadTaskEntity.key=? and DownloadTaskEntity.isGroupTask='false' and DownloadTaskEntity.url=?",
+ entity.getDownloadPath(), entity.getUrl());
+ DownloadTaskEntity taskEntity;
+ if (wrapper != null && !wrapper.isEmpty()) {
+ taskEntity = wrapper.get(0).taskEntity;
+ if (taskEntity == null) {
+ taskEntity = new DownloadTaskEntity();
+ } else if (taskEntity.getEntity() == null || TextUtils.isEmpty(taskEntity.getEntity().getUrl())) {
+ taskEntity.setEntity(entity);
+ }
+ } else {
taskEntity = new DownloadTaskEntity();
- taskEntity.save(entity);
- } else if (taskEntity.entity == null || TextUtils.isEmpty(taskEntity.entity.getUrl())) {
- taskEntity.save(entity);
- } else if (!taskEntity.entity.getUrl().equals(entity.getUrl())) { //处理地址切换而保存路径不变
- taskEntity.save(entity);
}
+ taskEntity.setKey(entity.getDownloadPath());
+ taskEntity.setUrl(entity.getUrl());
+ taskEntity.setEntity(entity);
return taskEntity;
}
@@ -80,6 +89,8 @@ class DTEntityFactory implements ITEntityFactory> {
+
+ /**
+ * 获取任务组的任务实体,
+ * 1、创建实体和任务实体之间的关联
+ * 2、如果在数据库中查找不到对应的数据,则新创建任务实体
+ *
+ * @param groupName 任务组名
+ * @param urls 子任务的下载地址
+ */
+ TASK_ENTITY getGTE(String groupName, List urls);
+
+ /**
+ * 获取FTP文件夹的任务实体,该方法需要以下操作:
+ * 1、创建实体和任务实体之间的关联
+ * 2、如果在数据库中查找不到对应的数据,则新创建任务实体
+ *
+ * @param ftpUrl ftp文件夹下载路径
+ */
+ TASK_ENTITY getFTE(String ftpUrl);
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/manager/ITEntityFactory.java b/Aria/src/main/java/com/arialyy/aria/core/manager/INormalTEFactory.java
similarity index 82%
rename from Aria/src/main/java/com/arialyy/aria/core/manager/ITEntityFactory.java
rename to Aria/src/main/java/com/arialyy/aria/core/manager/INormalTEFactory.java
index d92f7f2c..b55ddcf7 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/manager/ITEntityFactory.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/manager/INormalTEFactory.java
@@ -21,11 +21,7 @@ import com.arialyy.aria.core.inf.AbsTaskEntity;
/**
* Created by Aria.Lao on 2017/11/1.
*/
-interface ITEntityFactory> {
- /**
- * 通过信息实体创建任务实体
- */
- TASK_ENTITY create(ENTITY entity);
+interface INormalTEFactory> {
/**
* 通过key创建任务,只适应于单任务
diff --git a/Aria/src/main/java/com/arialyy/aria/core/manager/TEManager.java b/Aria/src/main/java/com/arialyy/aria/core/manager/TEManager.java
index 56018a88..1e8ccad1 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/manager/TEManager.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/manager/TEManager.java
@@ -18,7 +18,6 @@ package com.arialyy.aria.core.manager;
import android.support.v4.util.LruCache;
import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
-import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.upload.UploadTaskEntity;
import com.arialyy.aria.util.ALog;
@@ -29,7 +28,7 @@ import java.util.concurrent.locks.ReentrantLock;
/**
* Created by Aria.Lao on 2017/11/1.
- * 任务实体管理器,负责
+ * 任务实体管理器
*/
public class TEManager {
private static final String TAG = "TaskManager";
@@ -51,18 +50,17 @@ public class TEManager {
}
/**
- * 通过key创建任务,只适应于单任务,不能用于HTTP任务组,可用于Ftp文件夹
- * 如果是任务组,请使用{@link #createGTEntity(Class, List)}
+ * 通过key创建任务,只适应于单任务
*
* @return 如果任务实体创建失败,返回null
*/
- public TE createTEntity(Class clazz, String key) {
+ private TE createNormalTE(Class clazz, String key) {
final Lock lock = this.lock;
lock.lock();
try {
AbsTaskEntity tEntity = cache.get(convertKey(key));
if (tEntity == null || tEntity.getClass() != clazz) {
- ITEntityFactory factory = chooseFactory(clazz);
+ INormalTEFactory factory = chooseNormalFactory(clazz);
if (factory == null) {
ALog.e(TAG, "任务实体创建失败");
return null;
@@ -77,23 +75,44 @@ public class TEManager {
}
/**
- * 创建任务组实体
+ * 通过key创建不需要缓存的任务实体,只适应于单任务
*
* @return 如果任务实体创建失败,返回null
*/
- public TE createGTEntity(Class clazz, List urls) {
+ public TE createNormalNoCacheTE(Class clazz, String key) {
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ INormalTEFactory factory = chooseNormalFactory(clazz);
+ if (factory == null) {
+ ALog.e(TAG, "任务实体创建失败");
+ return null;
+ }
+ AbsTaskEntity tEntity = factory.create(key);
+ return (TE) tEntity;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * 创建任务组
+ *
+ * @return 如果任务实体创建失败,返回null
+ */
+ private TE createGTEntity(Class clazz, List urls) {
final Lock lock = this.lock;
lock.lock();
try {
String groupName = CommonUtil.getMd5Code(urls);
AbsTaskEntity tEntity = cache.get(convertKey(groupName));
if (tEntity == null || tEntity.getClass() != clazz) {
- IGTEntityFactory factory = chooseGroupFactory(clazz);
+ IGTEFactory factory = chooseGroupFactory(clazz);
if (factory == null) {
ALog.e(TAG, "任务实体创建失败");
return null;
}
- tEntity = factory.create(groupName, urls);
+ tEntity = factory.getGTE(groupName, urls);
cache.put(convertKey(groupName), tEntity);
}
return (TE) tEntity;
@@ -103,23 +122,23 @@ public class TEManager {
}
/**
- * 通过实体创建任务
+ * 通过ftp文件夹路径,创建FTP文件夹实体
*
* @return 如果任务实体创建失败,返回null
*/
- public TE createTEntity(Class clazz, AbsEntity absEntity) {
+ private TE createFDTE(Class clazz, String key) {
final Lock lock = this.lock;
lock.lock();
try {
- AbsTaskEntity tEntity = cache.get(convertKey(absEntity.getKey()));
+ AbsTaskEntity tEntity = cache.get(convertKey(key));
if (tEntity == null || tEntity.getClass() != clazz) {
- ITEntityFactory factory = chooseFactory(clazz);
+ IGTEFactory factory = chooseGroupFactory(clazz);
if (factory == null) {
ALog.e(TAG, "任务实体创建失败");
return null;
}
- tEntity = factory.create(absEntity);
- cache.put(convertKey(absEntity.getKey()), tEntity);
+ tEntity = factory.getFTE(key);
+ cache.put(convertKey(key), tEntity);
}
return (TE) tEntity;
} finally {
@@ -127,26 +146,26 @@ public class TEManager {
}
}
- private IGTEntityFactory chooseGroupFactory(Class clazz) {
+ private IGTEFactory chooseGroupFactory(Class clazz) {
if (clazz == DownloadGroupTaskEntity.class) {
- return DGTEntityFactory.getInstance();
+ return DGTEFactory.getInstance();
}
return null;
}
- private ITEntityFactory chooseFactory(Class clazz) {
+ private INormalTEFactory chooseNormalFactory(Class clazz) {
if (clazz == DownloadTaskEntity.class) {
- return DTEntityFactory.getInstance();
+ return DTEFactory.getInstance();
} else if (clazz == UploadTaskEntity.class) {
- return UTEntityFactory.getInstance();
- } else if (clazz == DownloadGroupTaskEntity.class) {
- return DGTEntityFactory.getInstance();
+ return UTEFactory.getInstance();
}
return null;
}
/**
- * 从任务实体管理器中获取任务实体
+ * 从缓存中获取单任务实体,如果任务实体不存在,则创建任务实体
+ *
+ * @return 创建失败,返回null
*/
public TE getTEntity(Class clazz, String key) {
final Lock lock = this.lock;
@@ -154,7 +173,53 @@ public class TEManager {
try {
AbsTaskEntity tEntity = cache.get(convertKey(key));
if (tEntity == null) {
- return null;
+ return createNormalTE(clazz, key);
+ } else {
+ return (TE) tEntity;
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * 从缓存中获取FTP文件夹任务实体,如果任务实体不存在,则创建任务实体
+ *
+ * @return 创建失败,返回null
+ */
+ public TE getFDTEntity(Class clazz, String key) {
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ AbsTaskEntity tEntity = cache.get(convertKey(key));
+ if (tEntity == null) {
+ return createFDTE(clazz, key);
+ } else {
+ return (TE) tEntity;
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * 从缓存中获取HTTP任务组的任务实体,如果任务实体不存在,则创建任务实体
+ *
+ * @param urls HTTP任务组的子任务下载地址列表
+ * @return 地址列表为null或创建实体失败,返回null
+ */
+ public TE getGTEntity(Class clazz, List urls) {
+ if (urls == null || urls.isEmpty()) {
+ ALog.e(TAG, "获取HTTP任务组实体失败:任务组的子任务下载地址列表为null");
+ return null;
+ }
+ final Lock lock = this.lock;
+ lock.lock();
+ try {
+ String groupName = CommonUtil.getMd5Code(urls);
+ AbsTaskEntity tEntity = cache.get(convertKey(groupName));
+ if (tEntity == null) {
+ return createGTEntity(clazz, urls);
} else {
return (TE) tEntity;
}
@@ -189,7 +254,7 @@ public class TEManager {
final Lock lock = this.lock;
lock.lock();
try {
- return cache.put(convertKey(te.key), te) != null;
+ return cache.put(convertKey(te.getKey()), te) != null;
} finally {
lock.unlock();
}
@@ -210,6 +275,7 @@ public class TEManager {
}
private String convertKey(String key) {
+ key = key.trim();
final Lock lock = this.lock;
lock.lock();
try {
diff --git a/Aria/src/main/java/com/arialyy/aria/core/manager/TaskManager.java b/Aria/src/main/java/com/arialyy/aria/core/manager/TaskManager.java
deleted file mode 100644
index e0f17a0b..00000000
--- a/Aria/src/main/java/com/arialyy/aria/core/manager/TaskManager.java
+++ /dev/null
@@ -1,86 +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.manager;
-
-import com.arialyy.aria.core.AriaManager;
-import com.arialyy.aria.core.inf.AbsTask;
-import com.arialyy.aria.util.ALog;
-import com.arialyy.aria.util.CommonUtil;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Created by Aria.Lao on 2017/9/1.
- * 任务管理器
- */
-class TaskManager {
- private static final String TAG = "TaskManager";
- private static volatile TaskManager INSTANCE = null;
- private Map map = new ConcurrentHashMap<>();
-
- public static TaskManager getInstance() {
- if (INSTANCE == null) {
- synchronized (TaskManager.class) {
- INSTANCE = new TaskManager();
- }
- }
- return INSTANCE;
- }
-
- private TaskManager() {
-
- }
-
- /**
- * 管理器添加任务
- *
- * @param key 任务的key,下载为保存路径,任务组为任务组名,上传为文件上传路径
- * @param task 任务
- * @return {@code true}添加成功
- */
- public boolean addTask(String key, Class clazz, T task) {
- String hash = CommonUtil.keyToHashKey(key);
- if (map.keySet().contains(hash)) {
- ALog.e(TAG, "任务【" + key + "】已存在");
- return false;
- }
- map.put(CommonUtil.keyToHashKey(key), task);
- return true;
- }
-
- /**
- * 移除任务
- *
- * @param key 任务的key,下载为保存路径,任务组为任务组名,上传为文件上传路径
- */
- public void removeTask(String key) {
- String hash = CommonUtil.keyToHashKey(key);
- for (Iterator> iter = map.entrySet().iterator(); iter.hasNext(); ) {
- Map.Entry entry = iter.next();
- if (entry.getKey().equals(hash)) iter.remove();
- }
- }
-
- /**
- * 通过key获取任务
- *
- * @return 如果找不到任务,返回null,否则返回key对应的任务
- */
- public AbsTask getTask(String key) {
- return map.get(CommonUtil.keyToHashKey(key));
- }
-}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/manager/UTEntityFactory.java b/Aria/src/main/java/com/arialyy/aria/core/manager/UTEFactory.java
similarity index 59%
rename from Aria/src/main/java/com/arialyy/aria/core/manager/UTEntityFactory.java
rename to Aria/src/main/java/com/arialyy/aria/core/manager/UTEFactory.java
index 629daa5d..759b2dbd 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/manager/UTEntityFactory.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/manager/UTEFactory.java
@@ -15,43 +15,55 @@
*/
package com.arialyy.aria.core.manager;
+import android.text.TextUtils;
import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTaskEntity;
+import com.arialyy.aria.core.upload.wrapper.UTEWrapper;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.Regular;
+import java.util.List;
import java.util.regex.Pattern;
/**
* Created by Aria.Lao on 2017/11/1.
* 任务实体工厂
*/
-class UTEntityFactory implements ITEntityFactory {
- private static final String TAG = "DTEntityFactory";
- private static volatile UTEntityFactory INSTANCE = null;
+class UTEFactory implements INormalTEFactory {
+ private static final String TAG = "DTEFactory";
+ private static volatile UTEFactory INSTANCE = null;
- private UTEntityFactory() {
+ private UTEFactory() {
}
- public static UTEntityFactory getInstance() {
+ public static UTEFactory getInstance() {
if (INSTANCE == null) {
- synchronized (UTEntityFactory.class) {
- INSTANCE = new UTEntityFactory();
+ synchronized (UTEFactory.class) {
+ INSTANCE = new UTEFactory();
}
}
return INSTANCE;
}
- @Override public UploadTaskEntity create(UploadEntity entity) {
- UploadTaskEntity uTaskEntity =
- DbEntity.findFirst(UploadTaskEntity.class, "key=?", entity.getFilePath());
- if (uTaskEntity == null) {
- uTaskEntity = new UploadTaskEntity();
- uTaskEntity.entity = entity;
- }
- if (uTaskEntity.entity == null) {
- uTaskEntity.entity = entity;
+ private UploadTaskEntity create(UploadEntity entity) {
+ List wrapper =
+ DbEntity.findRelationData(UTEWrapper.class, "UploadTaskEntity.key=?",
+ entity.getFilePath());
+
+ if (wrapper != null && !wrapper.isEmpty()) {
+ UploadTaskEntity uTaskEntity = wrapper.get(0).taskEntity;
+ if (uTaskEntity == null) {
+ uTaskEntity = new UploadTaskEntity();
+ uTaskEntity.setEntity(entity);
+ } else if (uTaskEntity.getEntity() == null || TextUtils.isEmpty(
+ uTaskEntity.getEntity().getFilePath())) {
+ uTaskEntity.setEntity(entity);
+ }
+ return uTaskEntity;
+ } else {
+ UploadTaskEntity uTaskEntity = new UploadTaskEntity();
+ uTaskEntity.setEntity(entity);
+ return uTaskEntity;
}
- return uTaskEntity;
}
@Override public UploadTaskEntity create(String key) {
@@ -67,14 +79,12 @@ class UTEntityFactory implements ITEntityFactory
UploadEntity entity = UploadEntity.findFirst(UploadEntity.class, "filePath=?", filePath);
if (entity == null) {
entity = new UploadEntity();
- //String regex = "[/|\\\\|//]";
String regex = Regular.REG_FILE_NAME;
Pattern p = Pattern.compile(regex);
String[] strs = p.split(filePath);
String fileName = strs[strs.length - 1];
entity.setFileName(fileName);
entity.setFilePath(filePath);
- entity.insert();
}
return entity;
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java b/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java
index b8c02a25..7e96d1d0 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java
@@ -150,10 +150,10 @@ abstract class AbsTaskQueue
&& mExecutePool.getTask(entity.getEntity().getKey()) == null) {
task = (UploadTask) TaskFactory.getInstance()
.createTask(targetName, entity, UploadSchedulers.getInstance());
- entity.key = entity.getEntity().getFilePath();
+ entity.setKey(entity.getEntity().getFilePath());
mCachePool.putTask(task);
} else {
ALog.w(TAG, "任务已存在");
diff --git a/Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java b/Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java
index 83f82b28..5cfdfced 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java
@@ -18,6 +18,7 @@ package com.arialyy.aria.core.scheduler;
import android.os.CountDownTimer;
import android.os.Message;
import com.arialyy.aria.core.AriaManager;
+import com.arialyy.aria.core.download.DownloadGroupTask;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.AbsNormalEntity;
@@ -38,8 +39,8 @@ import java.util.concurrent.ConcurrentHashMap;
* Created by lyy on 2017/6/4.
* 事件调度器,用于处理任务状态的调度
*/
-abstract class AbsSchedulers, QUEUE extends ITaskQueue>
- implements ISchedulers {
+abstract class AbsSchedulers,
+ QUEUE extends ITaskQueue> implements ISchedulers {
private final String TAG = "AbsSchedulers";
protected QUEUE mQueue;
@@ -54,12 +55,12 @@ abstract class AbsSchedulers listener = mObservers.get(targetName);
+ AbsSchedulerListener listener = mObservers.get(getKey(obj));
if (listener == null) {
listener = createListener(targetName);
if (listener != null) {
listener.setListener(obj);
- mObservers.put(targetName, listener);
+ mObservers.put(getKey(obj), listener);
} else {
ALog.e(TAG, "注册错误,没有【" + targetName + "】观察者");
}
@@ -67,18 +68,22 @@ abstract class AbsSchedulers>> iter =
mObservers.entrySet().iterator(); iter.hasNext(); ) {
Map.Entry> entry = iter.next();
- if (entry.getKey().equals(obj.getClass().getName())) {
+ if (entry.getKey().equals(getKey(obj))) {
iter.remove();
}
}
}
+ private String getKey(Object obj) {
+ return obj.getClass().getName() + obj.hashCode();
+ }
+
/**
* 创建代理类
*
@@ -178,7 +183,9 @@ abstract class AbsSchedulers reTryNum) {
+ callback(FAIL, task);
+ mQueue.removeTaskFormQueue(task.getKey());
+ startNextTask();
+ TEManager.getInstance().removeTEntity(task.getKey());
+ return;
+ }
CountDownTimer timer = new CountDownTimer(interval, 1000) {
@Override public void onTick(long millisUntilFinished) {
@@ -269,7 +283,7 @@ abstract class AbsSchedulers> {
+abstract class AbsUploadTarget
+ extends AbsTarget {
- /**
- * 通过key创建任务
- */
- TASK_ENTITY create(String groupName, List urls);
}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/BaseNormalTarget.java b/Aria/src/main/java/com/arialyy/aria/core/upload/BaseNormalTarget.java
new file mode 100644
index 00000000..ad08ddb8
--- /dev/null
+++ b/Aria/src/main/java/com/arialyy/aria/core/upload/BaseNormalTarget.java
@@ -0,0 +1,133 @@
+/*
+ * 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.upload;
+
+import android.support.annotation.NonNull;
+import android.text.TextUtils;
+import com.arialyy.aria.core.manager.TEManager;
+import com.arialyy.aria.core.queue.UploadTaskQueue;
+import com.arialyy.aria.util.ALog;
+import java.io.File;
+
+/**
+ * Created by AriaL on 2018/3/9.
+ */
+abstract class BaseNormalTarget
+ extends AbsUploadTarget {
+
+ protected String mTempUrl;
+
+ void initTarget(String filePath) {
+ mTaskEntity = TEManager.getInstance().getTEntity(UploadTaskEntity.class, filePath);
+ mEntity = mTaskEntity.getEntity();
+ File file = new File(filePath);
+ mEntity.setFileName(file.getName());
+ mEntity.setFileSize(file.length());
+ mTempUrl = mEntity.getUrl();
+ }
+
+ /**
+ * 设置上传路径
+ *
+ * @param uploadUrl 上传路径
+ */
+ public TARGET setUploadUrl(@NonNull String uploadUrl) {
+ mTempUrl = uploadUrl;
+ return (TARGET) this;
+ }
+
+ /**
+ * 上传任务是否存在
+ *
+ * @return {@code true}存在
+ */
+ @Override public boolean taskExists() {
+ return UploadTaskQueue.getInstance().getTask(mEntity.getFilePath()) != null;
+ }
+
+ /**
+ * 是否在上传
+ *
+ * @deprecated {@link #isRunning()}
+ */
+ public boolean isUploading() {
+ return isRunning();
+ }
+
+ @Override public boolean isRunning() {
+ UploadTask task = UploadTaskQueue.getInstance().getTask(mEntity.getKey());
+ return task != null && task.isRunning();
+ }
+
+ @Override protected boolean checkEntity() {
+ boolean b = checkUrl() && checkFilePath();
+ if (b) {
+ mEntity.save();
+ mTaskEntity.save();
+ }
+ return b;
+ }
+
+ /**
+ * 检查上传文件路径是否合法
+ *
+ * @return {@code true} 合法
+ */
+ private boolean checkFilePath() {
+ String filePath = mEntity.getFilePath();
+ if (TextUtils.isEmpty(filePath)) {
+ ALog.e(TAG, "上传失败,文件路径为null");
+ return false;
+ } else if (!filePath.startsWith("/")) {
+ ALog.e(TAG, "上传失败,文件路径【" + filePath + "】不合法");
+ return false;
+ }
+
+ File file = new File(mEntity.getFilePath());
+ if (!file.exists()) {
+ ALog.e(TAG, "上传失败,文件【" + filePath + "】不存在");
+ return false;
+ }
+ if (file.isDirectory()) {
+ ALog.e(TAG, "上传失败,文件【" + filePath + "】不能是文件夹");
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * 检查普通任务的下载地址
+ *
+ * @return {@code true}地址合法
+ */
+ protected boolean checkUrl() {
+ final String url = mTempUrl;
+ if (TextUtils.isEmpty(url)) {
+ ALog.e(TAG, "上传失败,url为null");
+ return false;
+ } else if (!url.startsWith("http") && !url.startsWith("ftp")) {
+ ALog.e(TAG, "上传失败,url【" + url + "】错误");
+ return false;
+ }
+ int index = url.indexOf("://");
+ if (index == -1) {
+ ALog.e(TAG, "上传失败,url【" + url + "】不合法");
+ return false;
+ }
+ mEntity.setUrl(url);
+ return true;
+ }
+}
diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/BaseUListener.java b/Aria/src/main/java/com/arialyy/aria/core/upload/BaseUListener.java
index 48aa5b73..fcb7ad05 100644
--- a/Aria/src/main/java/com/arialyy/aria/core/upload/BaseUListener.java
+++ b/Aria/src/main/java/com/arialyy/aria/core/upload/BaseUListener.java
@@ -136,11 +136,11 @@ class BaseUListener