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 c8868aeb..999b3f1b 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 @@ -335,8 +335,8 @@ 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; } else { 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 87fb4e2d..f522e2ae 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 @@ -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() { 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 a81142f3..82863d1c 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 @@ -55,6 +55,15 @@ public class FtpDirDownloadTarget extends BaseGroupTarget 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; } 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 06a82131..633343ec 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 @@ -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(); - } else { - onStart(); + 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.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,20 +468,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.url, 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); + } } } } 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 e5a47a82..89352252 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 @@ -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,7 +67,12 @@ 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; @@ -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 { - mInitFailNum++; - mActualTaskNum--; - if (mActualTaskNum < 0) mActualTaskNum = 0; - } - failNum++; - if (mInitNum + mInitFailNum >= mGTEntity.getEntity().getSubEntities().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 a7baafea..efbea34d 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 @@ -73,13 +73,14 @@ 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() @@ -96,6 +97,7 @@ class Downloader extends AbsFileer { } } } + return false; } @Override protected AbsThreadTask selectThreadTask(SubThreadConfig config) { 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 1b1b4b3c..5a348ded 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 @@ -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 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(); + } } } 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 7efa26b0..2a03ead9 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 @@ -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()); } - if (mEntity.getSubEntities() == null) { - mEntity.setSubEntities(new ArrayList()); - } mEntity.getSubEntities().add(entity); mTaskEntity.getSubTaskEntities().add(taskEntity); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java index 48fb66f8..7b99c7ec 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java @@ -34,7 +34,7 @@ import org.apache.commons.net.ftp.FTPReply; * Ftp下载任务 */ class FtpThreadTask extends AbsFtpThreadTask { - private final String TAG = "FtpDownloadThreadTask"; + private final String TAG = "FtpThreadTask"; FtpThreadTask(StateConstance constance, IDownloadListener listener, SubThreadConfig downloadInfo) { diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/wrapper/DGroupTaskEntityWrapper.java b/Aria/src/main/java/com/arialyy/aria/core/download/wrapper/DGroupTaskEntityWrapper.java index 0575daee..19ef388f 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/wrapper/DGroupTaskEntityWrapper.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/wrapper/DGroupTaskEntityWrapper.java @@ -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 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); 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 be18161c..0943ef48 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 @@ -139,4 +139,11 @@ public abstract class AbsTaskEntity extends DbEntity { } public abstract String getKey(); + + @Override public void update() { + if (getEntity() != null) { + getEntity().update(); + } + super.update(); + } } 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 index fe5325e8..69e3b559 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/manager/DGTEFactory.java +++ b/Aria/src/main/java/com/arialyy/aria/core/manager/DGTEFactory.java @@ -99,6 +99,13 @@ class DGTEFactory implements IGTEFactory()); + } + if (fte.getSubTaskEntities() == null) { + fte.setSubTaskEntities(new ArrayList()); + } return fte; } 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 a48bb7f5..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; @@ -182,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) { @@ -273,7 +283,7 @@ abstract class AbsSchedulers extends AbsUploadTarget { - 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 * * @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 * * @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 ALog.e(TAG, "上传失败,url【" + url + "】不合法"); return false; } + mEntity.setUrl(url); return true; } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/FtpUploadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/upload/FtpUploadTarget.java index 8c48e213..2acb666b 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/FtpUploadTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/FtpUploadTarget.java @@ -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 implements IFtpTarget { private FtpDelegate 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 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 } } + @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; } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java index 9db2c3fa..bf80d9ff 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadEntity.java @@ -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; /** * 上传完成后服务器返回的数据 diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java index ba4c3457..86c0b055 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/UploadTarget.java @@ -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 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 */ diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpFileInfoThread.java b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpFileInfoThread.java index f31ae371..1db2974d 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpFileInfoThread.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpFileInfoThread.java @@ -58,6 +58,7 @@ class FtpFileInfoThread extends AbsFtpInfoThread //远程文件已完成 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 + 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); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java index f5ee778a..a626fbb0 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java @@ -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 { private final String TAG = "FtpUploadThreadTask"; @@ -114,7 +114,7 @@ class FtpThreadTask extends AbsFtpThreadTask { 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); } diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java index 3143737f..a46feac4 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java @@ -73,6 +73,7 @@ class HttpThreadTask extends AbsThreadTask { 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); diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/Uploader.java b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/Uploader.java index dac6b56d..6e89b915 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/Uploader.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/Uploader.java @@ -65,8 +65,8 @@ class Uploader extends AbsFileer { } } - @Override protected void handleNewTask() { - + @Override protected boolean handleNewTask() { + return true; } @Override protected int setNewTaskThreadNum() { diff --git a/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java b/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java index 84113515..53c104b4 100644 --- a/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java +++ b/Aria/src/main/java/com/arialyy/aria/orm/DBConfig.java @@ -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 mapping = new HashMap<>(); static String DB_NAME; static int VERSION = 31; diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e7f371fb..a5338d32 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -15,10 +15,10 @@ android:supportsRtl="true" android:theme="@style/AppTheme.NoActionBar"> - + diff --git a/app/src/main/assets/aria_config.xml b/app/src/main/assets/aria_config.xml index 9cd82f96..ce92a575 100644 --- a/app/src/main/assets/aria_config.xml +++ b/app/src/main/assets/aria_config.xml @@ -11,7 +11,7 @@ - + diff --git a/app/src/main/java/com/arialyy/simple/test/TestActivity.java b/app/src/main/java/com/arialyy/simple/test/TestActivity.java index 3f1f88d9..75296fba 100644 --- a/app/src/main/java/com/arialyy/simple/test/TestActivity.java +++ b/app/src/main/java/com/arialyy/simple/test/TestActivity.java @@ -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 { 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 { @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; } } diff --git a/app/src/main/java/com/arialyy/simple/test/TestGroupActivity.java b/app/src/main/java/com/arialyy/simple/test/TestGroupActivity.java index d8455218..d8856485 100644 --- a/app/src/main/java/com/arialyy/simple/test/TestGroupActivity.java +++ b/app/src/main/java/com/arialyy/simple/test/TestGroupActivity.java @@ -19,6 +19,7 @@ import java.util.List; public class TestGroupActivity extends BaseActivity { List 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 { 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; } }