1.Ŀ®复了任务重试多次回调问题

2.移除路径被占用导致的崩溃问题
3.支持在任意类中使用回调
pull/330/head
laoyuyu 7 years ago committed by laoyuyu
parent 618db821ed
commit 4d55b95a8d
  1. 8
      Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java
  2. 1
      Aria/src/main/java/com/arialyy/aria/core/common/AbsFtpInfoThread.java
  3. 6
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java
  4. 9
      Aria/src/main/java/com/arialyy/aria/core/download/FtpDirDownloadTarget.java
  5. 95
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/AbsGroupUtil.java
  6. 32
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadGroupUtil.java
  7. 4
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java
  8. 22
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirDownloadUtil.java
  9. 15
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpDirInfoThread.java
  10. 2
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java
  11. 5
      Aria/src/main/java/com/arialyy/aria/core/download/wrapper/DGroupTaskEntityWrapper.java
  12. 7
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java
  13. 7
      Aria/src/main/java/com/arialyy/aria/core/manager/DGTEFactory.java
  14. 14
      Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java
  15. 15
      Aria/src/main/java/com/arialyy/aria/core/upload/BaseNormalTarget.java
  16. 48
      Aria/src/main/java/com/arialyy/aria/core/upload/FtpUploadTarget.java
  17. 3
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java
  18. 12
      Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java
  19. 7
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpFileInfoThread.java
  20. 4
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java
  21. 1
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java
  22. 4
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/Uploader.java
  23. 1
      Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java
  24. 4
      app/src/main/AndroidManifest.xml
  25. 2
      app/src/main/assets/aria_config.xml
  26. 50
      app/src/main/java/com/arialyy/simple/test/TestActivity.java
  27. 19
      app/src/main/java/com/arialyy/simple/test/TestGroupActivity.java

