ftp下载获取dns的ip列表时添加超时限制,修复端口不存在导致的崩溃问题,https://github.com/AriaLyy/Aria/issues/251

ä修复https://github.com/AriaLyy/Aria/issues/233
pull/330/head
laoyuyu 7 years ago
parent 426c148370
commit e362621c38
  1. 4
      Aria/build.gradle
  2. 2
      Aria/src/main/java/com/arialyy/aria/core/command/group/GroupCancelCmd.java
  3. 5
      Aria/src/main/java/com/arialyy/aria/core/command/normal/StartCmd.java
  4. 44
      Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java
  5. 56
      Aria/src/main/java/com/arialyy/aria/core/common/AbsFtpInfoThread.java
  6. 2
      Aria/src/main/java/com/arialyy/aria/core/common/AbsFtpThreadTask.java
  7. 81
      Aria/src/main/java/com/arialyy/aria/core/common/AbsThreadTask.java
  8. 6
      Aria/src/main/java/com/arialyy/aria/core/download/BaseNormalTarget.java
  9. 1
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupListener.java
  10. 8
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java
  11. 53
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/AbsGroupUtil.java
  12. 17
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadGroupUtil.java
  13. 37
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java
  14. 27
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java
  15. 2
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsTarget.java
  16. 16
      Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java
  17. 3
      Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java
  18. 28
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java
  19. 6
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/HttpThreadTask.java
  20. 3
      Aria/src/main/java/com/arialyy/aria/util/ALog.java
  21. 95
      Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java
  22. 9
      Aria/src/main/java/com/arialyy/aria/util/Regular.java
  23. 3
      README.md
  24. 5
      app/src/main/AndroidManifest.xml
  25. 2
      app/src/main/assets/aria_config.xml
  26. 5
      app/src/main/java/com/arialyy/simple/download/group/DownloadGroupActivity.java
  27. 8
      app/src/main/java/com/arialyy/simple/test/AnyRunActivity.java
  28. 8
      app/src/main/java/com/arialyy/simple/test/TestActivity.java
  29. 1
      aria/src/main/AndroidManifest.xml

@ -26,8 +26,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.3' // compile 'com.arialyy.aria:aria-ftp-plug:1.0.3'
// compile project(':AriaFtpPlug') compile project(':AriaFtpPlug')
} }
apply from: 'bintray-release.gradle' apply from: 'bintray-release.gradle'

