修复resumeall 导致的进度错乱问题,修复ftp文件上传不完整问题 https://github.com/AriaLyy/Aria/issues/127
This commit is contained in:
@@ -23,8 +23,8 @@ dependencies {
|
|||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
compile 'com.android.support:appcompat-v7:23.1.1'
|
compile 'com.android.support:appcompat-v7:23.1.1'
|
||||||
compile project(':AriaAnnotations')
|
compile project(':AriaAnnotations')
|
||||||
// compile 'com.arialyy.aria:aria-ftp-plug:1.0.0'
|
compile 'com.arialyy.aria:aria-ftp-plug:1.0.1'
|
||||||
compile project(':AriaFtpPlug')
|
// compile project(':AriaFtpPlug')
|
||||||
|
|
||||||
}
|
}
|
||||||
apply from: 'bintray-release.gradle'
|
apply from: 'bintray-release.gradle'
|
||||||
|
@@ -31,7 +31,7 @@ public class TaskManager {
|
|||||||
private static volatile TaskManager INSTANCE = null;
|
private static volatile TaskManager INSTANCE = null;
|
||||||
private Map<String, AbsTask> map = new ConcurrentHashMap<>();
|
private Map<String, AbsTask> map = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public TaskManager getInstance() {
|
public static TaskManager getInstance() {
|
||||||
if (INSTANCE == null) {
|
if (INSTANCE == null) {
|
||||||
synchronized (AriaManager.LOCK) {
|
synchronized (AriaManager.LOCK) {
|
||||||
INSTANCE = new TaskManager();
|
INSTANCE = new TaskManager();
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
package com.arialyy.aria.core.command.normal;
|
package com.arialyy.aria.core.command.normal;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import com.arialyy.aria.core.Aria;
|
|
||||||
import com.arialyy.aria.core.AriaManager;
|
import com.arialyy.aria.core.AriaManager;
|
||||||
import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
|
import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
|
||||||
import com.arialyy.aria.core.download.DownloadTaskEntity;
|
import com.arialyy.aria.core.download.DownloadTaskEntity;
|
||||||
@@ -49,21 +48,25 @@ final class ResumeAllCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T> {
|
|||||||
DbEntity.findDatas(DownloadTaskEntity.class, "isGroupTask=?", "false");
|
DbEntity.findDatas(DownloadTaskEntity.class, "isGroupTask=?", "false");
|
||||||
if (dTaskEntity != null && !dTaskEntity.isEmpty()) {
|
if (dTaskEntity != null && !dTaskEntity.isEmpty()) {
|
||||||
for (DownloadTaskEntity te : dTaskEntity) {
|
for (DownloadTaskEntity te : dTaskEntity) {
|
||||||
|
if (te == null || te.getEntity() == null) continue;
|
||||||
int state = te.getState();
|
int state = te.getState();
|
||||||
if (state == IEntity.STATE_COMPLETE || state == IEntity.STATE_FAIL) continue;
|
if (state == IEntity.STATE_STOP || state == IEntity.STATE_OTHER) {
|
||||||
resumeEntity(te);
|
resumeEntity(te);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<DownloadGroupTaskEntity> groupTask = DbEntity.findAllData(DownloadGroupTaskEntity.class);
|
List<DownloadGroupTaskEntity> groupTask = DbEntity.findAllData(DownloadGroupTaskEntity.class);
|
||||||
if (groupTask != null && !groupTask.isEmpty()) {
|
if (groupTask != null && !groupTask.isEmpty()) {
|
||||||
for (DownloadGroupTaskEntity te : groupTask) {
|
for (DownloadGroupTaskEntity te : groupTask) {
|
||||||
|
if (te == null || te.getEntity() == null) continue;
|
||||||
int state = te.getState();
|
int state = te.getState();
|
||||||
if (state == IEntity.STATE_COMPLETE || state == IEntity.STATE_FAIL) continue;
|
if (state == IEntity.STATE_STOP || state == IEntity.STATE_OTHER) {
|
||||||
resumeEntity(te);
|
resumeEntity(te);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 恢复上传,包括普通任务和任务组
|
* 恢复上传,包括普通任务和任务组
|
||||||
@@ -73,12 +76,14 @@ final class ResumeAllCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T> {
|
|||||||
DbEntity.findDatas(UploadTaskEntity.class, "isGroupTask=?", "false");
|
DbEntity.findDatas(UploadTaskEntity.class, "isGroupTask=?", "false");
|
||||||
if (dTaskEntity != null && !dTaskEntity.isEmpty()) {
|
if (dTaskEntity != null && !dTaskEntity.isEmpty()) {
|
||||||
for (UploadTaskEntity te : dTaskEntity) {
|
for (UploadTaskEntity te : dTaskEntity) {
|
||||||
|
if (te == null || te.getEntity() == null) continue;
|
||||||
int state = te.getState();
|
int state = te.getState();
|
||||||
if (state == IEntity.STATE_COMPLETE || state == IEntity.STATE_FAIL) continue;
|
if (state == IEntity.STATE_STOP || state == IEntity.STATE_OTHER) {
|
||||||
resumeEntity(te);
|
resumeEntity(te);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 恢复实体任务
|
* 恢复实体任务
|
||||||
|
@@ -70,7 +70,6 @@ class StartCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 任务不存在时,根据配置不同,对任务执行操作
|
|
||||||
if (!task.isRunning()) {
|
if (!task.isRunning()) {
|
||||||
startTask();
|
startTask();
|
||||||
}
|
}
|
||||||
|
@@ -96,8 +96,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
|
|||||||
if (mListener instanceof IDownloadListener) {
|
if (mListener instanceof IDownloadListener) {
|
||||||
((IDownloadListener) mListener).onPostPre(mEntity.getFileSize());
|
((IDownloadListener) mListener).onPostPre(mEntity.getFileSize());
|
||||||
}
|
}
|
||||||
mConstance.cleanState();
|
mConstance.resetState();
|
||||||
mConstance.isRunning = true;
|
|
||||||
if (!mTaskEntity.isSupportBP) {
|
if (!mTaskEntity.isSupportBP) {
|
||||||
mThreadNum = 1;
|
mThreadNum = 1;
|
||||||
mConstance.THREAD_NUM = mThreadNum;
|
mConstance.THREAD_NUM = mThreadNum;
|
||||||
@@ -125,7 +124,10 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
|
|||||||
mTimer = new Timer(true);
|
mTimer = new Timer(true);
|
||||||
mTimer.schedule(new TimerTask() {
|
mTimer.schedule(new TimerTask() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
if (mConstance.isComplete() || !mConstance.isRunning) {
|
if (mConstance.isComplete()
|
||||||
|
|| mConstance.isStop()
|
||||||
|
|| mConstance.isCancel()
|
||||||
|
|| !mConstance.isRunning) {
|
||||||
closeTimer();
|
closeTimer();
|
||||||
} else if (mConstance.CURRENT_LOCATION >= 0) {
|
} else if (mConstance.CURRENT_LOCATION >= 0) {
|
||||||
mListener.onProgress(mConstance.CURRENT_LOCATION);
|
mListener.onProgress(mConstance.CURRENT_LOCATION);
|
||||||
@@ -179,9 +181,9 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
|
|||||||
|
|
||||||
@Override public void stop() {
|
@Override public void stop() {
|
||||||
closeTimer();
|
closeTimer();
|
||||||
if (mConstance.isComplete()) return;
|
|
||||||
mConstance.isStop = true;
|
|
||||||
mConstance.isRunning = false;
|
mConstance.isRunning = false;
|
||||||
|
mConstance.isStop = true;
|
||||||
|
if (mConstance.isComplete()) return;
|
||||||
if (mFixedThreadPool != null) {
|
if (mFixedThreadPool != null) {
|
||||||
mFixedThreadPool.shutdown();
|
mFixedThreadPool.shutdown();
|
||||||
}
|
}
|
||||||
@@ -393,5 +395,4 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
|
|||||||
* 选择单任务线程的类型
|
* 选择单任务线程的类型
|
||||||
*/
|
*/
|
||||||
protected abstract AbsThreadTask selectThreadTask(SubThreadConfig<TASK_ENTITY> config);
|
protected abstract AbsThreadTask selectThreadTask(SubThreadConfig<TASK_ENTITY> config);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -23,7 +23,6 @@ import com.arialyy.aria.core.download.DownloadGroupEntity;
|
|||||||
import com.arialyy.aria.core.inf.AbsEntity;
|
import com.arialyy.aria.core.inf.AbsEntity;
|
||||||
import com.arialyy.aria.core.inf.AbsTaskEntity;
|
import com.arialyy.aria.core.inf.AbsTaskEntity;
|
||||||
import com.arialyy.aria.core.upload.UploadEntity;
|
import com.arialyy.aria.core.upload.UploadEntity;
|
||||||
import com.arialyy.aria.util.CommonUtil;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import org.apache.commons.net.ftp.FTP;
|
import org.apache.commons.net.ftp.FTP;
|
||||||
import org.apache.commons.net.ftp.FTPClient;
|
import org.apache.commons.net.ftp.FTPClient;
|
||||||
@@ -37,7 +36,7 @@ import org.apache.commons.net.ftp.FTPReply;
|
|||||||
public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>>
|
public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>>
|
||||||
implements Runnable {
|
implements Runnable {
|
||||||
|
|
||||||
private final String TAG = "HttpFileInfoThread";
|
private final String TAG = "AbsFtpInfoThread";
|
||||||
protected ENTITY mEntity;
|
protected ENTITY mEntity;
|
||||||
protected TASK_ENTITY mTaskEntity;
|
protected TASK_ENTITY mTaskEntity;
|
||||||
private int mConnectTimeOut;
|
private int mConnectTimeOut;
|
||||||
@@ -86,6 +85,9 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
mTaskEntity.code = reply;
|
mTaskEntity.code = reply;
|
||||||
|
if (mSize != 0 && !isUpload) {
|
||||||
|
mEntity.setFileSize(mSize);
|
||||||
|
}
|
||||||
mEntity.update();
|
mEntity.update();
|
||||||
mTaskEntity.update();
|
mTaskEntity.update();
|
||||||
onPreComplete(reply);
|
onPreComplete(reply);
|
||||||
@@ -170,9 +172,9 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
|
|||||||
size += file.getSize();
|
size += file.getSize();
|
||||||
handleFile(path + file.getName(), file);
|
handleFile(path + file.getName(), file);
|
||||||
} else {
|
} else {
|
||||||
size += getFileSize(client.listFiles(
|
String remotePath =
|
||||||
CommonUtil.strCharSetConvert(path + file.getName(), mTaskEntity.charSet)), client,
|
new String((path + file.getName()).getBytes(charSet), AbsFtpThreadTask.SERVER_CHARSET);
|
||||||
path + file.getName());
|
size += getFileSize(client.listFiles(remotePath), client, path + file.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
|
@@ -74,7 +74,7 @@ public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTI
|
|||||||
client.enterLocalPassiveMode();
|
client.enterLocalPassiveMode();
|
||||||
client.setFileType(FTP.BINARY_FILE_TYPE);
|
client.setFileType(FTP.BINARY_FILE_TYPE);
|
||||||
client.setBufferSize(mBufSize);
|
client.setBufferSize(mBufSize);
|
||||||
//client.setControlKeepAliveTimeout(5);
|
client.setControlKeepAliveTimeout(5);
|
||||||
//client.setCopyStreamListener();
|
//client.setCopyStreamListener();
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
@@ -229,7 +229,6 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
|
|||||||
*/
|
*/
|
||||||
protected void writeConfig(boolean isComplete, final long record) throws IOException {
|
protected void writeConfig(boolean isComplete, final long record) throws IOException {
|
||||||
synchronized (AriaManager.LOCK) {
|
synchronized (AriaManager.LOCK) {
|
||||||
Log.d(TAG, "really record == " + record);
|
|
||||||
String key = null, value = null;
|
String key = null, value = null;
|
||||||
if (0 < record && record < mConfig.END_LOCATION) {
|
if (0 < record && record < mConfig.END_LOCATION) {
|
||||||
key = mConfig.TEMP_FILE.getName() + "_record_" + mConfig.THREAD_ID;
|
key = mConfig.TEMP_FILE.getName() + "_record_" + mConfig.THREAD_ID;
|
||||||
|
@@ -35,7 +35,7 @@ public class StateConstance {
|
|||||||
public StateConstance() {
|
public StateConstance() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanState() {
|
public void resetState() {
|
||||||
isCancel = false;
|
isCancel = false;
|
||||||
isStop = false;
|
isStop = false;
|
||||||
isRunning = true;
|
isRunning = true;
|
||||||
|
@@ -17,6 +17,7 @@ package com.arialyy.aria.core.download;
|
|||||||
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.util.Log;
|
||||||
import com.arialyy.aria.core.AriaManager;
|
import com.arialyy.aria.core.AriaManager;
|
||||||
import com.arialyy.aria.core.common.IUtil;
|
import com.arialyy.aria.core.common.IUtil;
|
||||||
import com.arialyy.aria.core.download.downloader.AbsGroupUtil;
|
import com.arialyy.aria.core.download.downloader.AbsGroupUtil;
|
||||||
@@ -56,8 +57,12 @@ public class DownloadGroupTask extends AbsGroupTask<DownloadGroupTaskEntity, Dow
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public void start() {
|
@Override public void start() {
|
||||||
|
if (mUtil.isRunning()) {
|
||||||
|
Log.d(TAG, "任务正在下载");
|
||||||
|
} else {
|
||||||
mUtil.start();
|
mUtil.start();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override public void stop() {
|
@Override public void stop() {
|
||||||
if (!mUtil.isRunning()) {
|
if (!mUtil.isRunning()) {
|
||||||
|
@@ -43,23 +43,15 @@ import java.util.concurrent.Executors;
|
|||||||
public abstract class AbsGroupUtil implements IUtil {
|
public abstract class AbsGroupUtil implements IUtil {
|
||||||
private final String TAG = "AbsGroupUtil";
|
private final String TAG = "AbsGroupUtil";
|
||||||
/**
|
/**
|
||||||
* 任务组所有任务总大小
|
* 任务组所有任务总长度
|
||||||
*/
|
*/
|
||||||
long mTotalSize = 0;
|
long mTotalLen = 0;
|
||||||
long mCurrentLocation = 0;
|
long mCurrentLocation = 0;
|
||||||
private ExecutorService mExePool;
|
private ExecutorService mExePool;
|
||||||
protected IDownloadGroupListener mListener;
|
protected IDownloadGroupListener mListener;
|
||||||
protected DownloadGroupTaskEntity mTaskEntity;
|
protected DownloadGroupTaskEntity mTaskEntity;
|
||||||
private boolean isRunning = false;
|
private boolean isRunning = false;
|
||||||
private Timer mTimer;
|
private Timer mTimer;
|
||||||
/**
|
|
||||||
* 初始化完成的任务书数
|
|
||||||
*/
|
|
||||||
int mInitNum = 0;
|
|
||||||
/**
|
|
||||||
* 初始化失败的任务数
|
|
||||||
*/
|
|
||||||
int mInitFailNum = 0;
|
|
||||||
/**
|
/**
|
||||||
* 保存所有没有下载完成的任务,key为下载地址
|
* 保存所有没有下载完成的任务,key为下载地址
|
||||||
*/
|
*/
|
||||||
@@ -79,18 +71,26 @@ public abstract class AbsGroupUtil implements IUtil {
|
|||||||
* 该任务组对应的所有任务
|
* 该任务组对应的所有任务
|
||||||
*/
|
*/
|
||||||
private Map<String, DownloadTaskEntity> mTasksMap = new HashMap<>();
|
private Map<String, DownloadTaskEntity> mTasksMap = new HashMap<>();
|
||||||
|
/**
|
||||||
|
* 是否需要读取文件长度,{@code true}需要
|
||||||
|
*/
|
||||||
|
boolean isNeedLoadFileSize = true;
|
||||||
//已经完成的任务数
|
//已经完成的任务数
|
||||||
private int mCompleteNum = 0;
|
private int mCompleteNum = 0;
|
||||||
//失败的任务数
|
//失败的任务数
|
||||||
private int mFailNum = 0;
|
private int mFailNum = 0;
|
||||||
//停止的任务数
|
//停止的任务数
|
||||||
private int mStopNum = 0;
|
private int mStopNum = 0;
|
||||||
|
|
||||||
//实际的下载任务数
|
//实际的下载任务数
|
||||||
int mActualTaskNum = 0;
|
int mActualTaskNum = 0;
|
||||||
/**
|
//初始化完成的任务数
|
||||||
* 是否需要读取文件长度,{@code true}需要
|
int mInitNum = 0;
|
||||||
*/
|
// 初始化失败的任务数
|
||||||
boolean isNeedLoadFileSize = true;
|
int mInitFailNum = 0;
|
||||||
|
|
||||||
|
//任务组大小
|
||||||
|
int mGroupSize = 0;
|
||||||
|
|
||||||
AbsGroupUtil(IDownloadGroupListener listener, DownloadGroupTaskEntity taskEntity) {
|
AbsGroupUtil(IDownloadGroupListener listener, DownloadGroupTaskEntity taskEntity) {
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
@@ -105,14 +105,13 @@ public abstract class AbsGroupUtil implements IUtil {
|
|||||||
mTasksMap.put(te.getEntity().getUrl(), te);
|
mTasksMap.put(te.getEntity().getUrl(), te);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mTotalSize = taskEntity.getEntity().getFileSize();
|
mGroupSize = mTaskEntity.entity.getSubTask().size();
|
||||||
isNeedLoadFileSize = mTotalSize <= 1;
|
mTotalLen = taskEntity.getEntity().getFileSize();
|
||||||
|
isNeedLoadFileSize = mTotalLen <= 1;
|
||||||
for (DownloadEntity entity : mTaskEntity.entity.getSubTask()) {
|
for (DownloadEntity entity : mTaskEntity.entity.getSubTask()) {
|
||||||
File file = new File(entity.getDownloadPath());
|
File file = new File(entity.getDownloadPath());
|
||||||
if (entity.getState() == IEntity.STATE_COMPLETE && file.exists()) {
|
if (entity.getState() == IEntity.STATE_COMPLETE && file.exists()) {
|
||||||
mCompleteNum++;
|
mCompleteNum++;
|
||||||
mInitNum++;
|
|
||||||
mStopNum++;
|
|
||||||
mCurrentLocation += entity.getFileSize();
|
mCurrentLocation += entity.getFileSize();
|
||||||
} else {
|
} else {
|
||||||
mExeMap.put(entity.getUrl(), createChildDownloadTask(entity));
|
mExeMap.put(entity.getUrl(), createChildDownloadTask(entity));
|
||||||
@@ -120,7 +119,7 @@ public abstract class AbsGroupUtil implements IUtil {
|
|||||||
mActualTaskNum++;
|
mActualTaskNum++;
|
||||||
}
|
}
|
||||||
if (isNeedLoadFileSize) {
|
if (isNeedLoadFileSize) {
|
||||||
mTotalSize += entity.getFileSize();
|
mTotalLen += entity.getFileSize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateFileSize();
|
updateFileSize();
|
||||||
@@ -128,7 +127,7 @@ public abstract class AbsGroupUtil implements IUtil {
|
|||||||
|
|
||||||
void updateFileSize() {
|
void updateFileSize() {
|
||||||
if (isNeedLoadFileSize) {
|
if (isNeedLoadFileSize) {
|
||||||
mTaskEntity.getEntity().setFileSize(mTotalSize);
|
mTaskEntity.getEntity().setFileSize(mTotalLen);
|
||||||
mTaskEntity.getEntity().update();
|
mTaskEntity.getEntity().update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -212,7 +211,7 @@ public abstract class AbsGroupUtil implements IUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public long getFileSize() {
|
@Override public long getFileSize() {
|
||||||
return mTotalSize;
|
return mTotalLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public long getCurrentLocation() {
|
@Override public long getCurrentLocation() {
|
||||||
@@ -272,7 +271,6 @@ public abstract class AbsGroupUtil implements IUtil {
|
|||||||
|
|
||||||
@Override public void stop() {
|
@Override public void stop() {
|
||||||
closeTimer(false);
|
closeTimer(false);
|
||||||
mListener.onStop(mCurrentLocation);
|
|
||||||
onStop();
|
onStop();
|
||||||
if (!mExePool.isShutdown()) {
|
if (!mExePool.isShutdown()) {
|
||||||
mExePool.shutdown();
|
mExePool.shutdown();
|
||||||
@@ -325,7 +323,7 @@ public abstract class AbsGroupUtil implements IUtil {
|
|||||||
*/
|
*/
|
||||||
void startRunningFlow() {
|
void startRunningFlow() {
|
||||||
closeTimer(true);
|
closeTimer(true);
|
||||||
mListener.onPostPre(mTotalSize);
|
mListener.onPostPre(mTotalLen);
|
||||||
mListener.onStart(mCurrentLocation);
|
mListener.onStart(mCurrentLocation);
|
||||||
startTimer();
|
startTimer();
|
||||||
}
|
}
|
||||||
@@ -413,8 +411,8 @@ public abstract class AbsGroupUtil implements IUtil {
|
|||||||
ChildDownloadListener(DownloadTaskEntity entity) {
|
ChildDownloadListener(DownloadTaskEntity entity) {
|
||||||
this.taskEntity = entity;
|
this.taskEntity = entity;
|
||||||
this.entity = taskEntity.getEntity();
|
this.entity = taskEntity.getEntity();
|
||||||
lastLen = this.entity.getCurrentProgress();
|
|
||||||
this.entity.setFailNum(0);
|
this.entity.setFailNum(0);
|
||||||
|
lastLen = this.entity.getCurrentProgress();
|
||||||
mLastSaveTime = System.currentTimeMillis();
|
mLastSaveTime = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,12 +456,14 @@ public abstract class AbsGroupUtil implements IUtil {
|
|||||||
saveData(IEntity.STATE_STOP, stopLocation);
|
saveData(IEntity.STATE_STOP, stopLocation);
|
||||||
handleSpeed(0);
|
handleSpeed(0);
|
||||||
mListener.onSubStop(entity);
|
mListener.onSubStop(entity);
|
||||||
|
synchronized (AbsGroupUtil.class) {
|
||||||
mStopNum++;
|
mStopNum++;
|
||||||
if (mStopNum + mCompleteNum >= mInitNum) {
|
if (mStopNum + mCompleteNum + mInitFailNum + mFailNum >= mGroupSize) {
|
||||||
closeTimer(false);
|
closeTimer(false);
|
||||||
mListener.onStop(mCurrentLocation);
|
mListener.onStop(mCurrentLocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override public void onCancel() {
|
@Override public void onCancel() {
|
||||||
saveData(IEntity.STATE_CANCEL, -1);
|
saveData(IEntity.STATE_CANCEL, -1);
|
||||||
@@ -473,16 +473,19 @@ public abstract class AbsGroupUtil implements IUtil {
|
|||||||
|
|
||||||
@Override public void onComplete() {
|
@Override public void onComplete() {
|
||||||
saveData(IEntity.STATE_COMPLETE, entity.getFileSize());
|
saveData(IEntity.STATE_COMPLETE, entity.getFileSize());
|
||||||
mCompleteNum++;
|
|
||||||
handleSpeed(0);
|
handleSpeed(0);
|
||||||
mListener.onSubComplete(entity);
|
mListener.onSubComplete(entity);
|
||||||
|
synchronized (AbsGroupUtil.class) {
|
||||||
|
mCompleteNum++;
|
||||||
//如果子任务完成的数量和总任务数一致,表示任务组任务已经完成
|
//如果子任务完成的数量和总任务数一致,表示任务组任务已经完成
|
||||||
if (mCompleteNum >= mTaskEntity.getEntity().getSubTask().size()) {
|
if (mCompleteNum >= mGroupSize) {
|
||||||
closeTimer(false);
|
closeTimer(false);
|
||||||
mListener.onComplete();
|
mListener.onComplete();
|
||||||
} else if (mCompleteNum + mFailNum >= mActualTaskNum) {
|
} else if (mStopNum + mCompleteNum + mInitFailNum + mFailNum >= mGroupSize) {
|
||||||
//如果子任务完成数量加上失败的数量和总任务数一致,则任务组停止下载
|
//如果子任务完成数量加上失败的数量和总任务数一致,则任务组停止下载
|
||||||
closeTimer(false);
|
closeTimer(false);
|
||||||
|
mListener.onStop(mCurrentLocation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -74,7 +74,7 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i != 0 && i == mExeMap.size()) startRunningFlow();
|
if (i != 0 && i == mExeMap.size()) startRunningFlow();
|
||||||
if (mCurrentLocation == mTotalSize) {
|
if (mCurrentLocation == mTotalLen) {
|
||||||
mListener.onComplete();
|
mListener.onComplete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
|
|||||||
DownloadTaskEntity te = mExeMap.get(url);
|
DownloadTaskEntity te = mExeMap.get(url);
|
||||||
if (te != null) {
|
if (te != null) {
|
||||||
if (isNeedLoadFileSize) {
|
if (isNeedLoadFileSize) {
|
||||||
mTotalSize += te.getEntity().getFileSize();
|
mTotalLen += te.getEntity().getFileSize();
|
||||||
}
|
}
|
||||||
createChildDownload(te);
|
createChildDownload(te);
|
||||||
}
|
}
|
||||||
|
@@ -16,7 +16,6 @@
|
|||||||
package com.arialyy.aria.core.download.downloader;
|
package com.arialyy.aria.core.download.downloader;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import com.arialyy.aria.core.AriaManager;
|
|
||||||
import com.arialyy.aria.core.common.AbsFileer;
|
import com.arialyy.aria.core.common.AbsFileer;
|
||||||
import com.arialyy.aria.core.common.AbsThreadTask;
|
import com.arialyy.aria.core.common.AbsThreadTask;
|
||||||
import com.arialyy.aria.core.common.SubThreadConfig;
|
import com.arialyy.aria.core.common.SubThreadConfig;
|
||||||
@@ -43,10 +42,7 @@ class Downloader extends AbsFileer<DownloadEntity, DownloadTaskEntity> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override protected void checkTask() {
|
@Override protected void checkTask() {
|
||||||
mConfigFile = new File(mContext.getFilesDir().getPath()
|
mConfigFile = new File(CommonUtil.getFileConfigPath(true, mEntity.getFileName()));
|
||||||
+ AriaManager.DOWNLOAD_TEMP_DIR
|
|
||||||
+ mEntity.getFileName()
|
|
||||||
+ ".properties");
|
|
||||||
mTempFile = new File(mEntity.getDownloadPath());
|
mTempFile = new File(mEntity.getDownloadPath());
|
||||||
if (!mTaskEntity.isSupportBP) {
|
if (!mTaskEntity.isSupportBP) {
|
||||||
isNewTask = true;
|
isNewTask = true;
|
||||||
|
@@ -43,6 +43,8 @@ public class FtpDirDownloadUtil extends AbsGroupUtil {
|
|||||||
mExeMap.put(entity.getUrl(), createChildDownloadTask(entity));
|
mExeMap.put(entity.getUrl(), createChildDownloadTask(entity));
|
||||||
}
|
}
|
||||||
mActualTaskNum = mTaskEntity.entity.getSubTask().size();
|
mActualTaskNum = mTaskEntity.entity.getSubTask().size();
|
||||||
|
mGroupSize = mActualTaskNum;
|
||||||
|
mTotalLen = mTaskEntity.entity.getFileSize();
|
||||||
startDownload();
|
startDownload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,9 +32,7 @@ class FtpFileInfoThread extends AbsFtpInfoThread<DownloadEntity, DownloadTaskEnt
|
|||||||
|
|
||||||
@Override protected String setRemotePath() {
|
@Override protected String setRemotePath() {
|
||||||
String url = mEntity.getUrl();
|
String url = mEntity.getUrl();
|
||||||
return url.substring(url.indexOf(mPort) + mPort.length(), url.length())
|
return url.substring(url.indexOf(mPort) + mPort.length(), url.length());
|
||||||
+ "/"
|
|
||||||
+ mEntity.getFileName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override protected void onPreComplete(int code) {
|
@Override protected void onPreComplete(int code) {
|
||||||
@@ -43,5 +41,6 @@ class FtpFileInfoThread extends AbsFtpInfoThread<DownloadEntity, DownloadTaskEnt
|
|||||||
mTaskEntity.isNewTask = true;
|
mTaskEntity.isNewTask = true;
|
||||||
}
|
}
|
||||||
mEntity.setFileSize(mSize);
|
mEntity.setFileSize(mSize);
|
||||||
|
mCallback.onComplete(mEntity.getUrl(), code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -20,9 +20,7 @@ import android.text.TextUtils;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import com.arialyy.aria.core.AriaManager;
|
import com.arialyy.aria.core.AriaManager;
|
||||||
import com.arialyy.aria.core.inf.AbsTask;
|
import com.arialyy.aria.core.inf.AbsTask;
|
||||||
import com.arialyy.aria.core.inf.ITask;
|
|
||||||
import com.arialyy.aria.util.CommonUtil;
|
import com.arialyy.aria.util.CommonUtil;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@@ -185,8 +183,11 @@ public class BaseExecutePool<TASK extends AbsTask> implements IPool<TASK> {
|
|||||||
}
|
}
|
||||||
String convertKey = CommonUtil.keyToHashKey(key);
|
String convertKey = CommonUtil.keyToHashKey(key);
|
||||||
TASK task = mExecuteMap.get(convertKey);
|
TASK task = mExecuteMap.get(convertKey);
|
||||||
|
if (mExecuteQueue.remove(task)) {
|
||||||
mExecuteMap.remove(convertKey);
|
mExecuteMap.remove(convertKey);
|
||||||
return mExecuteQueue.remove(task);
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,7 +19,6 @@ import android.os.CountDownTimer;
|
|||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import com.arialyy.aria.core.AriaManager;
|
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.download.DownloadTask;
|
||||||
import com.arialyy.aria.core.inf.AbsEntity;
|
import com.arialyy.aria.core.inf.AbsEntity;
|
||||||
import com.arialyy.aria.core.inf.AbsNormalEntity;
|
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.inf.IEntity;
|
||||||
import com.arialyy.aria.core.queue.ITaskQueue;
|
import com.arialyy.aria.core.queue.ITaskQueue;
|
||||||
import com.arialyy.aria.core.upload.UploadTask;
|
import com.arialyy.aria.core.upload.UploadTask;
|
||||||
import com.arialyy.aria.util.NetUtils;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@@ -47,7 +47,7 @@ public class FtpUploadTarget
|
|||||||
mEntity.setFileSize(file.length());
|
mEntity.setFileSize(file.length());
|
||||||
|
|
||||||
//暂时不支持断点续传上传
|
//暂时不支持断点续传上传
|
||||||
mTaskEntity.isSupportBP = false;
|
//mTaskEntity.isSupportBP = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -22,9 +22,9 @@ import java.io.InputStream;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by lyy on 2017/9/26.
|
* Created by lyy on 2017/9/26.
|
||||||
* 具有进度的InputStream
|
* BufferedRandomAccessFile 转 InputStream 适配器
|
||||||
*/
|
*/
|
||||||
final class ProgressInputStream extends InputStream {
|
final class FtpFISAdapter extends InputStream {
|
||||||
|
|
||||||
private BufferedRandomAccessFile mIs;
|
private BufferedRandomAccessFile mIs;
|
||||||
private ProgressCallback mCallback;
|
private ProgressCallback mCallback;
|
||||||
@@ -34,12 +34,12 @@ final class ProgressInputStream extends InputStream {
|
|||||||
void onProgressCallback(byte[] buffer, int byteOffset, int byteCount) throws IOException;
|
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;
|
mIs = is;
|
||||||
mCallback = callback;
|
mCallback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgressInputStream(@NonNull BufferedRandomAccessFile is) {
|
FtpFISAdapter(@NonNull BufferedRandomAccessFile is) {
|
||||||
mIs = is;
|
mIs = is;
|
||||||
}
|
}
|
||||||
|
|
@@ -19,15 +19,18 @@ import com.arialyy.aria.core.common.AbsFtpInfoThread;
|
|||||||
import com.arialyy.aria.core.common.OnFileInfoCallback;
|
import com.arialyy.aria.core.common.OnFileInfoCallback;
|
||||||
import com.arialyy.aria.core.upload.UploadEntity;
|
import com.arialyy.aria.core.upload.UploadEntity;
|
||||||
import com.arialyy.aria.core.upload.UploadTaskEntity;
|
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;
|
import org.apache.commons.net.ftp.FTPFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Aria.Lao on 2017/9/26.
|
* Created by Aria.Lao on 2017/9/26.
|
||||||
* FTP远程服务器文件信息
|
* 单任务远程服务器文件信息
|
||||||
*/
|
*/
|
||||||
class FtpFileInfoThread extends AbsFtpInfoThread<UploadEntity, UploadTaskEntity> {
|
class FtpFileInfoThread extends AbsFtpInfoThread<UploadEntity, UploadTaskEntity> {
|
||||||
static final int CODE_EXISTS = 0xab1;
|
static final int CODE_COMPLETE = 0xab1;
|
||||||
private boolean exists = false;
|
private boolean isComplete = false;
|
||||||
|
|
||||||
FtpFileInfoThread(UploadTaskEntity taskEntity, OnFileInfoCallback callback) {
|
FtpFileInfoThread(UploadTaskEntity taskEntity, OnFileInfoCallback callback) {
|
||||||
super(taskEntity, callback);
|
super(taskEntity, callback);
|
||||||
@@ -40,16 +43,36 @@ class FtpFileInfoThread extends AbsFtpInfoThread<UploadEntity, UploadTaskEntity>
|
|||||||
+ mEntity.getFileName();
|
+ mEntity.getFileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果服务器的文件长度和本地上传文件的文件长度一致,则任务任务已完成。
|
||||||
|
* 否则重新修改保存的停止位置,这是因为outputStream是读不到服务器是否成功写入的。
|
||||||
|
* 而threadTask的保存的停止位置是File的InputStream的,所有就会导致两端停止位置不一致
|
||||||
|
*
|
||||||
|
* @param remotePath ftp服务器文件夹路径
|
||||||
|
* @param ftpFile ftp服务器上对应的文件
|
||||||
|
*/
|
||||||
@Override protected void handleFile(String remotePath, FTPFile ftpFile) {
|
@Override protected void handleFile(String remotePath, FTPFile ftpFile) {
|
||||||
super.handleFile(remotePath, ftpFile);
|
super.handleFile(remotePath, ftpFile);
|
||||||
|
if (ftpFile != null) {
|
||||||
//远程文件已完成
|
//远程文件已完成
|
||||||
if (ftpFile != null && ftpFile.getSize() == mEntity.getFileSize()) {
|
if (ftpFile.getSize() == mEntity.getFileSize()) {
|
||||||
exists = true;
|
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) {
|
@Override protected void onPreComplete(int code) {
|
||||||
super.onPreComplete(code);
|
super.onPreComplete(code);
|
||||||
mCallback.onComplete(mEntity.getKey(), exists ? CODE_EXISTS : code);
|
mCallback.onComplete(mEntity.getKey(), isComplete ? CODE_COMPLETE : code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -25,14 +25,10 @@ import com.arialyy.aria.core.upload.UploadTaskEntity;
|
|||||||
import com.arialyy.aria.util.BufferedRandomAccessFile;
|
import com.arialyy.aria.util.BufferedRandomAccessFile;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import org.apache.commons.net.ftp.FTPClient;
|
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.FTPReply;
|
||||||
import org.apache.commons.net.ftp.OnFtpInputStreamListener;
|
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.
|
* Created by Aria.Lao on 2017/7/28.
|
||||||
@@ -70,8 +66,8 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
|
|||||||
client.setRestartOffset(mConfig.START_LOCATION);
|
client.setRestartOffset(mConfig.START_LOCATION);
|
||||||
file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", mBufSize);
|
file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", mBufSize);
|
||||||
if (mConfig.START_LOCATION != 0) {
|
if (mConfig.START_LOCATION != 0) {
|
||||||
file.skipBytes((int) mConfig.START_LOCATION);
|
//file.skipBytes((int) mConfig.START_LOCATION);
|
||||||
//file.seek(mConfig.START_LOCATION);
|
file.seek(mConfig.START_LOCATION);
|
||||||
}
|
}
|
||||||
upload(client, file);
|
upload(client, file);
|
||||||
if (STATE.isCancel || STATE.isStop) return;
|
if (STATE.isCancel || STATE.isStop) return;
|
||||||
@@ -113,27 +109,16 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
|
|||||||
|
|
||||||
private void upload(final FTPClient client, final BufferedRandomAccessFile bis)
|
private void upload(final FTPClient client, final BufferedRandomAccessFile bis)
|
||||||
throws IOException {
|
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 {
|
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,
|
@Override public void onFtpInputStream(FTPClient client, long totalBytesTransferred,
|
||||||
int bytesTransferred, long streamSize) {
|
int bytesTransferred, long streamSize) {
|
||||||
if (STATE.isCancel || STATE.isStop) {
|
if ((STATE.isCancel || STATE.isStop) && !isStoped) {
|
||||||
try {
|
try {
|
||||||
|
isStoped = true;
|
||||||
client.abor();
|
client.abor();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -142,41 +127,22 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
|
|||||||
progress(bytesTransferred);
|
progress(bytesTransferred);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
//e.printStackTrace();
|
if (e.getMessage().contains("IOException caught while copying")) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} else {
|
||||||
|
fail(mChildCurrentLocation, "上传失败", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int reply = client.getReplyCode();
|
int reply = client.getReplyCode();
|
||||||
if (!FTPReply.isPositiveCompletion(reply)) {
|
if (!FTPReply.isPositiveCompletion(reply)) {
|
||||||
|
if (client.isConnected()) {
|
||||||
client.disconnect();
|
client.disconnect();
|
||||||
|
}
|
||||||
|
if (reply == FTPReply.TRANSFER_ABORTED) return;
|
||||||
fail(mChildCurrentLocation, "上传文件错误,错误码为:" + reply, null);
|
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);
|
|
||||||
}
|
|
||||||
Log.d(TAG, len + "");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override protected String getTaskType() {
|
@Override protected String getTaskType() {
|
||||||
|
@@ -49,7 +49,7 @@ public class SimpleUploadUtil implements IUtil, Runnable {
|
|||||||
mListener.onPre();
|
mListener.onPre();
|
||||||
new FtpFileInfoThread(mTaskEntity, new OnFileInfoCallback() {
|
new FtpFileInfoThread(mTaskEntity, new OnFileInfoCallback() {
|
||||||
@Override public void onComplete(String url, int code) {
|
@Override public void onComplete(String url, int code) {
|
||||||
if (code == FtpFileInfoThread.CODE_EXISTS) {
|
if (code == FtpFileInfoThread.CODE_COMPLETE) {
|
||||||
mListener.onComplete();
|
mListener.onComplete();
|
||||||
} else {
|
} else {
|
||||||
mUploader.start();
|
mUploader.start();
|
||||||
|
@@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.arialyy.aria.core.upload.uploader;
|
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.AbsFileer;
|
||||||
import com.arialyy.aria.core.common.AbsThreadTask;
|
import com.arialyy.aria.core.common.AbsThreadTask;
|
||||||
import com.arialyy.aria.core.common.SubThreadConfig;
|
import com.arialyy.aria.core.common.SubThreadConfig;
|
||||||
@@ -47,10 +46,7 @@ class Uploader extends AbsFileer<UploadEntity, UploadTaskEntity> {
|
|||||||
* 5、不支持断点,则是新任务
|
* 5、不支持断点,则是新任务
|
||||||
*/
|
*/
|
||||||
protected void checkTask() {
|
protected void checkTask() {
|
||||||
mConfigFile = new File(mContext.getFilesDir().getPath()
|
mConfigFile = new File(CommonUtil.getFileConfigPath(false, mEntity.getFileName()));
|
||||||
+ AriaManager.UPLOAD_TEMP_DIR
|
|
||||||
+ mEntity.getFileName()
|
|
||||||
+ ".properties");
|
|
||||||
if (!mTaskEntity.isSupportBP) {
|
if (!mTaskEntity.isSupportBP) {
|
||||||
isNewTask = true;
|
isNewTask = true;
|
||||||
return;
|
return;
|
||||||
|
@@ -266,7 +266,7 @@ public class CommonUtil {
|
|||||||
file.delete();
|
file.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File config = new File(getFileConfig(false, uEntity.getFileName()));
|
File config = new File(getFileConfigPath(false, uEntity.getFileName()));
|
||||||
if (config.exists()) {
|
if (config.exists()) {
|
||||||
config.delete();
|
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()) {
|
if (config.exists()) {
|
||||||
config.delete();
|
config.delete();
|
||||||
}
|
}
|
||||||
@@ -730,11 +730,11 @@ public class CommonUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过文件名获取下载配置文件
|
* 通过文件名获取下载配置文件路径
|
||||||
*
|
*
|
||||||
* @param fileName 文件名
|
* @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
|
return AriaManager.APP.getFilesDir().getPath() + (isDownload ? AriaManager.DOWNLOAD_TEMP_DIR
|
||||||
: AriaManager.UPLOAD_TEMP_DIR) + fileName + ".properties";
|
: AriaManager.UPLOAD_TEMP_DIR) + fileName + ".properties";
|
||||||
}
|
}
|
||||||
@@ -765,8 +765,8 @@ public class CommonUtil {
|
|||||||
|
|
||||||
private static void renameConfig(boolean isDownload, String oldName, String newName) {
|
private static void renameConfig(boolean isDownload, String oldName, String newName) {
|
||||||
if (oldName.equals(newName)) return;
|
if (oldName.equals(newName)) return;
|
||||||
File oldFile = new File(getFileConfig(isDownload, oldName));
|
File oldFile = new File(getFileConfigPath(isDownload, oldName));
|
||||||
File newFile = new File(getFileConfig(isDownload, oldName));
|
File newFile = new File(getFileConfigPath(isDownload, oldName));
|
||||||
if (!oldFile.exists()) {
|
if (!oldFile.exists()) {
|
||||||
createFile(newFile.getPath());
|
createFile(newFile.getPath());
|
||||||
} else {
|
} else {
|
||||||
|
@@ -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.1 增加网络事件,网络未连接,将不会重试下载,修复删除未开始任务,状态回调错误
|
||||||
+ v_3.3.0 增加任务组子任务暂停和开始控制功能、修复5.0系统以上数据库多生成两个字段的bug、去掉addSchedulerListener事件
|
+ v_3.3.0 增加任务组子任务暂停和开始控制功能、修复5.0系统以上数据库多生成两个字段的bug、去掉addSchedulerListener事件
|
||||||
+ v_3.2.26 修复任务组有时注解不起作用的问题
|
+ v_3.2.26 修复任务组有时注解不起作用的问题
|
||||||
|
@@ -6,9 +6,10 @@ Aria项目源于工作中遇到的一个文件下载管理的需求,当时被
|
|||||||
Aria有以下特点:
|
Aria有以下特点:
|
||||||
+ 简单、方便
|
+ 简单、方便
|
||||||
- 可以在Activity、Service、Fragment、Dialog、popupWindow、Notification等组件中使用
|
- 可以在Activity、Service、Fragment、Dialog、popupWindow、Notification等组件中使用
|
||||||
- 一行代码实现HTTP\FTP断线续传、多任务自动调度
|
- 支持HTTP\FTP断点续传、多任务自动调度
|
||||||
- 一行代码实现HTTP任务组\FTP文件夹下载
|
- 支持HTTP任务组\FTP文件夹,断点续传下载
|
||||||
- 一行代码实现HTTP\FTP断点续传上传
|
- 支持HTTP表单上传
|
||||||
|
- 支持文件FTP断点续传上传
|
||||||
+ 支持https地址下载
|
+ 支持https地址下载
|
||||||
- 在配置文件中很容易就可以设置CA证书的信息
|
- 在配置文件中很容易就可以设置CA证书的信息
|
||||||
+ 支持300、301、302重定向下载链接下载
|
+ 支持300、301、302重定向下载链接下载
|
||||||
|
@@ -46,14 +46,14 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
|
|||||||
private static final String DOWNLOAD_URL =
|
private static final String DOWNLOAD_URL =
|
||||||
//"http://kotlinlang.org/docs/kotlin-docs.pdf";
|
//"http://kotlinlang.org/docs/kotlin-docs.pdf";
|
||||||
//"https://atom-installer.github.com/v1.13.0/AtomSetup.exe?s=1484074138&ext=.exe";
|
//"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://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://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://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://tinghuaapp.oss-cn-shanghai.aliyuncs.com/20170612201739607815";
|
||||||
//"http://static.gaoshouyou.com/d/36/69/2d3699acfa69e9632262442c46516ad8.apk";
|
//"http://static.gaoshouyou.com/d/36/69/2d3699acfa69e9632262442c46516ad8.apk";
|
||||||
//"http://oqcpqqvuf.bkt.clouddn.com/ceshi.txt";
|
//"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://ox.konsung.net:5555/ksdc-web/download/downloadFile/?fileName=ksdc_1.0.2.apk&rRange=0-";
|
||||||
//"http://172.18.104.50:8080/download/_302turn";
|
//"http://172.18.104.50:8080/download/_302turn";
|
||||||
|
@@ -35,7 +35,7 @@ import com.arialyy.simple.widget.SubStateLinearLayout;
|
|||||||
* Created by Aria.Lao on 2017/7/6.
|
* Created by Aria.Lao on 2017/7/6.
|
||||||
*/
|
*/
|
||||||
public class FTPDirDownloadActivity extends BaseActivity<ActivityDownloadGroupBinding> {
|
public class FTPDirDownloadActivity extends BaseActivity<ActivityDownloadGroupBinding> {
|
||||||
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;
|
@Bind(R.id.child_list) SubStateLinearLayout mChildList;
|
||||||
|
|
||||||
|
@@ -19,6 +19,7 @@ package com.arialyy.simple.download.multi_download;
|
|||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@@ -182,7 +183,7 @@ public class DownloadAdapter extends AbsRVAdapter<AbsEntity, DownloadAdapter.Sim
|
|||||||
color = android.R.color.holo_red_light;
|
color = android.R.color.holo_red_light;
|
||||||
break;
|
break;
|
||||||
case IEntity.STATE_COMPLETE:
|
case IEntity.STATE_COMPLETE:
|
||||||
str = "重新开始?";
|
str = "完成";
|
||||||
holder.progress.setProgress(100);
|
holder.progress.setProgress(100);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -206,9 +207,9 @@ public class DownloadAdapter extends AbsRVAdapter<AbsEntity, DownloadAdapter.Sim
|
|||||||
mData.remove(entity);
|
mData.remove(entity);
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
if (isSimpleDownload(entity)) {
|
if (isSimpleDownload(entity)) {
|
||||||
Aria.download(getContext()).load((DownloadEntity) entity).cancel();
|
Aria.download(getContext()).load((DownloadEntity) entity).cancel(true);
|
||||||
} else {
|
} else {
|
||||||
Aria.download(getContext()).load((DownloadGroupEntity) entity).cancel();
|
Aria.download(getContext()).load((DownloadGroupEntity) entity).cancel(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -254,7 +255,6 @@ public class DownloadAdapter extends AbsRVAdapter<AbsEntity, DownloadAdapter.Sim
|
|||||||
case IEntity.STATE_OTHER:
|
case IEntity.STATE_OTHER:
|
||||||
case IEntity.STATE_FAIL:
|
case IEntity.STATE_FAIL:
|
||||||
case IEntity.STATE_STOP:
|
case IEntity.STATE_STOP:
|
||||||
case IEntity.STATE_COMPLETE:
|
|
||||||
case IEntity.STATE_PRE:
|
case IEntity.STATE_PRE:
|
||||||
case IEntity.STATE_POST_PRE:
|
case IEntity.STATE_POST_PRE:
|
||||||
start(entity);
|
start(entity);
|
||||||
@@ -262,6 +262,9 @@ public class DownloadAdapter extends AbsRVAdapter<AbsEntity, DownloadAdapter.Sim
|
|||||||
case IEntity.STATE_RUNNING:
|
case IEntity.STATE_RUNNING:
|
||||||
stop(entity);
|
stop(entity);
|
||||||
break;
|
break;
|
||||||
|
case IEntity.STATE_COMPLETE:
|
||||||
|
Log.d(TAG, "任务已完成");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -66,8 +66,8 @@ public class MultiTaskActivity extends BaseActivity<ActivityMultiBinding> {
|
|||||||
dialog.show(getSupportFragmentManager(), "download_num");
|
dialog.show(getSupportFragmentManager(), "download_num");
|
||||||
break;
|
break;
|
||||||
case R.id.stop_all:
|
case R.id.stop_all:
|
||||||
//Aria.download(this).stopAllTask();
|
Aria.download(this).stopAllTask();
|
||||||
Aria.download(this).removeAllTask(true);
|
//Aria.download(this).removeAllTask(true);
|
||||||
break;
|
break;
|
||||||
case R.id.turn:
|
case R.id.turn:
|
||||||
startActivity(new Intent(this, MultiDownloadActivity.class));
|
startActivity(new Intent(this, MultiDownloadActivity.class));
|
||||||
|
@@ -34,8 +34,8 @@ import com.arialyy.simple.databinding.ActivityFtpUploadBinding;
|
|||||||
* Ftp 文件上传demo
|
* Ftp 文件上传demo
|
||||||
*/
|
*/
|
||||||
public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
|
public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
|
||||||
private final String FILE_PATH = "/mnt/sdcard/Download/jd.jpg";
|
private final String FILE_PATH = "/mnt/sdcard/Download/me.jpg";
|
||||||
private final String URL = "ftp://192.168.1.9:21/upload/测试";
|
private final String URL = "ftp://172.18.104.49:21/upload/测试";
|
||||||
|
|
||||||
@Override protected void init(Bundle savedInstanceState) {
|
@Override protected void init(Bundle savedInstanceState) {
|
||||||
setTile("FTP 文件上传");
|
setTile("FTP 文件上传");
|
||||||
@@ -92,6 +92,7 @@ public class FtpUploadActivity extends BaseActivity<ActivityFtpUploadBinding> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Upload.onTaskRunning public void taskRunning(UploadTask task) {
|
@Upload.onTaskRunning public void taskRunning(UploadTask task) {
|
||||||
|
Log.d(TAG, "PP = " + task.getPercent());
|
||||||
getBinding().setProgress(task.getPercent());
|
getBinding().setProgress(task.getPercent());
|
||||||
getBinding().setSpeed(task.getConvertSpeed());
|
getBinding().setSpeed(task.getConvertSpeed());
|
||||||
}
|
}
|
||||||
|
@@ -37,7 +37,8 @@ task clean(type: Delete) {
|
|||||||
ext {
|
ext {
|
||||||
userOrg = 'arialyy'
|
userOrg = 'arialyy'
|
||||||
groupId = 'com.arialyy.aria'
|
groupId = 'com.arialyy.aria'
|
||||||
publishVersion = '3.3.0'
|
publishVersion = '3.3.3_dev'
|
||||||
|
// publishVersion = '1.0.1' //FTP插件
|
||||||
repoName='maven'
|
repoName='maven'
|
||||||
desc = 'android 下载框架'
|
desc = 'android 下载框架'
|
||||||
website = 'https://github.com/AriaLyy/Aria'
|
website = 'https://github.com/AriaLyy/Aria'
|
||||||
|
@@ -13,9 +13,9 @@
|
|||||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
# org.gradle.parallel=true
|
# org.gradle.parallel=true
|
||||||
#Wed Dec 07 20:19:22 CST 2016
|
#Wed Dec 07 20:19:22 CST 2016
|
||||||
org.gradle.daemon=true
|
#org.gradle.daemon=true
|
||||||
org.gradle.jvmargs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
|
#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/
|
# gradle proxy https://chaosleong.github.io/2017/02/10/Configuring-Gradle-Proxy/
|
||||||
#systemProp.socksProxyHost=127.0.0.1
|
systemProp.socksProxyHost=127.0.0.1
|
||||||
#systemProp.socksProxyPort=51110
|
systemProp.socksProxyPort=51110
|
||||||
#systemprop.socksProxyVersion=5
|
systemprop.socksProxyVersion=5
|
Reference in New Issue
Block a user