@ -335,8 +335,8 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
recordL[i] = -1;
}
int rl = 0;
if (isNewTask) {
handleNewTask();
if (isNewTask && !handleNewTask()) {
return;
}
for (int i = 0; i < mTotalThreadNum; i++) {
long startL = i * blockSize, endL = (i + 1) * blockSize;
@ -395,8 +395,10 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
/**
* 处理新任务
*
* @return {@code true}创建新任务失败
*/
protected abstract void handleNewTask();
protected abstract boolean handleNewTask();
/**
* 处理不支持断点的下载

@ -171,6 +171,7 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
if (m.find() && m.groupCount() > 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;
} else {

@ -71,16 +71,18 @@ public class DownloadGroupTask extends AbsGroupTask<DownloadGroupTaskEntity> {
@Override public void stop() {
if (!mUtil.isRunning()) {
mListener.onStop(getCurrentProgress());
}
} else {
mUtil.stop();
}
}
@Override public void cancel() {
if (!mUtil.isRunning()) {
mListener.onCancel();
}
} else {
mUtil.cancel();
}
}
@Override public String getTaskName() {
return "任务组->" + (TextUtils.isEmpty(mTaskEntity.getEntity().getAlias())

@ -55,6 +55,15 @@ public class FtpDirDownloadTarget extends BaseGroupTarget<FtpDirDownloadTarget>
if (b) {
mEntity.save();
mTaskEntity.save();
if (mTaskEntity.getSubTaskEntities() != null) {
//初始化子项的登录信息
for (DownloadTaskEntity entity : mTaskEntity.getSubTaskEntities()) {
entity.urlEntity.needLogin = mTaskEntity.urlEntity.needLogin;
entity.urlEntity.account = mTaskEntity.urlEntity.account;
entity.urlEntity.user = mTaskEntity.urlEntity.user;
entity.urlEntity.password = mTaskEntity.urlEntity.password;
}
}
}
return b;
}

@ -84,17 +84,9 @@ public abstract class AbsGroupUtil implements IUtil {
*/
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;
private long mUpdateInterval = 1000;
@ -103,27 +95,6 @@ public abstract class AbsGroupUtil implements IUtil {
mListener = listener;
mGTEntity = groupEntity;
mExePool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
mGroupSize = mGTEntity.getSubTaskEntities().size();
mTotalLen = groupEntity.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.url, te);
mCurrentLocation += file.exists() ? te.getEntity().getCurrentProgress() : 0;
mActualTaskNum++;
}
if (isNeedLoadFileSize) {
mTotalLen += te.getEntity().getFileSize();
}
mTasksMap.put(te.url, te);
}
updateFileSize();
mUpdateInterval =
AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getUpdateInterval();
}
@ -250,7 +221,6 @@ public abstract class AbsGroupUtil implements IUtil {
@Override public void cancel() {
closeTimer(false);
mListener.onCancel();
onCancel();
if (!mExePool.isShutdown()) {
mExePool.shutdown();
@ -263,7 +233,9 @@ public abstract class AbsGroupUtil implements IUtil {
dt.cancel();
}
}
clearState();
CommonUtil.delDownloadGroupTaskConfig(mGTEntity.removeFile, mGTEntity.getEntity());
mListener.onCancel();
}
public void onCancel() {
@ -290,15 +262,36 @@ public abstract class AbsGroupUtil implements IUtil {
}
@Override public void start() {
isRunning = true;
mFailNum = 0;
/**
* 预处理操作由于属性的不同http任务组在构造函数中就可以完成了
* 而FTP文件夹的需要获取完成所有子任务信息才算预处理完成
*/
protected void onPre() {
mListener.onPre();
if (mCompleteNum == mGroupSize) {
mListener.onComplete();
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 {
onStart();
mExeMap.put(te.url, te);
mCurrentLocation += file.exists() ? te.getEntity().getCurrentProgress() : 0;
}
if (isNeedLoadFileSize) {
mTotalLen += te.getEntity().getFileSize();
}
mTasksMap.put(te.url, te);
}
updateFileSize();
}
@Override public void start() {
isRunning = true;
clearState();
onStart();
}
protected void onStart() {
@ -314,6 +307,13 @@ public abstract class AbsGroupUtil implements IUtil {
}
private void clearState(){
mExeMap.clear();
mDownloaderMap.clear();
mFailMap.clear();
mTasksMap.clear();
}
private void closeTimer(boolean isRunning) {
this.isRunning = isRunning;
if (mTimer != null) {
@ -429,7 +429,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);
}
@ -446,13 +446,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);
@ -468,24 +468,27 @@ 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.url, subTaskEntity);
mListener.onSubFail(subEntity);
//如果失败的任务数大于实际的下载任务数,任务组停止下载
if (mFailNum >= mActualTaskNum) {
if (mFailMap.size() >= mExeMap.size()) {
closeTimer(false);
if (mFailMap.size() == mGroupSize) { //所有任务都失败了,则认为该任务组已经失败
mListener.onFail(true);
} else {
mListener.onStop(mCurrentLocation);
}
}
}
}
}
private void reStartTask() {
Timer timer = new Timer();

@ -34,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;
/**
* 文件信息回调组
@ -43,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() {
@ -65,6 +67,11 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
@Override protected void onStart() {
super.onStart();
if (mCompleteNum == mGroupSize) {
mListener.onComplete();
return;
}
if (mExeMap.size() == 0) {
ALog.e(TAG, "任务组无可执行任务");
mListener.onFail(false);
@ -108,32 +115,31 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
}
createChildDownload(te);
}
mInitNum++;
if (mInitNum + mInitFailNum >= mGTEntity.getEntity().getSubEntities().size()
|| !isNeedLoadFileSize) {
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 {
//if (failNum < 3 && !errorMsg.contains("错误码:404") && !errorMsg.contains(
// "UnknownHostException")) {
// mInfoPool.execute(createFileInfoThread(te));
//} else {
// mInitFailNum++;
//}
//failNum++;
mInitFailNum ++;
mActualTaskNum--;
if (mActualTaskNum < 0) mActualTaskNum = 0;
}
failNum++;
if (mInitNum + mInitFailNum >= mGTEntity.getEntity().getSubEntities().size()
|| !isNeedLoadFileSize) {
if (mInitCompleteNum + mInitFailNum >= mGroupSize || !isNeedLoadFileSize) {
startRunningFlow();
updateFileSize();
}

@ -73,13 +73,14 @@ class Downloader extends AbsFileer<DownloadEntity, DownloadTaskEntity> {
}
}
@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()
@ -96,6 +97,7 @@ class Downloader extends AbsFileer<DownloadEntity, DownloadTaskEntity> {
}
}
}
return false;
}
@Override protected AbsThreadTask selectThreadTask(SubThreadConfig<DownloadTaskEntity> config) {

@ -17,10 +17,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.core.manager.TEManager;
import com.arialyy.aria.util.ErrorHelp;
import java.util.Set;
@ -40,19 +38,23 @@ 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, CompleteInfo info) {
if (info.code >= 200 && info.code < 300) {
mActualTaskNum = mGTEntity.getEntity().getSubEntities().size();
mGroupSize = mActualTaskNum;
mTotalLen = mGTEntity.getEntity().getFileSize();
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);
}
@ -61,6 +63,10 @@ public class FtpDirDownloadUtil extends AbsGroupUtil {
}
private void startDownload() {
if (mCompleteNum == mGroupSize) {
mListener.onComplete();
return;
}
int i = 0;
Set<String> keys = mExeMap.keySet();
for (String key : keys) {
@ -70,6 +76,10 @@ public class FtpDirDownloadUtil extends AbsGroupUtil {
i++;
}
}
if (i == mExeMap.size()) startRunningFlow();
if (mExeMap.size() == 0) {
mListener.onComplete();
} else if (i == mExeMap.size()) {
startRunningFlow();
}
}
}

@ -23,6 +23,7 @@ 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;
@ -57,10 +58,10 @@ class FtpDirInfoThread extends AbsFtpInfoThread<DownloadGroupEntity, DownloadGro
* FTP文件夹的子任务实体 在这生成
*/
private void addEntity(String remotePath, FTPFile ftpFile) {
final FtpUrlEntity urlEntity = mTaskEntity.urlEntity;
final FtpUrlEntity urlEntity = mTaskEntity.urlEntity.clone();
DownloadEntity entity = new DownloadEntity();
entity.setUrl(
urlEntity.protocol + "://" + urlEntity.hostName + ":" + urlEntity.port + remotePath);
urlEntity.protocol + "://" + urlEntity.hostName + ":" + urlEntity.port + "/" + remotePath);
entity.setDownloadPath(mEntity.getDirPath() + "/" + remotePath);
int lastIndex = remotePath.lastIndexOf("/");
String fileName = lastIndex < 0 ? CommonUtil.keyToHashKey(remotePath)
@ -74,16 +75,18 @@ class FtpDirInfoThread extends AbsFtpInfoThread<DownloadGroupEntity, DownloadGro
DownloadTaskEntity taskEntity = new DownloadTaskEntity();
taskEntity.key = entity.getDownloadPath();
taskEntity.url = entity.getUrl();
taskEntity.isGroupTask = false;
taskEntity.entity = entity;
taskEntity.isGroupTask = true;
taskEntity.groupName = mEntity.getGroupName();
taskEntity.requestType = AbsTaskEntity.D_FTP;
urlEntity.url = entity.getUrl();
urlEntity.remotePath = remotePath;
taskEntity.urlEntity = urlEntity;
taskEntity.insert();
if (mEntity.getUrls() == null) {
mEntity.setUrls(new ArrayList<String>());
}
if (mEntity.getSubEntities() == null) {
mEntity.setSubEntities(new ArrayList<DownloadEntity>());
}
mEntity.getSubEntities().add(entity);
mTaskEntity.getSubTaskEntities().add(taskEntity);
}