@ -19,7 +19,7 @@ import com.arialyy.aria.core.inf.AbsGroupTaskEntity;
/** /**
* Created by AriaL on 2017/6/29. * Created by AriaL on 2017/6/29.
* 删除任务组 * 删除任务组子任务
*/ */
class GroupCancelCmd<T extends AbsGroupTaskEntity> extends AbsGroupCmd<T> { class GroupCancelCmd<T extends AbsGroupTaskEntity> extends AbsGroupCmd<T> {
/** /**

@ -86,8 +86,11 @@ class StartCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T> {
} }
} }
} else { } else {
if (!task.isRunning()) { //任务没执行并且执行队列中没有该任务,才认为任务没有运行中
if (!task.isRunning() && !mQueue.taskIsRunning(task.getKey())) {
resumeTask(); resumeTask();
}else {
ALog.w(TAG, String.format("任务【%s】已经在运行", task.getTaskName()));
} }
} }
if (mQueue.getCurrentCachePoolNum() == 0) { if (mQueue.getCurrentCachePoolNum() == 0) {

@ -16,7 +16,6 @@
package com.arialyy.aria.core.common; package com.arialyy.aria.core.common;
import android.content.Context; import android.content.Context;
import android.util.SparseArray;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.inf.AbsNormalEntity; import com.arialyy.aria.core.inf.AbsNormalEntity;
@ -29,8 +28,10 @@ import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.util.DbHelper; import com.arialyy.aria.util.DbHelper;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.Timer; import java.util.Timer;
@ -65,8 +66,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
private int mStartThreadNum; private int mStartThreadNum;
//已完成的线程数 //已完成的线程数
private int mCompleteThreadNum; private int mCompleteThreadNum;
private SparseArray<AbsThreadTask> mTask = new SparseArray<>(); private Map<Integer, AbsThreadTask> mTask = new HashMap<>();
private Timer mTimer; private Timer mTimer;
@Deprecated @Deprecated
@ -188,7 +188,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
} }
/** /**
* 获取当前下载位置 * 获取当前任务位置
*/ */
@Override public long getCurrentLocation() { @Override public long getCurrentLocation() {
return mConstance.CURRENT_LOCATION; return mConstance.CURRENT_LOCATION;
@ -244,7 +244,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
* 检查任务检查线程数 * 检查任务检查线程数
* 新任务条件 * 新任务条件
* 1文件不存在 * 1文件不存在
* 2下载记录文件缺失或不匹配 * 2任务记录文件缺失或不匹配
* 3数据库记录不存在 * 3数据库记录不存在
* 4不支持断点则是新任务 * 4不支持断点则是新任务
*/ */
@ -318,14 +318,14 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
tRecord.key = mRecord.filePath; tRecord.key = mRecord.filePath;
Object state = pro.getProperty(mTempFile.getName() + STATE + i); Object state = pro.getProperty(mTempFile.getName() + STATE + i);
Object record = pro.getProperty(mTempFile.getName() + RECORD + i); Object record = pro.getProperty(mTempFile.getName() + RECORD + i);
if (state != null && Integer.parseInt(state + "") == 1) { if (state != null && Integer.parseInt(String.valueOf(state)) == 1) {
mCompleteThreadNum++; mCompleteThreadNum++;
tRecord.isComplete = true; tRecord.isComplete = true;
continue; continue;
} }
mStartThreadNum++; mStartThreadNum++;
if (record != null) { if (record != null) {
Long temp = Long.parseLong(record + ""); Long temp = Long.parseLong(String.valueOf(record));
tRecord.startLocation = temp > 0 ? temp : 0; tRecord.startLocation = temp > 0 ? temp : 0;
} else { } else {
tRecord.startLocation = 0; tRecord.startLocation = 0;
@ -373,7 +373,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
*/ */
private boolean resumeRecordLocation(int i, long startL, long endL) { private boolean resumeRecordLocation(int i, long startL, long endL) {
mConstance.CURRENT_LOCATION += endL - startL; mConstance.CURRENT_LOCATION += endL - startL;
ALog.d(TAG, "任务【" + mTaskEntity.getEntity().getFileName() + "】线程__" + i + "__已完成"); ALog.d(TAG, String.format("任务【%s】线程__%s__已完成", mTaskEntity.getEntity().getFileName(), i));
mConstance.COMPLETE_THREAD_NUM = mCompleteThreadNum; mConstance.COMPLETE_THREAD_NUM = mCompleteThreadNum;
mConstance.STOP_NUM++; mConstance.STOP_NUM++;
mConstance.CANCEL_NUM++; mConstance.CANCEL_NUM++;
@ -439,7 +439,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
continue; continue;
} }
//如果有记录,则恢复下载 //如果有记录,则恢复任务
if (tr.startLocation >= 0) { if (tr.startLocation >= 0) {
Long r = tr.startLocation; Long r = tr.startLocation;
//记录的位置需要在线程区间中 //记录的位置需要在线程区间中
@ -447,7 +447,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
mConstance.CURRENT_LOCATION += r - startL; mConstance.CURRENT_LOCATION += r - startL;
startL = r; startL = r;
} }
ALog.d(TAG, "任务【" + mEntity.getFileName() + "】线程__" + i + "__恢复下载"); ALog.d(TAG, String.format("任务【%s】线程__%s__恢复任务", mEntity.getFileName(), i));
} }
//最后一个线程的结束位置即为文件的总长度 //最后一个线程的结束位置即为文件的总长度
if (i == (mTotalThreadNum - 1)) { if (i == (mTotalThreadNum - 1)) {
@ -470,7 +470,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
} }
/** /**
* 启动单线程下载任务 * 启动单线程任务
*/ */
private void startThreadTask(int[] recordL) { private void startThreadTask(int[] recordL) {
if (mConstance.CURRENT_LOCATION > 0) { if (mConstance.CURRENT_LOCATION > 0) {
@ -488,6 +488,26 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
} }
} }
/**
* 重试线程任务只有线程创建成功才能重试
*/
public void retryThradTask() {
if (mTask == null || mTask.size() == 0) {
ALog.w(TAG, "没有线程任务");
return;
}
Set<Integer> keys = mTask.keySet();
for (Integer key : keys) {
AbsThreadTask task = mTask.get(key);
if (task != null && !task.isThreadComplete()) {
task.getConfig().START_LOCATION = task.getCurrentLocation();
ALog.d(TAG, String.format("任务【%s】开始重试,线程__%s__【开始位置:%s,结束位置:%s】", mEntity.getFileName(),
key, task.getConfig().START_LOCATION, task.getConfig().END_LOCATION));
mFixedThreadPool.execute(task);
}
}
}
/** /**
* 处理新任务 * 处理新任务
* *
@ -496,7 +516,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
protected abstract boolean handleNewTask(); protected abstract boolean handleNewTask();
/** /**
* 处理不支持断点的下载 * 处理不支持断点的任务
*/ */
private void handleNoSupportBP() { private void handleNoSupportBP() {
SubThreadConfig<TASK_ENTITY> config = new SubThreadConfig<>(); SubThreadConfig<TASK_ENTITY> config = new SubThreadConfig<>();

@ -26,6 +26,7 @@ import com.arialyy.aria.util.Regular;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTP;
@ -72,7 +73,7 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
try { try {
client = createFtpClient(); client = createFtpClient();
if (client == null) { if (client == null) {
failDownload("创建FTP客户端失败", true); ALog.e(TAG, String.format("任务【%s】失败", mTaskEntity.getUrlEntity().url));
return; return;
} }
String remotePath = String remotePath =
@ -82,8 +83,8 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
ALog.i(TAG, s); ALog.i(TAG, s);
boolean isExist = files.length != 0; boolean isExist = files.length != 0;
if (!isExist && !isUpload) { if (!isExist && !isUpload) {
failDownload("文件不存在,任务链接【" + mTaskEntity.getUrlEntity().url + "】,remotePath:" + remotePath, failDownload(String.format("文件不存在,任务链接【%s】,remotePath:%s", mTaskEntity.getUrlEntity().url,
false); remotePath), false);
int i = remotePath.lastIndexOf(File.separator); int i = remotePath.lastIndexOf(File.separator);
FTPFile[] files1; FTPFile[] files1;
if (i == -1) { if (i == -1) {
@ -92,7 +93,8 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
files1 = client.listFiles(remotePath.substring(0, i + 1)); files1 = client.listFiles(remotePath.substring(0, i + 1));
} }
if (files1.length > 0) { if (files1.length > 0) {
ALog.i(TAG, "路径【" + setRemotePath() + "】下的文件列表 ==================================="); ALog.i(TAG,
String.format("路径【%s】下的文件列表 ===================================", setRemotePath()));
for (FTPFile file : files1) { for (FTPFile file : files1) {
ALog.d(TAG, file.toString()); ALog.d(TAG, file.toString());
} }
@ -114,7 +116,8 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
mTaskEntity.setNewTask(true); mTaskEntity.setNewTask(true);
} else { } else {
client.disconnect(); client.disconnect();
failDownload("获取文件信息错误,错误码为:" + reply + ",msg:" + client.getReplyString(), true); failDownload(String.format("获取文件信息错误,错误码为:%s,msg:%s", reply, client.getReplyString()),
true);
return; return;
} }
} }
@ -171,11 +174,14 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
if (m.find() && m.groupCount() > 0) { if (m.find() && m.groupCount() > 0) {
client = new FTPClient(); client = new FTPClient();
InetAddress ip = InetAddress.getByName(urlEntity.hostName); InetAddress ip = InetAddress.getByName(urlEntity.hostName);
client.setConnectTimeout(10000); // 连接10s超时 client.setConnectTimeout(mConnectTimeOut); // 连接10s超时
client.connect(ip, Integer.parseInt(urlEntity.port)); client.connect(ip, Integer.parseInt(urlEntity.port));
mTaskEntity.getUrlEntity().validAddr = ip; mTaskEntity.getUrlEntity().validAddr = ip;
} else { } else {
InetAddress[] ips = InetAddress.getAllByName(urlEntity.hostName); DNSQueryThread dnsThread = new DNSQueryThread(urlEntity.hostName);
dnsThread.start();
dnsThread.join(mConnectTimeOut);
InetAddress[] ips = dnsThread.getIps();
client = connect(new FTPClient(), ips, 0, Integer.parseInt(urlEntity.port)); client = connect(new FTPClient(), ips, 0, Integer.parseInt(urlEntity.port));
} }
@ -206,7 +212,8 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
int reply = client.getReplyCode(); int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) { if (!FTPReply.isPositiveCompletion(reply)) {
client.disconnect(); client.disconnect();
failDownload("无法连接到ftp服务器,错误码为:" + reply + ",msg:" + client.getReplyString(), true); failDownload(String.format("无法连接到ftp服务器,错误码为:%s,msg:%s", reply, client.getReplyString()),
true);
return null; return null;
} }
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码 // 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码
@ -221,9 +228,10 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
client.setDataTimeout(10 * 1000); client.setDataTimeout(10 * 1000);
client.enterLocalPassiveMode(); client.enterLocalPassiveMode();
client.setFileType(FTP.BINARY_FILE_TYPE); client.setFileType(FTP.BINARY_FILE_TYPE);
client.setConnectTimeout(mConnectTimeOut);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} }
return client; return client;
} }
@ -232,7 +240,12 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
* 连接到ftp服务器 * 连接到ftp服务器
*/ */
private FTPClient connect(FTPClient client, InetAddress[] ips, int index, int port) { private FTPClient connect(FTPClient client, InetAddress[] ips, int index, int port) {
if (ips == null || ips.length == 0) {
ALog.w(TAG, "无可用ip");
return null;
}
try { try {
client.setConnectTimeout(mConnectTimeOut); //需要先设置超时,这样才不会出现阻塞
client.connect(ips[index], port); client.connect(ips[index], port);
mTaskEntity.getUrlEntity().validAddr = ips[index]; mTaskEntity.getUrlEntity().validAddr = ips[index];
return client; return client;
@ -295,4 +308,29 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
mCallback.onFail(mEntity.getKey(), errorMsg, needRetry); mCallback.onFail(mEntity.getKey(), errorMsg, needRetry);
} }
} }
/**
* 获取可用IP的超时线程InetAddress.getByName没有超时功能需要自己处理超时
*/
private static class DNSQueryThread extends Thread {
private String hostName;
private InetAddress[] ips;
DNSQueryThread(String hostName) {
this.hostName = hostName;
}
@Override public void run() {
try {
ips = InetAddress.getAllByName(hostName);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
synchronized InetAddress[] getIps() {
return ips;
}
}
} }

@ -88,7 +88,7 @@ public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTI
if (!FTPReply.isPositiveCompletion(reply)) { if (!FTPReply.isPositiveCompletion(reply)) {
client.disconnect(); client.disconnect();
fail(mChildCurrentLocation, fail(mChildCurrentLocation,
"无法连接到ftp服务器,错误码为:" + reply + ",msg:" + client.getReplyString(), null); String.format("无法连接到ftp服务器,错误码为:%s,msg:%s", reply, client.getReplyString()), null);
return null; return null;
} }
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码 // 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码

@ -52,15 +52,14 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
protected SubThreadConfig<TASK_ENTITY> mConfig; protected SubThreadConfig<TASK_ENTITY> mConfig;
protected ENTITY mEntity; protected ENTITY mEntity;
protected TASK_ENTITY mTaskEntity; protected TASK_ENTITY mTaskEntity;
private int mFailNum = 0; private int mFailTimes = 0;
private String mTaskType;
private Timer mFailTimer; private Timer mFailTimer;
private long mLastSaveTime; private long mLastSaveTime;
private ExecutorService mConfigThreadPool; private ExecutorService mConfigThreadPool;
protected int mConnectTimeOut; //连接超时时间 protected int mConnectTimeOut; //连接超时时间
protected int mReadTimeOut; //流读取的超时时间 protected int mReadTimeOut; //流读取的超时时间
protected boolean isNotNetRetry = false; //断网情况是否重试 protected boolean isNotNetRetry = false; //断网情况是否重试
protected boolean taskBreak = false; //任务中断 private boolean taskBreak = false; //任务中断
private Thread mConfigThread = new Thread(new Runnable() { private Thread mConfigThread = new Thread(new Runnable() {
@Override public void run() { @Override public void run() {
@ -76,13 +75,10 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
mConfig = info; mConfig = info;
mTaskEntity = mConfig.TASK_ENTITY; mTaskEntity = mConfig.TASK_ENTITY;
mEntity = mTaskEntity.getEntity(); mEntity = mTaskEntity.getEntity();
mTaskType = getTaskType();
mLastSaveTime = System.currentTimeMillis(); mLastSaveTime = System.currentTimeMillis();
mConfigThreadPool = Executors.newCachedThreadPool(); mConfigThreadPool = Executors.newCachedThreadPool();
} }
protected abstract String getTaskType();
public void setMaxSpeed(double maxSpeed) { public void setMaxSpeed(double maxSpeed) {
if (-0.9999 < maxSpeed && maxSpeed < 0.00001) { if (-0.9999 < maxSpeed && maxSpeed < 0.00001) {
mSleepTime = 0; mSleepTime = 0;
@ -93,6 +89,28 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
} }
} }
/**
* 当前线程是否完成对于不支持断点的任务一律未完成
* {@code true} 完成{@code false} 未完成
*/
public boolean isThreadComplete() {
return mConfig.THREAD_RECORD.isComplete;
}
/**
* 获取线程配置信息
*/
public SubThreadConfig getConfig() {
return mConfig;
}
/**
* 当前线程下载进度
*/
public long getCurrentLocation() {
return mChildCurrentLocation;
}
private boolean filterVersion() { private boolean filterVersion() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
} }
@ -124,21 +142,16 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
if (mConfig.SUPPORT_BP) { if (mConfig.SUPPORT_BP) {
final long currentTemp = mChildCurrentLocation; final long currentTemp = mChildCurrentLocation;
STATE.STOP_NUM++; STATE.STOP_NUM++;
ALog.d(TAG, "任务【" ALog.d(TAG, String.format("任务【%s】thread__%s__停止【停止位置:%s】", mConfig.TEMP_FILE.getName(),
+ mConfig.TEMP_FILE.getName() mConfig.THREAD_ID, currentTemp));
+ "】thread__"
+ mConfig.THREAD_ID
+ "__停止【停止位置: "
+ currentTemp
+ "】");
writeConfig(false, currentTemp); writeConfig(false, currentTemp);
if (STATE.isStop()) { if (STATE.isStop()) {
ALog.i(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】已停止"); ALog.i(TAG, String.format("任务【%s】已停止", mConfig.TEMP_FILE.getName()));
STATE.isRunning = false; STATE.isRunning = false;
mListener.onStop(STATE.CURRENT_LOCATION); mListener.onStop(STATE.CURRENT_LOCATION);
} }
} else { } else {
ALog.i(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】已停止"); ALog.i(TAG, String.format("任务【%s】已停止", mConfig.TEMP_FILE.getName()));
STATE.isRunning = false; STATE.isRunning = false;
mListener.onStop(STATE.CURRENT_LOCATION); mListener.onStop(STATE.CURRENT_LOCATION);
} }
@ -174,17 +187,18 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
synchronized (AriaManager.LOCK) { synchronized (AriaManager.LOCK) {
if (mConfig.SUPPORT_BP) { if (mConfig.SUPPORT_BP) {
STATE.CANCEL_NUM++; STATE.CANCEL_NUM++;
ALog.d(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】thread__" + mConfig.THREAD_ID + "__取消"); ALog.d(TAG,
String.format("任务【%s】thread__%s__取消", mConfig.TEMP_FILE.getName(), mConfig.THREAD_ID));
if (STATE.isCancel()) { if (STATE.isCancel()) {
if (mConfig.TEMP_FILE.exists() && !(mEntity instanceof UploadEntity)) { if (mConfig.TEMP_FILE.exists() && !(mEntity instanceof UploadEntity)) {
mConfig.TEMP_FILE.delete(); mConfig.TEMP_FILE.delete();
} }
ALog.d(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】已取消"); ALog.d(TAG, String.format("任务【%s】已取消", mConfig.TEMP_FILE.getName()));
STATE.isRunning = false; STATE.isRunning = false;
mListener.onCancel(); mListener.onCancel();
} }
} else { } else {
ALog.d(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】已取消"); ALog.d(TAG, String.format("任务【%s】已取消", mConfig.TEMP_FILE.getName()));
STATE.isRunning = false; STATE.isRunning = false;
mListener.onCancel(); mListener.onCancel();
} }
@ -216,9 +230,9 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
} }
if (mConfig.SUPPORT_BP) { if (mConfig.SUPPORT_BP) {
writeConfig(false, subCurrentLocation); writeConfig(false, subCurrentLocation);
retryThis(STATE.START_THREAD_NUM != 1); retryThis(needRetry && STATE.START_THREAD_NUM != 1);
} else { } else {
ALog.e(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】执行失败"); ALog.e(TAG, String.format("任务【%s】执行失败", mConfig.TEMP_FILE.getName()));
mListener.onFail(true); mListener.onFail(true);
ErrorHelp.saveError(TAG, "", ALog.getExceptionString(ex)); ErrorHelp.saveError(TAG, "", ALog.getExceptionString(ex));
} }
@ -236,23 +250,21 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
mFailTimer.cancel(); mFailTimer.cancel();
} }
if (!NetUtils.isConnected(AriaManager.APP) && !isNotNetRetry) { if (!NetUtils.isConnected(AriaManager.APP) && !isNotNetRetry) {
ALog.w(TAG, ALog.w(TAG, String.format("任务【%s】thread__%s__重试失败,网络未连接", mConfig.TEMP_FILE.getName(),
"任务【" + mConfig.TEMP_FILE.getName() + "】thread__" + mConfig.THREAD_ID + "__重试失败,网络未连接"); mConfig.THREAD_ID));
} }
if (mFailNum < RETRY_NUM if (mFailTimes < RETRY_NUM
&& needRetry && needRetry
&& NetUtils.isConnected(AriaManager.APP) && (NetUtils.isConnected(AriaManager.APP) || isNotNetRetry)
&& !isNotNetRetry && isBreak()) {
&& !STATE.isCancel
&& !STATE.isStop) {
mFailTimer = new Timer(true); mFailTimer = new Timer(true);
mFailTimer.schedule(new TimerTask() { mFailTimer.schedule(new TimerTask() {
@Override public void run() { @Override public void run() {
mFailNum++; mFailTimes++;
ALog.w(TAG, ALog.w(TAG, String.format("任务【%s】thread__%s__正在重试", mConfig.TEMP_FILE.getName(),
"任务【" + mConfig.TEMP_FILE.getName() + "】thread__" + mConfig.THREAD_ID + "__正在重试"); mConfig.THREAD_ID));
mConfig.START_LOCATION = final long temp = mChildCurrentLocation;
mChildCurrentLocation == 0 ? mConfig.START_LOCATION : mChildCurrentLocation; mConfig.START_LOCATION = mChildCurrentLocation == 0 ? mConfig.START_LOCATION : temp;
AbsThreadTask.this.run(); AbsThreadTask.this.run();
} }
}, RETRY_INTERVAL); }, RETRY_INTERVAL);
@ -261,7 +273,7 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
if (STATE.isFail()) { if (STATE.isFail()) {
STATE.isRunning = false; STATE.isRunning = false;
STATE.isStop = true; STATE.isStop = true;
ALog.e(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】执行失败"); ALog.e(TAG, String.format("任务【%s】执行失败", mConfig.TEMP_FILE.getName()));
mListener.onFail(true); mListener.onFail(true);
} }
} }
@ -269,6 +281,9 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
/** /**
* 将记录写入到配置文件 * 将记录写入到配置文件
*
* @param isComplete 当前线程是否完成 {@code true}完成
* @param record 当前下载进度
*/ */
protected void writeConfig(boolean isComplete, final long record) { protected void writeConfig(boolean isComplete, final long record) {
if (mConfig.THREAD_RECORD != null) { if (mConfig.THREAD_RECORD != null) {

@ -136,8 +136,12 @@ abstract class BaseNormalTarget<TARGET extends BaseNormalTarget>
} else if (getTargetType() == FTP) { } else if (getTargetType() == FTP) {
filePath += mEntity.getFileName(); filePath += mEntity.getFileName();
} }
} else {
// http文件名设置
if (TextUtils.isEmpty(mEntity.getFileName())) {
mEntity.setFileName(file.getName());
}
} }
mEntity.setFileName(file.getName());
//设置文件保存路径,如果新文件路径和就文件路径不同,则修改路径 //设置文件保存路径,如果新文件路径和就文件路径不同,则修改路径
if (!filePath.equals(mEntity.getDownloadPath())) { if (!filePath.equals(mEntity.getDownloadPath())) {

@ -89,6 +89,7 @@ class DownloadGroupListener
for (DownloadEntity e : mEntity.getSubEntities()) { for (DownloadEntity e : mEntity.getSubEntities()) {
location += e.getCurrentProgress(); location += e.getCurrentProgress();
} }
mEntity.setCurrentProgress(location); mEntity.setCurrentProgress(location);
mEntity.update(); mEntity.update();
} }

@ -143,9 +143,13 @@ public class DownloadGroupTarget extends BaseGroupTarget<DownloadGroupTarget> {
reChangeDirPath(mDirPathTemp); reChangeDirPath(mDirPathTemp);
} }
if (!mSubNameTemp.isEmpty()) { if (mSubNameTemp.isEmpty()) {
updateSingleSubFileName(); for (String url : mUrls) {
int lastIndex = url.lastIndexOf(File.separator);
mSubNameTemp.add(url.substring(lastIndex + 1, url.length()));
}
} }
updateSingleSubFileName();
return true; return true;
} }
return false; return false;

@ -39,6 +39,7 @@ import java.util.concurrent.Executors;
* 任务组核心逻辑 * 任务组核心逻辑
*/ */
public abstract class AbsGroupUtil implements IUtil { public abstract class AbsGroupUtil implements IUtil {
private static final Object LOCK = new Object();
private final String TAG = "AbsGroupUtil"; private final String TAG = "AbsGroupUtil";
/** /**
* FTP文件夹 * FTP文件夹
@ -158,6 +159,9 @@ public abstract class AbsGroupUtil implements IUtil {
DownloadTaskEntity det = mTasksMap.get(url); DownloadTaskEntity det = mTasksMap.get(url);
if (det != null) { if (det != null) {
mTotalLen -= det.getEntity().getFileSize(); mTotalLen -= det.getEntity().getFileSize();
mCurrentLocation -= det.getEntity().getCurrentProgress();
mExeMap.remove(det.getKey());
mFailMap.remove(det.getKey());
mGroupSize--; mGroupSize--;
if (mGroupSize == 0) { if (mGroupSize == 0) {
closeTimer(false); closeTimer(false);
@ -305,12 +309,12 @@ public abstract class AbsGroupUtil implements IUtil {
} }
private void clearState(){ private void clearState() {
mDownloaderMap.clear(); mDownloaderMap.clear();
mFailMap.clear(); mFailMap.clear();
} }
private void closeTimer(boolean isRunning) { void closeTimer(boolean isRunning) {
this.isRunning = isRunning; this.isRunning = isRunning;
if (mTimer != null) { if (mTimer != null) {
mTimer.purge(); mTimer.purge();
@ -374,6 +378,8 @@ public abstract class AbsGroupUtil implements IUtil {
private int RUN_SAVE_INTERVAL = 5 * 1000; //5s保存一次下载中的进度 private int RUN_SAVE_INTERVAL = 5 * 1000; //5s保存一次下载中的进度
private long lastSaveTime; private long lastSaveTime;
private long lastLen = 0; private long lastLen = 0;
private Timer timer;
private boolean isNotNetRetry = false;
ChildDownloadListener(DownloadTaskEntity entity) { ChildDownloadListener(DownloadTaskEntity entity) {
subTaskEntity = entity; subTaskEntity = entity;
@ -381,6 +387,7 @@ public abstract class AbsGroupUtil implements IUtil {
subEntity.setFailNum(0); subEntity.setFailNum(0);
lastLen = subEntity.getCurrentProgress(); lastLen = subEntity.getCurrentProgress();
lastSaveTime = System.currentTimeMillis(); lastSaveTime = System.currentTimeMillis();
isNotNetRetry = AriaManager.getInstance(AriaManager.APP).getDownloadConfig().isNotNetRetry();
} }
@Override public void onPre() { @Override public void onPre() {
@ -423,7 +430,7 @@ public abstract class AbsGroupUtil implements IUtil {
saveData(IEntity.STATE_STOP, stopLocation); saveData(IEntity.STATE_STOP, stopLocation);
handleSpeed(0); handleSpeed(0);
mListener.onSubStop(subEntity); mListener.onSubStop(subEntity);
synchronized (AbsGroupUtil.class) { synchronized (AbsGroupUtil.LOCK) {
mStopNum++; mStopNum++;
if (mStopNum + mCompleteNum + mFailMap.size() == mGroupSize) { if (mStopNum + mCompleteNum + mFailMap.size() == mGroupSize) {
closeTimer(false); closeTimer(false);
@ -439,16 +446,17 @@ public abstract class AbsGroupUtil implements IUtil {
} }
@Override public void onComplete() { @Override public void onComplete() {
subEntity.setComplete(true);
saveData(IEntity.STATE_COMPLETE, subEntity.getFileSize()); saveData(IEntity.STATE_COMPLETE, subEntity.getFileSize());
handleSpeed(0); handleSpeed(0);
mListener.onSubComplete(subEntity); mListener.onSubComplete(subEntity);
synchronized (ChildDownloadListener.class) { synchronized (AbsGroupUtil.LOCK) {
mCompleteNum++; mCompleteNum++;
//如果子任务完成的数量和总任务数一致,表示任务组任务已经完成 //如果子任务完成的数量和总任务数一致,表示任务组任务已经完成
if (mCompleteNum >= mGroupSize) { if (mCompleteNum == mGroupSize) {
closeTimer(false); closeTimer(false);
mListener.onComplete(); mListener.onComplete();
} else if (mFailMap.size() > 0 && mStopNum + mCompleteNum + mFailMap.size() >= mGroupSize) { } else if (mFailMap.size() > 0 && mStopNum + mCompleteNum + mFailMap.size() == mGroupSize) {
//如果子任务完成数量加上失败的数量和总任务数一致,则任务组停止下载 //如果子任务完成数量加上失败的数量和总任务数一致,则任务组停止下载
closeTimer(false); closeTimer(false);
mListener.onStop(mCurrentLocation); mListener.onStop(mCurrentLocation);
@ -464,41 +472,48 @@ public abstract class AbsGroupUtil implements IUtil {
} }
/** /**
* 重试下载 * 重试下载只有全部都下载失败才会执行任务组的整体重试否则只会执行单个子任务的重试
*/ */
private void reTry(boolean needRetry) { private void reTry(boolean needRetry) {
synchronized (ChildDownloadListener.class) { synchronized (AbsGroupUtil.LOCK) {
if (subEntity.getFailNum() < 5 && needRetry && NetUtils.isConnected(AriaManager.APP)) { if (subEntity.getFailNum() < 5
&& needRetry && (NetUtils.isConnected(AriaManager.APP) || isNotNetRetry)) {
reStartTask(); reStartTask();
} else { } else {
mFailMap.put(subTaskEntity.getUrl(), subTaskEntity); mFailMap.put(subTaskEntity.getUrl(), subTaskEntity);
mListener.onSubFail(subEntity); mListener.onSubFail(subEntity);
//如果失败的任务数大于实际的下载任务数,任务组停止下载 if (mFailMap.size() == mExeMap.size() || mFailMap.size() + mCompleteNum == mGroupSize) {
if (mFailMap.size() >= mExeMap.size()) {
closeTimer(false); closeTimer(false);
if (mFailMap.size() == mGroupSize) { //所有任务都失败了,则认为该任务组已经失败 }
mListener.onFail(true); if (mFailMap.size() == mGroupSize) {
} else { mListener.onFail(true);
mListener.onStop(mCurrentLocation); } else if (mFailMap.size() + mCompleteNum >= mExeMap.size()) {
} mListener.onStop(mCurrentLocation);
} }
} }
} }
} }
private void reStartTask() { private void reStartTask() {
Timer timer = new Timer(); if (timer != null) {
timer.purge();
timer.cancel();
}
timer = new Timer();
timer.schedule(new TimerTask() { timer.schedule(new TimerTask() {
@Override public void run() { @Override public void run() {
Downloader dt = mDownloaderMap.get(subEntity.getUrl()); Downloader dt = mDownloaderMap.get(subEntity.getUrl());
dt.start(); if (dt != null) {
dt.retryThradTask();
}
} }
}, 3000); }, 3000);
} }
private void handleSpeed(long speed) { private void handleSpeed(long speed) {
subEntity.setSpeed(speed); subEntity.setSpeed(speed);
subEntity.setConvertSpeed(speed <= 0 ? "" : CommonUtil.formatFileSize(speed) + "/s"); subEntity.setConvertSpeed(
speed <= 0 ? "" : String.format("%s/s", CommonUtil.formatFileSize(speed)));
subEntity.setPercent((int) (subEntity.getFileSize() <= 0 ? 0 subEntity.setPercent((int) (subEntity.getFileSize() <= 0 ? 0
: subEntity.getCurrentProgress() * 100 / subEntity.getFileSize())); : subEntity.getCurrentProgress() * 100 / subEntity.getFileSize()));
} }

@ -34,7 +34,14 @@ import java.util.concurrent.Executors;
public class DownloadGroupUtil extends AbsGroupUtil implements IUtil { public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
private final String TAG = "DownloadGroupUtil"; private final String TAG = "DownloadGroupUtil";
private ExecutorService mInfoPool; private ExecutorService mInfoPool;
private int mInitCompleteNum, mInitFailNum; /**
* 初始化完成的任务数
*/
private int mInitCompleteNum;
/**
* 初始化失败的任务数
*/
private int mInitFailNum;
private boolean isStop = false; private boolean isStop = false;
/** /**
@ -126,7 +133,7 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
@Override public void onFail(String url, String errorMsg, boolean needRetry) { @Override public void onFail(String url, String errorMsg, boolean needRetry) {
if (isStop) return; if (isStop) return;
ALog.e(TAG, "任务【" + url + "】初始化失败。"); ALog.e(TAG, String.format("任务【%s】初始化失败", url));
DownloadTaskEntity te = mExeMap.get(url); DownloadTaskEntity te = mExeMap.get(url);
if (te != null) { if (te != null) {
mFailMap.put(url, te); mFailMap.put(url, te);
@ -154,7 +161,11 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
*/ */
private void checkStartFlow() { private void checkStartFlow() {
synchronized (DownloadGroupUtil.class) { synchronized (DownloadGroupUtil.class) {
if (mInitCompleteNum + mInitFailNum >= mGroupSize || !isNeedLoadFileSize) { if (mInitFailNum == mGroupSize){
closeTimer(false);
mListener.onFail(true);
}
if (mInitCompleteNum + mInitFailNum == mGroupSize || !isNeedLoadFileSize) {
startRunningFlow(); startRunningFlow();
updateFileSize(); updateFileSize();
} }

@ -61,15 +61,9 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
InputStream is = null; InputStream is = null;
try { try {
ALog.d(TAG, "任务【" ALog.d(TAG,
+ mConfig.TEMP_FILE.getName() String.format("任务【%s】线程__%s__开始下载【开始位置 : %s,结束位置:%s】", mConfig.TEMP_FILE.getName(),
+ "】线程__" mConfig.THREAD_ID, mConfig.START_LOCATION, mConfig.END_LOCATION));
+ mConfig.THREAD_ID
+ "__开始下载【开始位置 : "
+ mConfig.START_LOCATION
+ ",结束位置:"
+ mConfig.END_LOCATION
+ "】");
client = createClient(); client = createClient();
if (client == null) return; if (client == null) return;
if (mConfig.START_LOCATION > 0) { if (mConfig.START_LOCATION > 0) {
@ -78,18 +72,20 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
//发送第二次指令时,还需要再做一次判断 //发送第二次指令时,还需要再做一次判断
int reply = client.getReplyCode(); int reply = client.getReplyCode();
if (!FTPReply.isPositivePreliminary(reply) && reply != FTPReply.COMMAND_OK) { if (!FTPReply.isPositivePreliminary(reply) && reply != FTPReply.COMMAND_OK) {
fail(mChildCurrentLocation, "获取文件信息错误,错误码为:" + reply + ",msg:" + client.getReplyString(), fail(mChildCurrentLocation,
String.format("获取文件信息错误,错误码为:%s,msg:%s", reply, client.getReplyString()),
null); null);
client.disconnect(); client.disconnect();
return; return;
} }
String remotePath = String remotePath =
new String(mTaskEntity.getUrlEntity().remotePath.getBytes(charSet), SERVER_CHARSET); new String(mTaskEntity.getUrlEntity().remotePath.getBytes(charSet), SERVER_CHARSET);
ALog.i(TAG, "remotePath【" + remotePath + "】"); ALog.i(TAG, String.format("remotePath【%s】", remotePath));
is = client.retrieveFileStream(remotePath); is = client.retrieveFileStream(remotePath);
reply = client.getReplyCode(); reply = client.getReplyCode();
if (!FTPReply.isPositivePreliminary(reply)) { if (!FTPReply.isPositivePreliminary(reply)) {
fail(mChildCurrentLocation, "获取流失败,错误码为:" + reply + ",msg:" + client.getReplyString(), fail(mChildCurrentLocation,
String.format("获取流失败,错误码为:%s,msg:%s", reply, client.getReplyString()),
null); null);
client.disconnect(); client.disconnect();
return; return;
@ -101,11 +97,12 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
readNormal(is); readNormal(is);
} }
if (isBreak()){ if (isBreak()) {
return; return;
} }
ALog.i(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】线程__" + mConfig.THREAD_ID + "__下载完毕"); ALog.i(TAG,
writeConfig(true, 1); String.format("任务【%s】线程__%s__下载完毕", mConfig.TEMP_FILE.getName(), mConfig.THREAD_ID));
writeConfig(true, mConfig.END_LOCATION);
STATE.COMPLETE_THREAD_NUM++; STATE.COMPLETE_THREAD_NUM++;
if (STATE.isComplete()) { if (STATE.isComplete()) {
STATE.TASK_RECORD.deleteData(); STATE.TASK_RECORD.deleteData();
@ -117,7 +114,7 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
mListener.onFail(false); mListener.onFail(false);
} }
} catch (IOException e) { } catch (IOException e) {
fail(mChildCurrentLocation, "下载失败【" + mConfig.URL + "】", e); fail(mChildCurrentLocation, String.format("下载失败【%s】", mConfig.URL), e);
} catch (Exception e) { } catch (Exception e) {
fail(mChildCurrentLocation, "获取流失败", e); fail(mChildCurrentLocation, "获取流失败", e);
} finally { } finally {
@ -162,7 +159,7 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
fail(mChildCurrentLocation, "下载失败【" + mConfig.URL + "】", e); fail(mChildCurrentLocation, String.format("下载失败【%s】", mConfig.URL), e);
} finally { } finally {
try { try {
if (fos != null) { if (fos != null) {
@ -206,7 +203,7 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
} }
} }
} catch (IOException e) { } catch (IOException e) {
fail(mChildCurrentLocation, "下载失败【" + mConfig.URL + "】", e); fail(mChildCurrentLocation, String.format("下载失败【%s】", mConfig.URL), e);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
@ -219,8 +216,4 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
} }
} }
} }
@Override protected String getTaskType() {
return "FTP_DOWNLOAD";
}
} }

@ -67,18 +67,12 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
URL url = new URL(CommonUtil.convertUrl(mConfig.URL)); URL url = new URL(CommonUtil.convertUrl(mConfig.URL));
conn = ConnectionHelp.handleConnection(url); conn = ConnectionHelp.handleConnection(url);
if (mConfig.SUPPORT_BP) { if (mConfig.SUPPORT_BP) {
ALog.d(TAG, "任务【" ALog.d(TAG,
+ mConfig.TEMP_FILE.getName() String.format("任务【%s】线程__%s__开始下载【开始位置 : %s,结束位置:%s】", mConfig.TEMP_FILE.getName(),
+ "】线程__" mConfig.THREAD_ID, mConfig.START_LOCATION, mConfig.END_LOCATION));
+ mConfig.THREAD_ID
+ "__开始下载【开始位置 : "
+ mConfig.START_LOCATION
+ ",结束位置:"
+ mConfig.END_LOCATION
+ "】");
//在头里面请求下载开始位置和结束位置 //在头里面请求下载开始位置和结束位置
conn.setRequestProperty("Range", conn.setRequestProperty("Range",
"bytes=" + mConfig.START_LOCATION + "-" + (mConfig.END_LOCATION - 1)); String.format("bytes=%s-%s", mConfig.START_LOCATION, (mConfig.END_LOCATION - 1)));
} else { } else {
ALog.w(TAG, "该下载不支持断点"); ALog.w(TAG, "该下载不支持断点");
} }
@ -108,7 +102,7 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
fail(mChildCurrentLocation, "下载链接异常", e); fail(mChildCurrentLocation, "下载链接异常", e);
} catch (IOException e) { } catch (IOException e) {
fail(mChildCurrentLocation, "下载失败【" + mConfig.URL + "】", e); fail(mChildCurrentLocation, String.format("下载失败【%s】", mConfig.URL), e);
} catch (Exception e) { } catch (Exception e) {
fail(mChildCurrentLocation, "获取流失败", e); fail(mChildCurrentLocation, "获取流失败", e);
} finally { } finally {
@ -156,7 +150,7 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
fail(mChildCurrentLocation, "下载失败【" + mConfig.URL + "】", e); fail(mChildCurrentLocation, String.format("下载失败【%s】", mConfig.URL), e);
} finally { } finally {
try { try {
if (fos != null) { if (fos != null) {
@ -210,8 +204,9 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
//支持断点的处理 //支持断点的处理
if (mConfig.SUPPORT_BP) { if (mConfig.SUPPORT_BP) {
if (mChildCurrentLocation == mConfig.END_LOCATION) { if (mChildCurrentLocation == mConfig.END_LOCATION) {
ALog.i(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】线程__" + mConfig.THREAD_ID + "__下载完毕"); ALog.i(TAG,
writeConfig(true, 1); String.format("任务【%s】线程__%s__下载完毕", mConfig.TEMP_FILE.getName(), mConfig.THREAD_ID));
writeConfig(true, mConfig.END_LOCATION);
STATE.COMPLETE_THREAD_NUM++; STATE.COMPLETE_THREAD_NUM++;
if (STATE.isComplete()) { if (STATE.isComplete()) {
STATE.TASK_RECORD.deleteData(); STATE.TASK_RECORD.deleteData();
@ -231,8 +226,4 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
mListener.onComplete(); mListener.onComplete();
} }
} }
@Override protected String getTaskType() {
return "HTTP_DOWNLOAD";
}
} }

@ -107,7 +107,7 @@ public abstract class AbsTarget<TARGET extends AbsTarget, ENTITY extends AbsEnti
if (TextUtils.isEmpty(mEntity.getStr()) || !mEntity.getStr().equals(str)) { if (TextUtils.isEmpty(mEntity.getStr()) || !mEntity.getStr().equals(str)) {
mEntity.setStr(str); mEntity.setStr(str);
} else { } else {
ALog.e(TAG, "设置扩展字段失败,扩展字段为null"); ALog.e(TAG, "设置扩展字段失败,扩展字段为一致");
} }
return (TARGET) this; return (TARGET) this;

@ -165,12 +165,14 @@ abstract class AbsTaskQueue<TASK extends AbsTask, TASK_ENTITY extends AbsTaskEnt
} }
@Override public void stopTask(TASK task) { @Override public void stopTask(TASK task) {
if (!task.isRunning()) ALog.w(TAG, "停止任务【" + task.getTaskName() + "】失败,原因:已停止"); if (!task.isRunning()) {
ALog.w(TAG, String.format("停止任务【%s】失败,原因:已停止", task.getTaskName()));
}
if (mExecutePool.removeTask(task)) { if (mExecutePool.removeTask(task)) {
task.stop(); task.stop();
} else { } else {
task.stop(); task.stop();
ALog.w(TAG, "删除任务【" + task.getTaskName() + "】失败,原因:执行队列中没有该任务"); ALog.w(TAG, String.format("删除任务【%s】失败,原因:执行队列中没有该任务", task.getTaskName()));
} }
} }
@ -178,13 +180,13 @@ abstract class AbsTaskQueue<TASK extends AbsTask, TASK_ENTITY extends AbsTaskEnt
//TEManager.getInstance().removeTEntity(key); //TEManager.getInstance().removeTEntity(key);
TASK task = mExecutePool.getTask(key); TASK task = mExecutePool.getTask(key);
if (task != null) { if (task != null) {
ALog.d(TAG, ALog.d(TAG, String.format("从执行池删除任务【%s】%s", task.getTaskName(),
"从执行池删除任务【" + task.getTaskName() + "】" + (mExecutePool.removeTask(task) ? "成功" : "失败")); (mExecutePool.removeTask(task) ? "成功" : "失败")));
} }
task = mCachePool.getTask(key); task = mCachePool.getTask(key);
if (task != null) { if (task != null) {
ALog.d(TAG, ALog.d(TAG, String.format("从缓存池删除任务【%s】%s", task.getTaskName(),
"从缓存池删除任务【" + task.getTaskName() + "】" + (mCachePool.removeTask(task) ? "成功" : "失败")); (mCachePool.removeTask(task) ? "成功" : "失败")));
} }
} }
@ -201,7 +203,7 @@ abstract class AbsTaskQueue<TASK extends AbsTask, TASK_ENTITY extends AbsTaskEnt
task.start(); task.start();
} else { } else {
task.stop(); task.stop();
ALog.e(TAG, "任务【" + task.getTaskName() + "】重试失败,原因:任务没有完全停止,"); ALog.e(TAG, String.format("任务【%s】重试失败,原因:任务没有完全停止", task.getTaskName()));
} }
} }

@ -17,6 +17,7 @@ package com.arialyy.aria.core.scheduler;
import android.os.CountDownTimer; import android.os.CountDownTimer;
import android.os.Message; import android.os.Message;
import android.util.Log;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.download.DownloadGroupTask; import com.arialyy.aria.core.download.DownloadGroupTask;
import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.core.download.DownloadTask;
@ -292,7 +293,7 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskEntity, TASK extends Abs
@Override public void onFinish() { @Override public void onFinish() {
AbsEntity entity = task.getTaskEntity().getEntity(); AbsEntity entity = task.getTaskEntity().getEntity();
if (entity.getFailNum() <= reTryNum) { if (entity.getFailNum() <= reTryNum) {
ALog.d(TAG, "任务【" + task.getTaskName() + "】开始重试"); ALog.d(TAG, String.format("任务【%s】开始重试", task.getTaskName()));
TASK task = mQueue.getTask(entity.getKey()); TASK task = mQueue.getTask(entity.getKey());
mQueue.reTryStart(task); mQueue.reTryStart(task);
} else { } else {

@ -54,15 +54,9 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
FTPClient client = null; FTPClient client = null;
BufferedRandomAccessFile file = null; BufferedRandomAccessFile file = null;
try { try {
ALog.d(TAG, "任务【" ALog.d(TAG,
+ mConfig.TEMP_FILE.getName() String.format("任务【%s】线程__%s__开始上传【开始位置 : %s,结束位置:%s】", mConfig.TEMP_FILE.getName(),
+ "】线程__" mConfig.THREAD_ID, mConfig.START_LOCATION, mConfig.END_LOCATION));
+ mConfig.THREAD_ID
+ "__开始上传【开始位置 : "
+ mConfig.START_LOCATION
+ ",结束位置:"
+ mConfig.END_LOCATION
+ "】");
client = createClient(); client = createClient();
if (client == null) return; if (client == null) return;
initPath(); initPath();
@ -85,8 +79,9 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
if (isBreak()) { if (isBreak()) {
return; return;
} }
ALog.i(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】线程__" + mConfig.THREAD_ID + "__上传完毕"); ALog.i(TAG,
writeConfig(true, 1); String.format("任务【%s】线程__%s__上传完毕", mConfig.TEMP_FILE.getName(), mConfig.THREAD_ID));
writeConfig(true, mConfig.END_LOCATION);
STATE.COMPLETE_THREAD_NUM++; STATE.COMPLETE_THREAD_NUM++;
if (STATE.isComplete()) { if (STATE.isComplete()) {
STATE.TASK_RECORD.deleteData(); STATE.TASK_RECORD.deleteData();
@ -98,7 +93,7 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
mListener.onFail(false); mListener.onFail(false);
} }
} catch (IOException e) { } catch (IOException e) {
fail(mChildCurrentLocation, "上传失败【" + mConfig.URL + "】", e); fail(mChildCurrentLocation, String.format("上传失败【%s】", mConfig.URL), e);
} catch (Exception e) { } catch (Exception e) {
fail(mChildCurrentLocation, "获取流失败", e); fail(mChildCurrentLocation, "获取流失败", e);
} finally { } finally {
@ -127,7 +122,7 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
throws IOException { throws IOException {
try { try {
ALog.d(TAG, "remotePath【" + remotePath + "】"); ALog.d(TAG, String.format("remotePath【%s】", remotePath));
client.storeFile(remotePath, new FtpFISAdapter(bis), new OnFtpInputStreamListener() { client.storeFile(remotePath, new FtpFISAdapter(bis), new OnFtpInputStreamListener() {
boolean isStoped = false; boolean isStoped = false;
@ -155,7 +150,8 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
int reply = client.getReplyCode(); int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) { if (!FTPReply.isPositiveCompletion(reply)) {
if (reply != FTPReply.TRANSFER_ABORTED) { if (reply != FTPReply.TRANSFER_ABORTED) {
fail(mChildCurrentLocation, "上传文件错误,错误码为:" + reply + ",msg:" + client.getReplyString(), fail(mChildCurrentLocation,
String.format("上传文件错误,错误码为:%s,msg:%s", reply, client.getReplyString()),
null); null);
} }
if (client.isConnected()) { if (client.isConnected()) {
@ -163,8 +159,4 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
} }
} }
} }
@Override protected String getTaskType() {
return "FTP_UPLOAD";
}
} }

@ -62,7 +62,7 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
@Override public void run() { @Override public void run() {
File uploadFile = new File(mEntity.getFilePath()); File uploadFile = new File(mEntity.getFilePath());
if (!uploadFile.exists()) { if (!uploadFile.exists()) {
ALog.e(TAG, "【" + mEntity.getFilePath() + "】,文件不存在。"); ALog.e(TAG, String.format("【%s】,文件不存在。", mEntity.getFilePath()));
fail(); fail();
return; return;
} }
@ -212,8 +212,4 @@ class HttpThreadTask extends AbsThreadTask<UploadEntity, UploadTaskEntity> {
mOutputStream.close(); mOutputStream.close();
return response.toString(); return response.toString();
} }
@Override protected String getTaskType() {
return "HTTP_UPLOAD";
}
} }

@ -117,6 +117,9 @@ public class ALog {
* 将异常信息转换为字符串 * 将异常信息转换为字符串
*/ */
public static String getExceptionString(Throwable ex) { public static String getExceptionString(Throwable ex) {
if (ex == null) {
return "";
}
StringBuilder err = new StringBuilder(); StringBuilder err = new StringBuilder();
err.append("ExceptionDetailed:\n"); err.append("ExceptionDetailed:\n");
err.append("====================Exception Info====================\n"); err.append("====================Exception Info====================\n");

@ -246,53 +246,30 @@ public class CommonUtil {
* @param url 输入的url{@code String url = "ftp://z:z@dygod18.com:21211/[电影天堂www.dy2018.com]猩球崛起3:终极之战BD国英双语中英双字.mkv";} * @param url 输入的url{@code String url = "ftp://z:z@dygod18.com:21211/[电影天堂www.dy2018.com]猩球崛起3:终极之战BD国英双语中英双字.mkv";}
*/ */
public static FtpUrlEntity getFtpUrlInfo(String url) { public static FtpUrlEntity getFtpUrlInfo(String url) {
Uri uri = Uri.parse(url);
String userInfo = uri.getUserInfo(), remotePath = uri.getPath();
ALog.d(TAG,
String.format("scheme = %s, user = %s, host = %s, port = %s, path = %s", uri.getScheme(),
userInfo, uri.getHost(), uri.getPort(), remotePath));
FtpUrlEntity entity = new FtpUrlEntity(); FtpUrlEntity entity = new FtpUrlEntity();
entity.url = url; entity.url = url;
//String regex = "(\\w+)://(.*):(\\d*)/(.*)"; entity.hostName = uri.getHost();
String regex = Regular.REG_FTP_URL; entity.port = uri.getPort() == -1 ? "21" : String.valueOf(uri.getPort());
Pattern p = Pattern.compile(regex); if (!TextUtils.isEmpty(userInfo)) {
Matcher m = p.matcher(url); String[] temp = userInfo.split(":");
if (m.find() && m.groupCount() > 0) { if (temp.length == 2) {
entity.protocol = m.group(1); entity.user = temp[0];
String str = m.group(2); entity.password = temp[1];
if (str.contains("@")) {
entity.needLogin = true;
//String hostReg = "(\\w+):?(\\w+)?@(.*)";
String hostReg = Regular.REG_FTP_HOST_NAME;
Pattern hp = Pattern.compile(hostReg);
Matcher hm = hp.matcher(str);
if (hm.find() && hm.groupCount() > 0) {
entity.user = hm.group(1);
entity.password = TextUtils.isEmpty(hm.group(2)) ? "" : hm.group(2);
entity.hostName = hm.group(3);
}
} else { } else {
entity.hostName = str; entity.user = userInfo;
} }
entity.port = m.group(3);
//entity.remotePath = TextUtils.isEmpty(m.group(4)) ? "/" : "/" + m.group(4);
entity.remotePath = TextUtils.isEmpty(m.group(4)) ? "/" : m.group(4);
} }
entity.remotePath = TextUtils.isEmpty(remotePath) ? "/" : remotePath;
return entity; return entity;
} }
/**
* 通过url获取FTP文件的remotePath
*
* @return remotePath如果没有找到返回""
*/
public static String getRemotePath(String url) {
String remotePath = null;
String regex = Regular.REG_FTP_URL;
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(url);
if (m.find() && m.groupCount() > 0) {
return TextUtils.isEmpty(m.group(4)) ? "" : "/" + m.group(4);
}
ALog.w(TAG, "链接【" + url + "】没有找到remotePath");
return "";
}
/** /**
* 转换Url * 转换Url
* *
@ -300,25 +277,27 @@ public class CommonUtil {
* @return 转换后的地址 * @return 转换后的地址
*/ */
public static String convertUrl(String url) { public static String convertUrl(String url) {
if (hasDoubleCharacter(url)) { Uri uri = Uri.parse(url);
//预先处理空格,URLEncoder只会把空格转换为+ url = uri.toString();
url = url.replaceAll(" ", "%20"); //if (hasDoubleCharacter(url)) {
//匹配双字节字符(包括汉字在内) // //预先处理空格,URLEncoder只会把空格转换为+
String regex = Regular.REG_DOUBLE_CHAR_AND_SPACE; // url = url.replaceAll(" ", "%20");
Pattern p = Pattern.compile(regex); // //匹配双字节字符(包括汉字在内)
Matcher m = p.matcher(url); // String regex = Regular.REG_DOUBLE_CHAR_AND_SPACE;
Set<String> strs = new HashSet<>(); // Pattern p = Pattern.compile(regex);
while (m.find()) { // Matcher m = p.matcher(url);
strs.add(m.group()); // Set<String> strs = new HashSet<>();
} // while (m.find()) {
try { // strs.add(m.group());
for (String str : strs) { // }
url = url.replaceAll(str, URLEncoder.encode(str, "UTF-8")); // try {
} // for (String str : strs) {
} catch (UnsupportedEncodingException e) { // url = url.replaceAll(str, URLEncoder.encode(str, "UTF-8"));
e.printStackTrace(); // }
} // } catch (UnsupportedEncodingException e) {
} // e.printStackTrace();
// }
//}
return url; return url;
} }

@ -5,15 +5,6 @@ package com.arialyy.aria.util;
* 正则表达式 * 正则表达式
*/ */
public interface Regular { public interface Regular {
/**
* ftp地址
*/
String REG_FTP_URL = "(\\w+)://(.*):(\\d*)/(.*)";
/**
* ftp主机用户密码分割
*/
String REG_FTP_HOST_NAME = "(\\w+):?(\\w+)?@(.*)";
/** /**
* 获取文件名 * 获取文件名

@ -126,8 +126,7 @@ protected void onCreate(Bundle savedInstanceState) {
## 其他 ## 其他
有任何问题,可以在[issues](https://github.com/AriaLyy/Aria/issues)给我留言反馈。</br> 有任何问题,可以在[issues](https://github.com/AriaLyy/Aria/issues)给我留言反馈。</br>
在提交问题前,希望你已经查看过[wiki](https://github.com/AriaLyy/Aria/wiki)或搜索过[issues](https://github.com/AriaLyy/Aria/issues)。</br> 在提交问题前,希望你已经查看过[wiki](https://aria.laoyuyu.me/aria_doc/)或搜索过[issues](https://github.com/AriaLyy/Aria/issues)。</br>
Aria交流群:524329160(加群条件:对aria有过star、commit、issues)
*** ***
License License

@ -14,8 +14,9 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
<!--android:name=".test.TestGroupActivity"--> <!--android:name=".test.TestGroupActivity"-->
<!--android:name=".test.TestActivity"-->
<!--android:name=".MainActivity"--> <!--android:name=".MainActivity"-->
<!--android:name=".download.group.DownloadGroupActivity"-->
<!--android:name=".test.TestActivity"-->
<activity <activity
android:name=".test.AnyRunActivity" android:name=".test.AnyRunActivity"
android:label="@string/app_name"> android:label="@string/app_name">
@ -33,7 +34,7 @@
<activity android:name=".download.multi_download.MultiDownloadActivity"/> <activity android:name=".download.multi_download.MultiDownloadActivity"/>
<activity android:name=".download.HighestPriorityActivity"/> <activity android:name=".download.HighestPriorityActivity"/>
<activity android:name=".test.TestMutilTaskSysDownload"/> <activity android:name=".test.TestMutilTaskSysDownload"/>
<activity android:name=".download.group.DownloadGroupActivity"/> <!--<activity android:name=".download.group.DownloadGroupActivity"/>-->
<activity android:name=".download.FtpDownloadActivity"/> <activity android:name=".download.FtpDownloadActivity"/>
<activity android:name=".download.group.FTPDirDownloadActivity"/> <activity android:name=".download.group.FTPDirDownloadActivity"/>
<activity android:name=".upload.HttpUploadActivity"/> <activity android:name=".upload.HttpUploadActivity"/>

@ -22,7 +22,7 @@
3、从3.4.1开始,如果线程数为1,文件初始化时将不再预占用对应长度的空间,下载多少byte,则占多大的空间; 3、从3.4.1开始,如果线程数为1,文件初始化时将不再预占用对应长度的空间,下载多少byte,则占多大的空间;
对于采用多线程的任务或旧任务,依然采用原来的文件空间占用方式; 对于采用多线程的任务或旧任务,依然采用原来的文件空间占用方式;
--> -->
<threadNum value="3"/> <threadNum value="1"/>
<!--设置下载队列最大任务数, 默认为2--> <!--设置下载队列最大任务数, 默认为2-->
<maxTaskNum value="2"/> <maxTaskNum value="2"/>

@ -84,7 +84,7 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
.setDirPath( .setDirPath(
Environment.getExternalStorageDirectory().getPath() + "/Download/group_test_3") Environment.getExternalStorageDirectory().getPath() + "/Download/group_test_3")
.setGroupAlias("任务组测试") .setGroupAlias("任务组测试")
.setSubFileName(getModule(GroupModule.class).getSubName()) //.setSubFileName(getModule(GroupModule.class).getSubName())
//.setFileSize(32895492) //.setFileSize(32895492)
.start(); .start();
break; break;
@ -92,7 +92,8 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
Aria.download(this).load(mUrls).stop(); Aria.download(this).load(mUrls).stop();
break; break;
case R.id.cancel: case R.id.cancel:
Aria.download(this).load(mUrls).cancel(true); //Aria.download(this).load(mUrls).cancel(true);
Aria.download(this).removeAllTask(true);
//mUrls = getModule(GroupModule.class).getUrls1(); //mUrls = getModule(GroupModule.class).getUrls1();
//Aria.download(this) //Aria.download(this)
// .load(mUrls) // .load(mUrls)

@ -19,11 +19,13 @@ public class AnyRunActivity extends BaseActivity<ActivityTestBinding> {
String[] urls; String[] urls;
int index = 0; int index = 0;
//String URL = "http://static.gaoshouyou.com/d/12/0d/7f120f50c80d2e7b8c4ba24ece4f9cdd.apk"; //String URL = "http://static.gaoshouyou.com/d/12/0d/7f120f50c80d2e7b8c4ba24ece4f9cdd.apk";
String URL = "http://58.213.157.242:8081/sims_file/rest/v1/file/mshd_touchscreen_ms/guideFile/41c33556-dc4a-4d78-bb76-b9f627f94448.mp4/%E5%85%AB%E5%8D%A6%E6%B4%B2%E5%8D%97%E4%BA%AC%E5%86%9C%E4%B8%9A%E5%98%89%E5%B9%B4%E5%8D%8E0511.mp4"; //String URL = "http://58.213.157.242:8081/sims_file/rest/v1/file/mshd_touchscreen_ms/guideFile/41c33556-dc4a-4d78-bb76-b9f627f94448.mp4/%E5%85%AB%E5%8D%A6%E6%B4%B2%E5%8D%97%E4%BA%AC%E5%86%9C%E4%B8%9A%E5%98%89%E5%B9%B4%E5%8D%8E0511.mp4";
//String URL = "http://d1.showself.com/download/showself_android-s236279_release.apk"; //String URL = "http://d1.showself.com/download/showself_android-s236279_release.apk";
//String URL = "http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk"; //String URL = "http://static.gaoshouyou.com/d/22/94/822260b849944492caadd2983f9bb624.apk";
//private final String URL = "ftp://192.168.29.140:21/download/AriaPrj.rar"; //private final String URL = "ftp://192.168.29.140:21/download/AriaPrj.rar";
//String URL = "https://dl.genymotion.com/releases/genymotion-2.12.1/genymotion-2.12.1-vbox.exe"; //String URL = "https://dl.genymotion.com/releases/genymotion-2.12.1/genymotion-2.12.1-vbox.exe";
//String URL = "ftp://192.168.29.140:21/download/SDK_Demo-release.apk";
String URL = "ftp://z:z@dygod18.com:21211/[电影天堂www.dy2018.com]猩球崛起3:终极之战BD国英双语中英双字.mkv";
@Override protected int setLayoutId() { @Override protected int setLayoutId() {
return R.layout.activity_test; return R.layout.activity_test;
@ -49,8 +51,8 @@ public class AnyRunActivity extends BaseActivity<ActivityTestBinding> {
//} //}
//for (int i = 0; i < 10; i++) { //for (int i = 0; i < 10; i++) {
//module.startFtp(URL); module.startFtp(URL);
module.start(URL); //module.start(URL);
//} //}
//List<AbsEntity> list = Aria.download(this).getTotalTaskList(); //List<AbsEntity> list = Aria.download(this).getTotalTaskList();
//ALog.d(TAG, "size ==> " + list.size()); //ALog.d(TAG, "size ==> " + list.size());

@ -1,5 +1,6 @@
package com.arialyy.simple.test; package com.arialyy.simple.test;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
@ -7,6 +8,7 @@ import com.arialyy.annotations.Upload;
import com.arialyy.aria.core.Aria; import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.RequestEnum; import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.upload.UploadTask; import com.arialyy.aria.core.upload.UploadTask;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import com.arialyy.simple.R; import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity; import com.arialyy.simple.base.BaseActivity;
@ -22,8 +24,8 @@ public class TestActivity extends BaseActivity<ActivityTestBinding> {
//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 URL = "ftp://192.168.1.3:21/download//AriaPrj.rar";
private final String FILE_PATH = "/mnt/sdcard/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 = "ftp://192.168.1.2:21/aa//你好";
private final String URL = "ftp://192.168.29.140:21/upload/";
@Override protected int setLayoutId() { @Override protected int setLayoutId() {
return R.layout.activity_test; return R.layout.activity_test;
@ -81,6 +83,8 @@ public class TestActivity extends BaseActivity<ActivityTestBinding> {
.setUploadUrl(URL) .setUploadUrl(URL)
.setExtendField("韩寒哈大双") .setExtendField("韩寒哈大双")
.start(); .start();
//Uri uri = Uri.parse("ftp://z:z@dygod18.com:21211/[电影天堂www.dy2018.com]猩球崛起3:终极之战BD国英双语中英双字.mkv");
//ALog.d(TAG, "sh = " + uri.getScheme() + ", user = " + uri.getUserInfo() + ", host = " + uri.getHost() + ", port = " + uri.getPort() + " remotePath = " + uri.getPath());
break; break;
case R.id.stop: case R.id.stop:
Aria.upload(this).loadFtp(FILE_PATH).stop(); Aria.upload(this).loadFtp(FILE_PATH).stop();

@ -1,6 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.arialyy.aria"> package="com.arialyy.aria">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application <application
android:allowBackup="true" android:allowBackup="true"
android:supportsRtl="true"> android:supportsRtl="true">

Loading…
Cancel
Save