diff --git a/Aria/build.gradle b/Aria/build.gradle index 75008e89..7f47d267 100644 --- a/Aria/build.gradle +++ b/Aria/build.gradle @@ -23,8 +23,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.0' - compile project(':AriaFtpPlug') + compile 'com.arialyy.aria:aria-ftp-plug:1.0.1' +// compile project(':AriaFtpPlug') } apply from: 'bintray-release.gradle' diff --git a/Aria/src/main/java/com/arialyy/aria/core/TaskManager.java b/Aria/src/main/java/com/arialyy/aria/core/TaskManager.java index 470ab6db..4954ff96 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/TaskManager.java +++ b/Aria/src/main/java/com/arialyy/aria/core/TaskManager.java @@ -31,7 +31,7 @@ public class TaskManager { private static volatile TaskManager INSTANCE = null; private Map map = new ConcurrentHashMap<>(); - public TaskManager getInstance() { + public static TaskManager getInstance() { if (INSTANCE == null) { synchronized (AriaManager.LOCK) { INSTANCE = new TaskManager(); 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 cec2011c..84f9c2dc 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 @@ -1,7 +1,6 @@ package com.arialyy.aria.core.command.normal; import android.util.Log; -import com.arialyy.aria.core.Aria; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.download.DownloadGroupTaskEntity; import com.arialyy.aria.core.download.DownloadTaskEntity; @@ -30,7 +29,7 @@ final class ResumeAllCmd extends AbsNormalCmd { } @Override public void executeCmd() { - if (!NetUtils.isConnected(AriaManager.APP)){ + if (!NetUtils.isConnected(AriaManager.APP)) { Log.w(TAG, "恢复任务失败,网络未连接"); return; } @@ -49,18 +48,22 @@ final class ResumeAllCmd extends AbsNormalCmd { DbEntity.findDatas(DownloadTaskEntity.class, "isGroupTask=?", "false"); if (dTaskEntity != null && !dTaskEntity.isEmpty()) { for (DownloadTaskEntity te : dTaskEntity) { + if (te == null || te.getEntity() == null) continue; int state = te.getState(); - if (state == IEntity.STATE_COMPLETE || state == IEntity.STATE_FAIL) continue; - resumeEntity(te); + if (state == IEntity.STATE_STOP || state == IEntity.STATE_OTHER) { + resumeEntity(te); + } } } List groupTask = DbEntity.findAllData(DownloadGroupTaskEntity.class); if (groupTask != null && !groupTask.isEmpty()) { for (DownloadGroupTaskEntity te : groupTask) { + if (te == null || te.getEntity() == null) continue; int state = te.getState(); - if (state == IEntity.STATE_COMPLETE || state == IEntity.STATE_FAIL) continue; - resumeEntity(te); + if (state == IEntity.STATE_STOP || state == IEntity.STATE_OTHER) { + resumeEntity(te); + } } } } @@ -73,9 +76,11 @@ final class ResumeAllCmd extends AbsNormalCmd { DbEntity.findDatas(UploadTaskEntity.class, "isGroupTask=?", "false"); if (dTaskEntity != null && !dTaskEntity.isEmpty()) { for (UploadTaskEntity te : dTaskEntity) { + if (te == null || te.getEntity() == null) continue; int state = te.getState(); - if (state == IEntity.STATE_COMPLETE || state == IEntity.STATE_FAIL) continue; - resumeEntity(te); + if (state == IEntity.STATE_STOP || state == IEntity.STATE_OTHER) { + resumeEntity(te); + } } } } 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 62f4982c..5a3a0190 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 @@ -70,7 +70,6 @@ class StartCmd extends AbsNormalCmd { } } } else { - // 任务不存在时,根据配置不同,对任务执行操作 if (!task.isRunning()) { startTask(); } 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 4dee42c4..ed7a56b5 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 @@ -96,8 +96,7 @@ public abstract class AbsFileer= 0) { mListener.onProgress(mConstance.CURRENT_LOCATION); @@ -179,9 +181,9 @@ public abstract class AbsFileer config); - } diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/AbsFtpInfoThread.java b/Aria/src/main/java/com/arialyy/aria/core/common/AbsFtpInfoThread.java index e0d7519d..adabb171 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/AbsFtpInfoThread.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/AbsFtpInfoThread.java @@ -23,7 +23,6 @@ import com.arialyy.aria.core.download.DownloadGroupEntity; import com.arialyy.aria.core.inf.AbsEntity; import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.upload.UploadEntity; -import com.arialyy.aria.util.CommonUtil; import java.io.IOException; import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTPClient; @@ -37,7 +36,7 @@ import org.apache.commons.net.ftp.FTPReply; public abstract class AbsFtpInfoThread> implements Runnable { - private final String TAG = "HttpFileInfoThread"; + private final String TAG = "AbsFtpInfoThread"; protected ENTITY mEntity; protected TASK_ENTITY mTaskEntity; private int mConnectTimeOut; @@ -86,6 +85,9 @@ public abstract class AbsFtpInfoThread mTasksMap = new HashMap<>(); + /** + * 是否需要读取文件长度,{@code true}需要 + */ + boolean isNeedLoadFileSize = true; //已经完成的任务数 private int mCompleteNum = 0; //失败的任务数 private int mFailNum = 0; //停止的任务数 private int mStopNum = 0; + //实际的下载任务数 int mActualTaskNum = 0; - /** - * 是否需要读取文件长度,{@code true}需要 - */ - boolean isNeedLoadFileSize = true; + //初始化完成的任务数 + int mInitNum = 0; + // 初始化失败的任务数 + int mInitFailNum = 0; + + //任务组大小 + int mGroupSize = 0; AbsGroupUtil(IDownloadGroupListener listener, DownloadGroupTaskEntity taskEntity) { mListener = listener; @@ -105,14 +105,13 @@ public abstract class AbsGroupUtil implements IUtil { mTasksMap.put(te.getEntity().getUrl(), te); } } - mTotalSize = taskEntity.getEntity().getFileSize(); - isNeedLoadFileSize = mTotalSize <= 1; + mGroupSize = mTaskEntity.entity.getSubTask().size(); + mTotalLen = taskEntity.getEntity().getFileSize(); + isNeedLoadFileSize = mTotalLen <= 1; for (DownloadEntity entity : mTaskEntity.entity.getSubTask()) { File file = new File(entity.getDownloadPath()); if (entity.getState() == IEntity.STATE_COMPLETE && file.exists()) { mCompleteNum++; - mInitNum++; - mStopNum++; mCurrentLocation += entity.getFileSize(); } else { mExeMap.put(entity.getUrl(), createChildDownloadTask(entity)); @@ -120,7 +119,7 @@ public abstract class AbsGroupUtil implements IUtil { mActualTaskNum++; } if (isNeedLoadFileSize) { - mTotalSize += entity.getFileSize(); + mTotalLen += entity.getFileSize(); } } updateFileSize(); @@ -128,7 +127,7 @@ public abstract class AbsGroupUtil implements IUtil { void updateFileSize() { if (isNeedLoadFileSize) { - mTaskEntity.getEntity().setFileSize(mTotalSize); + mTaskEntity.getEntity().setFileSize(mTotalLen); mTaskEntity.getEntity().update(); } } @@ -212,7 +211,7 @@ public abstract class AbsGroupUtil implements IUtil { } @Override public long getFileSize() { - return mTotalSize; + return mTotalLen; } @Override public long getCurrentLocation() { @@ -272,7 +271,6 @@ public abstract class AbsGroupUtil implements IUtil { @Override public void stop() { closeTimer(false); - mListener.onStop(mCurrentLocation); onStop(); if (!mExePool.isShutdown()) { mExePool.shutdown(); @@ -325,7 +323,7 @@ public abstract class AbsGroupUtil implements IUtil { */ void startRunningFlow() { closeTimer(true); - mListener.onPostPre(mTotalSize); + mListener.onPostPre(mTotalLen); mListener.onStart(mCurrentLocation); startTimer(); } @@ -413,8 +411,8 @@ public abstract class AbsGroupUtil implements IUtil { ChildDownloadListener(DownloadTaskEntity entity) { this.taskEntity = entity; this.entity = taskEntity.getEntity(); - lastLen = this.entity.getCurrentProgress(); this.entity.setFailNum(0); + lastLen = this.entity.getCurrentProgress(); mLastSaveTime = System.currentTimeMillis(); } @@ -458,10 +456,12 @@ public abstract class AbsGroupUtil implements IUtil { saveData(IEntity.STATE_STOP, stopLocation); handleSpeed(0); mListener.onSubStop(entity); - mStopNum++; - if (mStopNum + mCompleteNum >= mInitNum) { - closeTimer(false); - mListener.onStop(mCurrentLocation); + synchronized (AbsGroupUtil.class) { + mStopNum++; + if (mStopNum + mCompleteNum + mInitFailNum + mFailNum >= mGroupSize) { + closeTimer(false); + mListener.onStop(mCurrentLocation); + } } } @@ -473,16 +473,19 @@ public abstract class AbsGroupUtil implements IUtil { @Override public void onComplete() { saveData(IEntity.STATE_COMPLETE, entity.getFileSize()); - mCompleteNum++; handleSpeed(0); mListener.onSubComplete(entity); - //如果子任务完成的数量和总任务数一致,表示任务组任务已经完成 - if (mCompleteNum >= mTaskEntity.getEntity().getSubTask().size()) { - closeTimer(false); - mListener.onComplete(); - } else if (mCompleteNum + mFailNum >= mActualTaskNum) { - //如果子任务完成数量加上失败的数量和总任务数一致,则任务组停止下载 - closeTimer(false); + synchronized (AbsGroupUtil.class) { + mCompleteNum++; + //如果子任务完成的数量和总任务数一致,表示任务组任务已经完成 + if (mCompleteNum >= mGroupSize) { + closeTimer(false); + mListener.onComplete(); + } else if (mStopNum + mCompleteNum + mInitFailNum + mFailNum >= mGroupSize) { + //如果子任务完成数量加上失败的数量和总任务数一致,则任务组停止下载 + closeTimer(false); + 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 951200b2..88319a74 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 @@ -74,7 +74,7 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil { } } if (i != 0 && i == mExeMap.size()) startRunningFlow(); - if (mCurrentLocation == mTotalSize) { + if (mCurrentLocation == mTotalLen) { mListener.onComplete(); } } @@ -93,7 +93,7 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil { DownloadTaskEntity te = mExeMap.get(url); if (te != null) { if (isNeedLoadFileSize) { - mTotalSize += te.getEntity().getFileSize(); + mTotalLen += te.getEntity().getFileSize(); } createChildDownload(te); } 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 d3cd1d15..f12b6ef4 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 @@ -16,7 +16,6 @@ package com.arialyy.aria.core.download.downloader; import android.util.Log; -import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.common.AbsFileer; import com.arialyy.aria.core.common.AbsThreadTask; import com.arialyy.aria.core.common.SubThreadConfig; @@ -43,10 +42,7 @@ class Downloader extends AbsFileer { } @Override protected void checkTask() { - mConfigFile = new File(mContext.getFilesDir().getPath() - + AriaManager.DOWNLOAD_TEMP_DIR - + mEntity.getFileName() - + ".properties"); + mConfigFile = new File(CommonUtil.getFileConfigPath(true, mEntity.getFileName())); mTempFile = new File(mEntity.getDownloadPath()); if (!mTaskEntity.isSupportBP) { isNewTask = true; 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 a6810949..a730eb57 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 @@ -43,6 +43,8 @@ public class FtpDirDownloadUtil extends AbsGroupUtil { mExeMap.put(entity.getUrl(), createChildDownloadTask(entity)); } mActualTaskNum = mTaskEntity.entity.getSubTask().size(); + mGroupSize = mActualTaskNum; + mTotalLen = mTaskEntity.entity.getFileSize(); startDownload(); } } 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 ccbec98d..36afd539 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 @@ -32,9 +32,7 @@ class FtpFileInfoThread extends AbsFtpInfoThread implements IPool { } String convertKey = CommonUtil.keyToHashKey(key); TASK task = mExecuteMap.get(convertKey); - mExecuteMap.remove(convertKey); - return mExecuteQueue.remove(task); + if (mExecuteQueue.remove(task)) { + mExecuteMap.remove(convertKey); + return true; + } + return false; } } 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 3089c9ab..2704e55b 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 @@ -19,7 +19,6 @@ import android.os.CountDownTimer; import android.os.Message; import android.util.Log; import com.arialyy.aria.core.AriaManager; -import com.arialyy.aria.core.command.normal.NormalCmdFactory; import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.core.inf.AbsEntity; import com.arialyy.aria.core.inf.AbsNormalEntity; @@ -29,7 +28,6 @@ import com.arialyy.aria.core.inf.GroupSendParams; import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.queue.ITaskQueue; import com.arialyy.aria.core.upload.UploadTask; -import com.arialyy.aria.util.NetUtils; import java.util.Iterator; import java.util.Map; import java.util.Set; 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 780b5540..4863ca2b 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 @@ -47,7 +47,7 @@ public class FtpUploadTarget mEntity.setFileSize(file.length()); //暂时不支持断点续传上传 - mTaskEntity.isSupportBP = false; + //mTaskEntity.isSupportBP = false; } /** diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/ProgressInputStream.java b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpFISAdapter.java similarity index 88% rename from Aria/src/main/java/com/arialyy/aria/core/upload/uploader/ProgressInputStream.java rename to Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpFISAdapter.java index be014a99..2a54afec 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/ProgressInputStream.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpFISAdapter.java @@ -22,9 +22,9 @@ import java.io.InputStream; /** * Created by lyy on 2017/9/26. - * 具有进度的InputStream + * BufferedRandomAccessFile 转 InputStream 适配器 */ -final class ProgressInputStream extends InputStream { +final class FtpFISAdapter extends InputStream { private BufferedRandomAccessFile mIs; private ProgressCallback mCallback; @@ -34,12 +34,12 @@ final class ProgressInputStream extends InputStream { void onProgressCallback(byte[] buffer, int byteOffset, int byteCount) throws IOException; } - ProgressInputStream(@NonNull BufferedRandomAccessFile is, @NonNull ProgressCallback callback) { + FtpFISAdapter(@NonNull BufferedRandomAccessFile is, @NonNull ProgressCallback callback) { mIs = is; mCallback = callback; } - ProgressInputStream(@NonNull BufferedRandomAccessFile is) { + FtpFISAdapter(@NonNull BufferedRandomAccessFile is) { mIs = is; } 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 8fd33ea7..9920d912 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 @@ -19,15 +19,18 @@ import com.arialyy.aria.core.common.AbsFtpInfoThread; import com.arialyy.aria.core.common.OnFileInfoCallback; import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadTaskEntity; +import com.arialyy.aria.util.CommonUtil; +import java.io.File; +import java.util.Properties; import org.apache.commons.net.ftp.FTPFile; /** * Created by Aria.Lao on 2017/9/26. - * FTP远程服务器文件信息 + * 单任务远程服务器文件信息 */ class FtpFileInfoThread extends AbsFtpInfoThread { - static final int CODE_EXISTS = 0xab1; - private boolean exists = false; + static final int CODE_COMPLETE = 0xab1; + private boolean isComplete = false; FtpFileInfoThread(UploadTaskEntity taskEntity, OnFileInfoCallback callback) { super(taskEntity, callback); @@ -40,16 +43,36 @@ class FtpFileInfoThread extends AbsFtpInfoThread + mEntity.getFileName(); } + /** + * 如果服务器的文件长度和本地上传文件的文件长度一致,则任务任务已完成。 + * 否则重新修改保存的停止位置,这是因为outputStream是读不到服务器是否成功写入的。 + * 而threadTask的保存的停止位置是File的InputStream的,所有就会导致两端停止位置不一致 + * + * @param remotePath ftp服务器文件夹路径 + * @param ftpFile ftp服务器上对应的文件 + */ @Override protected void handleFile(String remotePath, FTPFile ftpFile) { super.handleFile(remotePath, ftpFile); - //远程文件已完成 - if (ftpFile != null && ftpFile.getSize() == mEntity.getFileSize()) { - exists = true; + if (ftpFile != null) { + //远程文件已完成 + if (ftpFile.getSize() == mEntity.getFileSize()) { + isComplete = true; + } else { + File configFile = new File(CommonUtil.getFileConfigPath(false, mEntity.getFileName())); + Properties pro = CommonUtil.loadConfig(configFile); + String key = mEntity.getFileName() + "_record_" + 0; + long oldRecord = Long.parseLong(pro.getProperty(key, "0")); + if (oldRecord != 0) { + //修改本地保存的停止地址为服务器上的真实地址 + pro.setProperty(key, ftpFile.getSize() + ""); + CommonUtil.saveConfig(configFile, pro); + } + } } } @Override protected void onPreComplete(int code) { super.onPreComplete(code); - mCallback.onComplete(mEntity.getKey(), exists ? CODE_EXISTS : code); + mCallback.onComplete(mEntity.getKey(), isComplete ? CODE_COMPLETE : code); } } 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 1bc1777c..ab8af078 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 @@ -25,14 +25,10 @@ import com.arialyy.aria.core.upload.UploadTaskEntity; import com.arialyy.aria.util.BufferedRandomAccessFile; import java.io.File; import java.io.IOException; -import java.io.OutputStream; import java.io.UnsupportedEncodingException; import org.apache.commons.net.ftp.FTPClient; -import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPReply; import org.apache.commons.net.ftp.OnFtpInputStreamListener; -import org.apache.commons.net.io.CopyStreamEvent; -import org.apache.commons.net.io.CopyStreamListener; /** * Created by Aria.Lao on 2017/7/28. @@ -70,8 +66,8 @@ class FtpThreadTask extends AbsFtpThreadTask { client.setRestartOffset(mConfig.START_LOCATION); file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", mBufSize); if (mConfig.START_LOCATION != 0) { - file.skipBytes((int) mConfig.START_LOCATION); - //file.seek(mConfig.START_LOCATION); + //file.skipBytes((int) mConfig.START_LOCATION); + file.seek(mConfig.START_LOCATION); } upload(client, file); if (STATE.isCancel || STATE.isStop) return; @@ -113,27 +109,16 @@ class FtpThreadTask extends AbsFtpThreadTask { private void upload(final FTPClient client, final BufferedRandomAccessFile bis) throws IOException { - //client.storeFile(remotePath, - // new ProgressInputStream(bis, new ProgressInputStream.ProgressCallback() { - // @Override public void onProgressCallback(byte[] buffer, int byteOffset, int byteCount) - // throws IOException { - // if (STATE.isCancel || STATE.isStop) { - // long s = client.abor(); - // Log.d(TAG, "s = " + s); - // client.disconnect(); - // } - // progress(byteCount); - // } - // })); - - try { - client.storeFile(remotePath, new ProgressInputStream(bis), new OnFtpInputStreamListener() { + client.storeFile(remotePath, new FtpFISAdapter(bis), new OnFtpInputStreamListener() { + boolean isStoped = false; + @Override public void onFtpInputStream(FTPClient client, long totalBytesTransferred, int bytesTransferred, long streamSize) { - if (STATE.isCancel || STATE.isStop) { + if ((STATE.isCancel || STATE.isStop) && !isStoped) { try { + isStoped = true; client.abor(); } catch (IOException e) { e.printStackTrace(); @@ -142,40 +127,21 @@ class FtpThreadTask extends AbsFtpThreadTask { progress(bytesTransferred); } }); - } catch (IOException e) { - //e.printStackTrace(); + if (e.getMessage().contains("IOException caught while copying")) { + e.printStackTrace(); + } else { + fail(mChildCurrentLocation, "上传失败", e); + } } int reply = client.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { - client.disconnect(); - fail(mChildCurrentLocation, "上传文件错误,错误码为:" + reply, null); - } - - } - - /** - * 执行上传操作 - */ - private void upload(BufferedRandomAccessFile file, OutputStream os) - throws IOException, InterruptedException { - int len; - byte[] buffer = new byte[mBufSize]; - while ((len = file.read(buffer)) != -1) { - if (STATE.isCancel) break; - if (STATE.isStop) break; - if (mSleepTime > 0) Thread.sleep(mSleepTime); - if (mChildCurrentLocation + len >= mConfig.END_LOCATION) { - len = (int) (mConfig.END_LOCATION - mChildCurrentLocation); - os.write(buffer, 0, len); - progress(len); - break; - } else { - os.write(buffer, 0, len); - progress(len); + if (client.isConnected()) { + client.disconnect(); } - Log.d(TAG, len + ""); + if (reply == FTPReply.TRANSFER_ABORTED) return; + fail(mChildCurrentLocation, "上传文件错误,错误码为:" + reply, null); } } diff --git a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/SimpleUploadUtil.java b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/SimpleUploadUtil.java index 8dc79df3..4c1b45c8 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/SimpleUploadUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/upload/uploader/SimpleUploadUtil.java @@ -49,7 +49,7 @@ public class SimpleUploadUtil implements IUtil, Runnable { mListener.onPre(); new FtpFileInfoThread(mTaskEntity, new OnFileInfoCallback() { @Override public void onComplete(String url, int code) { - if (code == FtpFileInfoThread.CODE_EXISTS) { + if (code == FtpFileInfoThread.CODE_COMPLETE) { mListener.onComplete(); } else { mUploader.start(); 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 8ef19e82..8e1ff443 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 @@ -15,7 +15,6 @@ */ package com.arialyy.aria.core.upload.uploader; -import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.common.AbsFileer; import com.arialyy.aria.core.common.AbsThreadTask; import com.arialyy.aria.core.common.SubThreadConfig; @@ -47,10 +46,7 @@ class Uploader extends AbsFileer { * 5、不支持断点,则是新任务 */ protected void checkTask() { - mConfigFile = new File(mContext.getFilesDir().getPath() - + AriaManager.UPLOAD_TEMP_DIR - + mEntity.getFileName() - + ".properties"); + mConfigFile = new File(CommonUtil.getFileConfigPath(false, mEntity.getFileName())); if (!mTaskEntity.isSupportBP) { isNewTask = true; return; diff --git a/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java b/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java index a64ec3ed..30480ce9 100644 --- a/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java @@ -266,7 +266,7 @@ public class CommonUtil { file.delete(); } } - File config = new File(getFileConfig(false, uEntity.getFileName())); + File config = new File(getFileConfigPath(false, uEntity.getFileName())); if (config.exists()) { config.delete(); } @@ -296,7 +296,7 @@ public class CommonUtil { } } - File config = new File(getFileConfig(true, dEntity.getFileName())); + File config = new File(getFileConfigPath(true, dEntity.getFileName())); if (config.exists()) { config.delete(); } @@ -730,11 +730,11 @@ public class CommonUtil { } /** - * 通过文件名获取下载配置文件 + * 通过文件名获取下载配置文件路径 * * @param fileName 文件名 */ - public static String getFileConfig(boolean isDownload, String fileName) { + public static String getFileConfigPath(boolean isDownload, String fileName) { return AriaManager.APP.getFilesDir().getPath() + (isDownload ? AriaManager.DOWNLOAD_TEMP_DIR : AriaManager.UPLOAD_TEMP_DIR) + fileName + ".properties"; } @@ -765,8 +765,8 @@ public class CommonUtil { private static void renameConfig(boolean isDownload, String oldName, String newName) { if (oldName.equals(newName)) return; - File oldFile = new File(getFileConfig(isDownload, oldName)); - File newFile = new File(getFileConfig(isDownload, oldName)); + File oldFile = new File(getFileConfigPath(isDownload, oldName)); + File newFile = new File(getFileConfigPath(isDownload, oldName)); if (!oldFile.exists()) { createFile(newFile.getPath()); } else { diff --git a/DEV_LOG.md b/DEV_LOG.md index e9c45098..ca6582e3 100644 --- a/DEV_LOG.md +++ b/DEV_LOG.md @@ -1,5 +1,5 @@ ## 开发日志 - + v_3.3.2 新加reTry(),修复上一个版本不会回调失败事件的问题;增加running状态下5秒钟保存一次数据库的功能 + + v_3.3.2 新加reTry(),修复上一个版本不会回调失败事件的问题;增加running状态下5秒钟保存一次数据库的功能;修复FTP断点上传文件不完整的问题 + v_3.3.1 增加网络事件,网络未连接,将不会重试下载,修复删除未开始任务,状态回调错误 + v_3.3.0 增加任务组子任务暂停和开始控制功能、修复5.0系统以上数据库多生成两个字段的bug、去掉addSchedulerListener事件 + v_3.2.26 修复任务组有时注解不起作用的问题 diff --git a/README.md b/README.md index d6851a95..9c3d977d 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,10 @@ Aria项目源于工作中遇到的一个文件下载管理的需求,当时被 Aria有以下特点: + 简单、方便 - 可以在Activity、Service、Fragment、Dialog、popupWindow、Notification等组件中使用 - - 一行代码实现HTTP\FTP断线续传、多任务自动调度 - - 一行代码实现HTTP任务组\FTP文件夹下载 - - 一行代码实现HTTP\FTP断点续传上传 + - 支持HTTP\FTP断点续传、多任务自动调度 + - 支持HTTP任务组\FTP文件夹,断点续传下载 + - 支持HTTP表单上传 + - 支持文件FTP断点续传上传 + 支持https地址下载 - 在配置文件中很容易就可以设置CA证书的信息 + 支持300、301、302重定向下载链接下载 diff --git a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java index 49e9bad1..e1c8de2e 100644 --- a/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java @@ -46,14 +46,14 @@ public class SingleTaskActivity extends BaseActivity { private static final String DOWNLOAD_URL = //"http://kotlinlang.org/docs/kotlin-docs.pdf"; //"https://atom-installer.github.com/v1.13.0/AtomSetup.exe?s=1484074138&ext=.exe"; - "http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk"; + //"http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk"; //"http://sitcac.daxincf.cn/wp-content/uploads/swift_vido/01/element.mp4_1"; //"http://120.25.196.56:8000/filereq?id=15692406294&ipncid=105635&client=android&filename=20170819185541.avi"; //"http://down2.xiaoshuofuwuqi.com/d/file/filetxt/20170608/14/%BA%DA%CE%D7%CA%A6%E1%C8%C6%F0.txt"; //"http://tinghuaapp.oss-cn-shanghai.aliyuncs.com/20170612201739607815"; //"http://static.gaoshouyou.com/d/36/69/2d3699acfa69e9632262442c46516ad8.apk"; //"http://oqcpqqvuf.bkt.clouddn.com/ceshi.txt"; - //"http://down8.androidgame-store.com/201706122321/97967927DD4E53D9905ECAA7874C8128/new/game1/19/45319/com.neuralprisma-2.5.2.174-2000174_1494784835.apk?f=web_1"; + "http://down8.androidgame-store.com/201706122321/97967927DD4E53D9905ECAA7874C8128/new/game1/19/45319/com.neuralprisma-2.5.2.174-2000174_1494784835.apk?f=web_1"; //不支持断点的链接 //"http://ox.konsung.net:5555/ksdc-web/download/downloadFile/?fileName=ksdc_1.0.2.apk&rRange=0-"; //"http://172.18.104.50:8080/download/_302turn"; diff --git a/app/src/main/java/com/arialyy/simple/download/group/FTPDirDownloadActivity.java b/app/src/main/java/com/arialyy/simple/download/group/FTPDirDownloadActivity.java index 864adc59..68cbc028 100644 --- a/app/src/main/java/com/arialyy/simple/download/group/FTPDirDownloadActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/group/FTPDirDownloadActivity.java @@ -35,7 +35,7 @@ import com.arialyy.simple.widget.SubStateLinearLayout; * Created by Aria.Lao on 2017/7/6. */ public class FTPDirDownloadActivity extends BaseActivity { - private static final String dir = "ftp://172.18.104.66:21/haha/"; + private static final String dir = "ftp://172.18.104.49:21/haha/"; @Bind(R.id.child_list) SubStateLinearLayout mChildList; diff --git a/app/src/main/java/com/arialyy/simple/download/multi_download/DownloadAdapter.java b/app/src/main/java/com/arialyy/simple/download/multi_download/DownloadAdapter.java index b88c57e8..aa38b3a0 100644 --- a/app/src/main/java/com/arialyy/simple/download/multi_download/DownloadAdapter.java +++ b/app/src/main/java/com/arialyy/simple/download/multi_download/DownloadAdapter.java @@ -19,6 +19,7 @@ package com.arialyy.simple.download.multi_download; import android.annotation.SuppressLint; import android.content.Context; import android.content.res.Resources; +import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; @@ -182,7 +183,7 @@ public class DownloadAdapter extends AbsRVAdapter { dialog.show(getSupportFragmentManager(), "download_num"); break; case R.id.stop_all: - //Aria.download(this).stopAllTask(); - Aria.download(this).removeAllTask(true); + Aria.download(this).stopAllTask(); + //Aria.download(this).removeAllTask(true); break; case R.id.turn: startActivity(new Intent(this, MultiDownloadActivity.class)); diff --git a/app/src/main/java/com/arialyy/simple/upload/FtpUploadActivity.java b/app/src/main/java/com/arialyy/simple/upload/FtpUploadActivity.java index 54389e0a..4ac0b303 100644 --- a/app/src/main/java/com/arialyy/simple/upload/FtpUploadActivity.java +++ b/app/src/main/java/com/arialyy/simple/upload/FtpUploadActivity.java @@ -34,8 +34,8 @@ import com.arialyy.simple.databinding.ActivityFtpUploadBinding; * Ftp 文件上传demo */ public class FtpUploadActivity extends BaseActivity { - private final String FILE_PATH = "/mnt/sdcard/Download/jd.jpg"; - private final String URL = "ftp://192.168.1.9:21/upload/测试"; + private final String FILE_PATH = "/mnt/sdcard/Download/me.jpg"; + private final String URL = "ftp://172.18.104.49:21/upload/测试"; @Override protected void init(Bundle savedInstanceState) { setTile("FTP 文件上传"); @@ -92,6 +92,7 @@ public class FtpUploadActivity extends BaseActivity { } @Upload.onTaskRunning public void taskRunning(UploadTask task) { + Log.d(TAG, "PP = " + task.getPercent()); getBinding().setProgress(task.getPercent()); getBinding().setSpeed(task.getConvertSpeed()); } diff --git a/build.gradle b/build.gradle index ccce5684..b8c4e13f 100644 --- a/build.gradle +++ b/build.gradle @@ -37,7 +37,8 @@ task clean(type: Delete) { ext { userOrg = 'arialyy' groupId = 'com.arialyy.aria' - publishVersion = '3.3.0' + publishVersion = '3.3.3_dev' +// publishVersion = '1.0.1' //FTP插件 repoName='maven' desc = 'android 下载框架' website = 'https://github.com/AriaLyy/Aria' diff --git a/gradle.properties b/gradle.properties index 85c0e6e3..56fde3f4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,9 +13,9 @@ # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true #Wed Dec 07 20:19:22 CST 2016 -org.gradle.daemon=true -org.gradle.jvmargs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 +#org.gradle.daemon=true +#org.gradle.jvmargs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 # gradle proxy https://chaosleong.github.io/2017/02/10/Configuring-Gradle-Proxy/ -#systemProp.socksProxyHost=127.0.0.1 -#systemProp.socksProxyPort=51110 -#systemprop.socksProxyVersion=5 \ No newline at end of file +systemProp.socksProxyHost=127.0.0.1 +systemProp.socksProxyPort=51110 +systemprop.socksProxyVersion=5 \ No newline at end of file