@ -34,7 +34,7 @@ import org.apache.commons.net.ftp.FTPReply;
* Ftp下载任务
*/
class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity> {
private final String TAG = "FtpDownloadThreadTask";
private final String TAG = "FtpThreadTask";
FtpThreadTask(StateConstance constance, IDownloadListener listener,
SubThreadConfig<DownloadTaskEntity> downloadInfo) {

@ -18,11 +18,13 @@ 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;
@ -51,6 +53,9 @@ public class DGroupTaskEntityWrapper extends AbsWrapper {
if (subWrappers != null && !subWrappers.isEmpty()) {
List<DownloadTaskEntity> temp = new ArrayList<>();
for (DownloadTaskWrapper dw : subWrappers) {
if (dw.taskEntity.requestType == AbsTaskEntity.D_FTP) {
dw.taskEntity.urlEntity = CommonUtil.getFtpUrlInfo(dw.taskEntity.url);
}
temp.add(dw.taskEntity);
}
taskEntity.setSubTaskEntities(temp);

@ -139,4 +139,11 @@ public abstract class AbsTaskEntity<ENTITY extends AbsEntity> extends DbEntity {
}
public abstract String getKey();
@Override public void update() {
if (getEntity() != null) {
getEntity().update();
}
super.update();
}
}

@ -99,6 +99,13 @@ class DGTEFactory implements IGTEFactory<DownloadGroupEntity, DownloadGroupTaskE
}
fte.setKey(ftpUrl);
fte.urlEntity = CommonUtil.getFtpUrlInfo(ftpUrl);
if (fte.getEntity().getSubEntities() == null) {
fte.getEntity().setSubEntities(new ArrayList<DownloadEntity>());
}
if (fte.getSubTaskEntities() == null) {
fte.setSubTaskEntities(new ArrayList<DownloadTaskEntity>());
}
return fte;
}

@ -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;
@ -182,8 +183,10 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskEntity, TASK extends Abs
} else {
TEManager.getInstance().putTEntity(task.getKey(), task.getTaskEntity());
}
if (what != FAIL) {
callback(what, task);
}
}
/**
* 回调
@ -257,7 +260,7 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskEntity, TASK extends Abs
}
long interval = 2000;
int num = 10;
if (task instanceof DownloadTask) {
if (task instanceof DownloadTask || task instanceof DownloadGroupTask) {
interval = AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getReTryInterval();
num = AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getReTryNum();
} else if (task instanceof UploadTask) {
@ -266,6 +269,13 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskEntity, TASK extends Abs
}
final int reTryNum = num;
if (task.getTaskEntity().getEntity().getFailNum() > 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) {
@ -273,7 +283,7 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskEntity, TASK extends Abs
@Override public void onFinish() {
AbsEntity entity = task.getTaskEntity().getEntity();
if (entity.getFailNum() < reTryNum) {
if (entity.getFailNum() <= reTryNum) {
TASK task = mQueue.getTask(entity.getKey());
mQueue.reTryStart(task);
} else {

@ -28,12 +28,15 @@ import java.io.File;
abstract class BaseNormalTarget<TARGET extends AbsUploadTarget>
extends AbsUploadTarget<TARGET, UploadEntity, UploadTaskEntity> {
protected void initTarget(String filePath) {
protected String mTempUrl;
void initTarget(String filePath) {
mTaskEntity = TEManager.getInstance().getTEntity(UploadTaskEntity.class, filePath);
mEntity = mTaskEntity.entity;
File file = new File(filePath);
mEntity.setFileName(file.getName());
mEntity.setFileSize(file.length());
mTempUrl = mEntity.getUrl();
}
/**
@ -41,7 +44,10 @@ abstract class BaseNormalTarget<TARGET extends AbsUploadTarget>
*
* @param uploadUrl 上传路径
*/
public abstract TARGET setUploadUrl(@NonNull String uploadUrl);
public TARGET setUploadUrl(@NonNull String uploadUrl) {
mTempUrl = uploadUrl;
return (TARGET) this;
}
/**
* 上传任务是否存在
@ -107,8 +113,8 @@ abstract class BaseNormalTarget<TARGET extends AbsUploadTarget>
*
* @return {@code true}地址合法
*/
private boolean checkUrl() {
final String url = mEntity.getUrl();
protected boolean checkUrl() {
final String url = mTempUrl;
if (TextUtils.isEmpty(url)) {
ALog.e(TAG, "上传失败,url为null");
return false;
@ -121,6 +127,7 @@ abstract class BaseNormalTarget<TARGET extends AbsUploadTarget>
ALog.e(TAG, "上传失败,url【" + url + "】不合法");
return false;
}
mEntity.setUrl(url);
return true;
}
}

@ -15,13 +15,11 @@
*/
package com.arialyy.aria.core.upload;
import android.support.annotation.NonNull;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.command.normal.NormalCmdFactory;
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.util.CheckUtil;
import com.arialyy.aria.util.CommonUtil;
/**
@ -32,6 +30,9 @@ public class FtpUploadTarget extends BaseNormalTarget<FtpUploadTarget>
implements IFtpTarget<FtpUploadTarget> {
private FtpDelegate<FtpUploadTarget, UploadEntity, UploadTaskEntity> mDelegate;
private String mAccount, mUser, mPw;
private boolean needLogin = false;
FtpUploadTarget(String filePath, String targetName) {
this.mTargetName = targetName;
initTask(filePath);
@ -43,25 +44,6 @@ public class FtpUploadTarget extends BaseNormalTarget<FtpUploadTarget>
mDelegate = new FtpDelegate<>(this, mTaskEntity);
}
/**
* 设置上传路径FTP上传路径必须是从"/"开始的完整路径
*
* @param uploadUrl 上传路径
*/
@Override
public FtpUploadTarget setUploadUrl(@NonNull String uploadUrl) {
if (!CheckUtil.checkUrl(uploadUrl)) {
return this;
}
if (!uploadUrl.endsWith("/")) {
uploadUrl += "/";
}
mTaskEntity.urlEntity = CommonUtil.getFtpUrlInfo(uploadUrl);
if (mEntity.getUrl().equals(uploadUrl)) return this;
mEntity.setUrl(uploadUrl);
return this;
}
/**
* 添加任务
*/
@ -74,15 +56,35 @@ public class FtpUploadTarget extends BaseNormalTarget<FtpUploadTarget>
}
}
@Override protected boolean checkUrl() {
boolean b = super.checkUrl();
if (!b) {
return false;
}
mTaskEntity.urlEntity = CommonUtil.getFtpUrlInfo(mTempUrl);
mTaskEntity.urlEntity.account = mAccount;
mTaskEntity.urlEntity.user = mUser;
mTaskEntity.urlEntity.password = mPw;
mTaskEntity.urlEntity.needLogin = needLogin;
return true;
}
@Override public FtpUploadTarget charSet(String charSet) {
return mDelegate.charSet(charSet);
}
@Override public FtpUploadTarget login(String userName, String password) {
return mDelegate.login(userName, password);
needLogin = true;
mUser = userName;
mPw = password;
return this;
}
@Override public FtpUploadTarget login(String userName, String password, String account) {
return mDelegate.login(userName, password, account);
needLogin = true;
mUser = userName;
mPw = password;
mAccount = account;
return this;
}
}

@ -19,7 +19,6 @@ import android.os.Parcel;
import android.os.Parcelable;
import com.arialyy.aria.core.inf.AbsNormalEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.orm.annotation.Foreign;
import com.arialyy.aria.orm.annotation.Primary;
/**
@ -30,7 +29,7 @@ public class UploadEntity extends AbsNormalEntity implements Parcelable {
/**
* 文件上传路径
*/
@Primary @Foreign(parent = UploadTaskEntity.class, column = "key") private String filePath;
@Primary private String filePath;
/**
* 上传完成后服务器返回的数据

@ -20,7 +20,6 @@ import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.delegate.HttpHeaderDelegate;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IHttpHeaderTarget;
import com.arialyy.aria.util.CheckUtil;
import java.util.Map;
/**
@ -45,17 +44,6 @@ public class UploadTarget extends BaseNormalTarget<UploadTarget>
mDelegate = new HttpHeaderDelegate<>(this, mTaskEntity);
}
@Override public UploadTarget setUploadUrl(@NonNull String uploadUrl) {
if (!CheckUtil.checkUrl(uploadUrl)){
return this;
}
if (mEntity.getUrl().equals(uploadUrl)) {
return this;
}
mEntity.setUrl(uploadUrl);
return this;
}
/**
* 设置userAgent
*/

@ -58,6 +58,7 @@ class FtpFileInfoThread extends AbsFtpInfoThread<UploadEntity, UploadTaskEntity>
//远程文件已完成
if (ftpFile.getSize() == mEntity.getFileSize()) {
isComplete = true;
ALog.d(TAG, "FTP服务器上已存在该文件【" + ftpFile.getName() + "】");
} else {
ALog.w(TAG, "FTP服务器已存在未完成的文件【"
+ ftpFile.getName()
@ -65,16 +66,16 @@ class FtpFileInfoThread extends AbsFtpInfoThread<UploadEntity, UploadTaskEntity>
+ ftpFile.getSize()
+ "】"
+ "尝试从位置:"
+ ftpFile.getSize()
+ (ftpFile.getSize() - 1)
+ "开始上传");
File configFile = new File(CommonUtil.getFileConfigPath(false, mEntity.getFileName()));
Properties pro = CommonUtil.loadConfig(configFile);
String key = mEntity.getFileName() + "_record_" + 0;
mTaskEntity.isNewTask = false;
long oldRecord = Long.parseLong(pro.getProperty(key, "0"));
if (oldRecord == 0) {
if (oldRecord == 0 || oldRecord != ftpFile.getSize()) {
//修改本地保存的停止地址为服务器上对应文件的大小
pro.setProperty(key, ftpFile.getSize() + "");
pro.setProperty(key, (ftpFile.getSize() - 1) + "");
CommonUtil.saveConfig(configFile, pro);
}
}

@ -32,7 +32,7 @@ import org.apache.commons.net.ftp.OnFtpInputStreamListener;
/**
* Created by Aria.Lao on 2017/7/28.
* FTP 单线程上传任务需要FTP 服务器给用户打开删除和读入IO的权限
* FTP 单线程上传任务需要FTP 服务器给用户打开append和write的权限
*/
class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
private final String TAG = "FtpUploadThreadTask";
@ -114,7 +114,7 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
private void initPath() throws UnsupportedEncodingException {
dir = new String(mTaskEntity.urlEntity.remotePath.getBytes(charSet), SERVER_CHARSET);
remotePath = new String(
("/" + mTaskEntity.urlEntity.remotePath + mEntity.getFileName()).getBytes(charSet),
("/" + mTaskEntity.urlEntity.remotePath + "/" + mEntity.getFileName()).getBytes(charSet),
SERVER_CHARSET);
}

@ -73,6 +73,7 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
mHttpConn.setRequestProperty("Content-Type",
mTaskEntity.contentType + "; boundary=" + BOUNDARY);
mHttpConn.setRequestProperty("User-Agent", mTaskEntity.userAgent);
mHttpConn.setConnectTimeout(5000);
//mHttpConn.setRequestProperty("Range", "bytes=" + 0 + "-" + "100");
//内部缓冲区---分段上传防止oom
mHttpConn.setChunkedStreamingMode(1024);

@ -65,8 +65,8 @@ class Uploader extends AbsFileer<UploadEntity, UploadTaskEntity> {
}
}
@Override protected void handleNewTask() {
@Override protected boolean handleNewTask() {
return true;
}
@Override protected int setNewTaskThreadNum() {

@ -31,6 +31,7 @@ import java.util.Map;
* 数据库配置信息
*/
class DBConfig {
/*adb pull /mnt/sdcard/Android/data/com.arialyy.simple/files/DB/AriaLyyDb d:/db*/
static Map<String, Class> mapping = new HashMap<>();
static String DB_NAME;
static int VERSION = 31;

@ -15,10 +15,10 @@
android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar">
<!--android:name=".MainActivity"-->
<!--android:name=".test.TestActivity"-->
<!--android:name=".test.AnyRunActivity"-->
<!--android:name=".test.TestGroupActivity"-->
<activity
android:name=".test.AnyRunActivity"
android:name=".test.TestActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

@ -11,7 +11,7 @@
<maxTaskNum value="2"/>
<!--设置下载失败,重试次数,默认为10-->
<reTryNum value="1"/>
<reTryNum value="2"/>
<!--设置重试间隔,单位为毫秒,默认2000毫秒-->
<reTryInterval value="5000"/>

@ -1,15 +1,12 @@
package com.arialyy.simple.test;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import com.arialyy.annotations.Download;
import com.arialyy.annotations.Upload;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.upload.UploadTask;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.util.show.L;
import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.databinding.ActivityTestBinding;
@ -21,7 +18,11 @@ import java.io.File;
public class TestActivity extends BaseActivity<ActivityTestBinding> {
String TAG = "TestActivity";
String URL = "http://58.210.9.131/tpk/sipgt//TDLYZTGH.tpk"; //chunked 下载
//String URL = "http://58.210.9.131/tpk/sipgt//TDLYZTGH.tpk"; //chunked 下载
//private final String URL = "ftp://192.168.1.3:21/download//AriaPrj.rar";
private final String FILE_PATH = "/mnt/sdcard/AriaPrj.rar";
//private final String URL = "ftp://192.168.29.140:21/aa//你好";
private final String URL = "http://192.168.29.140:5000/upload/";
@Override protected int setLayoutId() {
return R.layout.activity_test;
@ -30,62 +31,55 @@ public class TestActivity extends BaseActivity<ActivityTestBinding> {
@Override protected void init(Bundle savedInstanceState) {
super.init(savedInstanceState);
mBar.setVisibility(View.GONE);
Aria.download(this).register();
Aria.upload(this).register();
}
@Download.onWait void onWait(DownloadTask task) {
Log.d(TAG, "wait ==> " + task.getDownloadEntity().getFileName());
@Upload.onWait void onWait(UploadTask task) {
Log.d(TAG, "wait ==> " + task.getEntity().getFileName());
}
@Download.onPre protected void onPre(DownloadTask task) {
@Upload.onPre protected void onPre(UploadTask task) {
Log.d(TAG, "onPre");
}
@Download.onTaskStart void taskStart(DownloadTask task) {
@Upload.onTaskStart void taskStart(UploadTask task) {
Log.d(TAG, "onStart");
}
@Download.onTaskRunning protected void running(DownloadTask task) {
@Upload.onTaskRunning protected void running(UploadTask task) {
Log.d(TAG, "running");
}
@Download.onTaskResume void taskResume(DownloadTask task) {
@Upload.onTaskResume void taskResume(UploadTask task) {
Log.d(TAG, "resume");
}
@Download.onTaskStop void taskStop(DownloadTask task) {
@Upload.onTaskStop void taskStop(UploadTask task) {
Log.d(TAG, "stop");
}
@Download.onTaskCancel void taskCancel(DownloadTask task) {
@Upload.onTaskCancel void taskCancel(UploadTask task) {
Log.d(TAG, "cancel");
}
@Download.onTaskFail void taskFail(DownloadTask task) {
@Upload.onTaskFail void taskFail(UploadTask task) {
Log.d(TAG, "fail");
}
@Download.onTaskComplete void taskComplete(DownloadTask task) {
L.d(TAG, "path ==> " + task.getDownloadEntity().getDownloadPath());
L.d(TAG, "md5Code ==> " + CommonUtil.getFileMD5(new File(task.getDownloadPath())));
@Upload.onTaskComplete void taskComplete(UploadTask task) {
Log.d(TAG, "complete, md5 => " + CommonUtil.getFileMD5(new File(task.getKey())));
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
Aria.download(this)
.load(URL)
.addHeader("Accept-Encoding", "gzip, deflate")
.setRequestMode(RequestEnum.GET)
.setFilePath(Environment.getExternalStorageDirectory().getPath() + "/ggsg1.apk")
.resetState()
.start();
Aria.upload(this).load(FILE_PATH).setUploadUrl(URL).setExtendField("韩寒哈大双").setAttachment("file").start();
break;
case R.id.stop:
Aria.download(this).load(URL).stop();
Aria.upload(this).load(FILE_PATH).stop();
break;
case R.id.cancel:
Aria.download(this).load(URL).cancel();
Aria.upload(this).load(FILE_PATH).cancel();
break;
}
}

@ -19,6 +19,7 @@ import java.util.List;
public class TestGroupActivity extends BaseActivity<ActivityTestBinding> {
List<String> mUrls;
private static final String dir = "ftp://192.168.1.8:21/upload/测试";
@Override protected int setLayoutId() {
return R.layout.activity_test;
@ -74,17 +75,25 @@ public class TestGroupActivity extends BaseActivity<ActivityTestBinding> {
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
//Aria.download(this)
// .loadGroup(mUrls)
// .setDirPath(Environment.getExternalStorageDirectory().getPath() + "/download/test/")
// .resetState()
// .start();
Aria.download(this)
.loadGroup(mUrls)
.setDirPath(Environment.getExternalStorageDirectory().getPath() + "/download/test/")
.resetState()
.loadFtpDir(dir)
.setDirPath(
Environment.getExternalStorageDirectory().getPath() + "/Download/ftp_dir")
.setGroupAlias("ftp文件夹下载")
//.setSubTaskFileName(getModule(GroupModule.class).getSubName())
.login("lao", "123456")
.start();
break;
case R.id.stop:
Aria.download(this).loadGroup(mUrls).stop();
Aria.download(this).loadFtpDir(dir).stop();
break;
case R.id.cancel:
Aria.download(this).loadGroup(mUrls).cancel();
Aria.download(this).loadFtpDir(dir).cancel();
break;
}
}

Loading…
Cancel
Save