修复线程重启的导致下载失败的一个问题,https://github.com/AriaLyy/Aria/issues/160

pull/330/head
AriaLyy 7 years ago
parent ec1b504309
commit a310df2281
  1. 53
      Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java
  2. 24
      Aria/src/main/java/com/arialyy/aria/core/common/AbsThreadTask.java
  3. 2
      Aria/src/main/java/com/arialyy/aria/core/common/StateConstance.java
  4. 6
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java
  5. 6
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java
  6. 4
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java
  7. 8
      Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java
  8. 2
      app/src/main/assets/aria_config.xml
  9. 2
      app/src/main/java/com/arialyy/simple/download/FtpDownloadActivity.java
  10. 4
      app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java

@ -40,7 +40,7 @@ import java.util.concurrent.Executors;
*/ */
public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>> public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>>
implements Runnable, IUtil { implements Runnable, IUtil {
private final String TAG = "Downloader"; private final String TAG = "AbsFileer";
protected IEventListener mListener; protected IEventListener mListener;
protected TASK_ENTITY mTaskEntity; protected TASK_ENTITY mTaskEntity;
protected ENTITY mEntity; protected ENTITY mEntity;
@ -50,7 +50,12 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
protected boolean isNewTask = true; protected boolean isNewTask = true;
protected StateConstance mConstance; protected StateConstance mConstance;
private ExecutorService mFixedThreadPool; private ExecutorService mFixedThreadPool;
private int mThreadNum, mRealThreadNum; //总线程数
private int mTotalThreadNum;
//启动线程数
private int mStartThreadNum;
//已完成的线程数
private int mCompleteThreadNum;
private SparseArray<AbsThreadTask> mTask = new SparseArray<>(); private SparseArray<AbsThreadTask> mTask = new SparseArray<>();
/** /**
@ -72,7 +77,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
} }
@Override public void setMaxSpeed(double maxSpeed) { @Override public void setMaxSpeed(double maxSpeed) {
for (int i = 0; i < mThreadNum; i++) { for (int i = 0; i < mTotalThreadNum; i++) {
AbsThreadTask task = mTask.get(i); AbsThreadTask task = mTask.get(i);
if (task != null) { if (task != null) {
task.setMaxSpeed(maxSpeed); task.setMaxSpeed(maxSpeed);
@ -101,12 +106,13 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
((IDownloadListener) mListener).onPostPre(mEntity.getFileSize()); ((IDownloadListener) mListener).onPostPre(mEntity.getFileSize());
} }
if (!mTaskEntity.isSupportBP) { if (!mTaskEntity.isSupportBP) {
mThreadNum = 1; mTotalThreadNum = 1;
mConstance.THREAD_NUM = mThreadNum; mStartThreadNum = 1;
mConstance.THREAD_NUM = mTotalThreadNum;
handleNoSupportBP(); handleNoSupportBP();
} else { } else {
mThreadNum = isNewTask ? (getNewTaskThreadNum()) : mRealThreadNum; mTotalThreadNum = isNewTask ? (getNewTaskThreadNum()) : mStartThreadNum + mCompleteThreadNum;
mConstance.THREAD_NUM = mThreadNum; mConstance.THREAD_NUM = mTotalThreadNum;
handleBreakpoint(); handleBreakpoint();
} }
startTimer(); startTimer();
@ -116,8 +122,8 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
* 设置新任务的最大线程数 * 设置新任务的最大线程数
*/ */
protected int getNewTaskThreadNum() { protected int getNewTaskThreadNum() {
return mEntity.getFileSize() <= SUB_LEN || mTaskEntity.requestType == AbsTaskEntity.D_FTP_DIR ? 1 return mEntity.getFileSize() <= SUB_LEN || mTaskEntity.requestType == AbsTaskEntity.D_FTP_DIR
: AriaManager.getInstance(mContext).getDownloadConfig().getThreadNum(); ? 1 : AriaManager.getInstance(mContext).getDownloadConfig().getThreadNum();
} }
/** /**
@ -169,7 +175,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
if (mFixedThreadPool != null) { if (mFixedThreadPool != null) {
mFixedThreadPool.shutdown(); mFixedThreadPool.shutdown();
} }
for (int i = 0; i < mThreadNum; i++) { for (int i = 0; i < mStartThreadNum; i++) {
AbsThreadTask task = mTask.get(i); AbsThreadTask task = mTask.get(i);
if (task != null) { if (task != null) {
task.cancel(); task.cancel();
@ -190,7 +196,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
if (mFixedThreadPool != null) { if (mFixedThreadPool != null) {
mFixedThreadPool.shutdown(); mFixedThreadPool.shutdown();
} }
for (int i = 0; i < mThreadNum; i++) { for (int i = 0; i < mStartThreadNum; i++) {
AbsThreadTask task = mTask.get(i); AbsThreadTask task = mTask.get(i);
if (task != null) { if (task != null) {
task.stop(); task.stop();
@ -230,6 +236,8 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
* 检查记录文件如果是新任务返回{@code true}否则返回{@code false} * 检查记录文件如果是新任务返回{@code true}否则返回{@code false}
*/ */
protected boolean checkConfigFile() { protected boolean checkConfigFile() {
mStartThreadNum = 0;
mCompleteThreadNum = 0;
Properties pro = CommonUtil.loadConfig(mConfigFile); Properties pro = CommonUtil.loadConfig(mConfigFile);
if (pro.isEmpty()) { if (pro.isEmpty()) {
return true; return true;
@ -237,15 +245,18 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
Set<Object> keys = pro.keySet(); Set<Object> keys = pro.keySet();
int num = 0; int num = 0;
for (Object key : keys) { for (Object key : keys) {
if (String.valueOf(key).contains("_record_")) { String str = String.valueOf(key);
if (str.contains("_record_")) {
num++; num++;
} else if (str.contains("_state_")) {
mCompleteThreadNum++;
} }
} }
if (num == 0) { if (num == 0) {
return true; return true;
} }
mRealThreadNum = num; mStartThreadNum = num;
for (int i = 0; i < mRealThreadNum; i++) { for (int i = 0; i < mStartThreadNum; i++) {
if (pro.getProperty(mTempFile.getName() + "_record_" + i) == null) { if (pro.getProperty(mTempFile.getName() + "_record_" + i) == null) {
Object state = pro.getProperty(mTempFile.getName() + "_state_" + i); Object state = pro.getProperty(mTempFile.getName() + "_state_" + i);
if (state != null && Integer.parseInt(state + "") == 1) { if (state != null && Integer.parseInt(state + "") == 1) {
@ -264,8 +275,8 @@ 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, "++++++++++ 线程_" + i + "_已经下载完成 ++++++++++"); ALog.d(TAG, "任务【" + mTaskEntity.getEntity().getFileName() + "】线程__" + i + "__已完成");
mConstance.COMPLETE_THREAD_NUM++; mConstance.COMPLETE_THREAD_NUM = mCompleteThreadNum;
mConstance.STOP_NUM++; mConstance.STOP_NUM++;
mConstance.CANCEL_NUM++; mConstance.CANCEL_NUM++;
if (mConstance.isComplete()) { if (mConstance.isComplete()) {
@ -307,16 +318,16 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
private void handleBreakpoint() { private void handleBreakpoint() {
long fileLength = mEntity.getFileSize(); long fileLength = mEntity.getFileSize();
Properties pro = CommonUtil.loadConfig(mConfigFile); Properties pro = CommonUtil.loadConfig(mConfigFile);
long blockSize = fileLength / mThreadNum; long blockSize = fileLength / mTotalThreadNum;
int[] recordL = new int[mThreadNum]; int[] recordL = new int[mTotalThreadNum];
for (int i = 0; i < mThreadNum; i++) { for (int i = 0; i < mTotalThreadNum; i++) {
recordL[i] = -1; recordL[i] = -1;
} }
int rl = 0; int rl = 0;
if (isNewTask) { if (isNewTask) {
handleNewTask(); handleNewTask();
} }
for (int i = 0; i < mThreadNum; i++) { for (int i = 0; i < mTotalThreadNum; i++) {
long startL = i * blockSize, endL = (i + 1) * blockSize; long startL = i * blockSize, endL = (i + 1) * blockSize;
Object state = pro.getProperty(mTempFile.getName() + "_state_" + i); Object state = pro.getProperty(mTempFile.getName() + "_state_" + i);
if (state != null && Integer.parseInt(state + "") == 1) { //该线程已经完成 if (state != null && Integer.parseInt(state + "") == 1) { //该线程已经完成
@ -339,7 +350,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
recordL[rl] = i; recordL[rl] = i;
rl++; rl++;
} }
if (i == (mThreadNum - 1)) { if (i == (mTotalThreadNum - 1)) {
//最后一个线程的结束位置即为文件的总长度 //最后一个线程的结束位置即为文件的总长度
endL = fileLength; endL = fileLength;
} }

@ -42,7 +42,7 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
/** /**
* 线程重试次数 * 线程重试次数
*/ */
private final int RETRY_NUM = 5; private final int RETRY_NUM = 2;
/** /**
* 线程重试间隔 * 线程重试间隔
*/ */
@ -108,7 +108,8 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
+ "】thread__" + "】thread__"
+ mConfig.THREAD_ID + mConfig.THREAD_ID
+ "__停止【停止位置: " + "__停止【停止位置: "
+ currentTemp + "】"); + currentTemp
+ "】");
writeConfig(false, currentTemp); writeConfig(false, currentTemp);
if (STATE.isStop()) { if (STATE.isStop()) {
ALog.i(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】已停止"); ALog.i(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】已停止");
@ -134,7 +135,8 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
mChildCurrentLocation += len; mChildCurrentLocation += len;
STATE.CURRENT_LOCATION += len; STATE.CURRENT_LOCATION += len;
//mIncrement += len; //mIncrement += len;
if (System.currentTimeMillis() - mLastSaveTime > 5000) { if (System.currentTimeMillis() - mLastSaveTime > 5000
&& mChildCurrentLocation < mConfig.END_LOCATION) {
mLastSaveTime = System.currentTimeMillis(); mLastSaveTime = System.currentTimeMillis();
new Thread(new Runnable() { new Thread(new Runnable() {
@Override public void run() { @Override public void run() {
@ -209,15 +211,15 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY
* @param needRetry 是否可以重试 * @param needRetry 是否可以重试
*/ */
private void retryThis(boolean needRetry) { private void retryThis(boolean needRetry) {
if (mFailTimer != null) {
mFailTimer.purge();
mFailTimer.cancel();
}
if (!NetUtils.isConnected(AriaManager.APP)) { if (!NetUtils.isConnected(AriaManager.APP)) {
ALog.w(TAG, ALog.w(TAG,
"任务【" + mConfig.TEMP_FILE.getName() + "】thread__" + mConfig.THREAD_ID + "__重试失败,网络未连接"); "任务【" + mConfig.TEMP_FILE.getName() + "】thread__" + mConfig.THREAD_ID + "__重试失败,网络未连接");
} }
if (mFailNum < RETRY_NUM && needRetry && NetUtils.isConnected(AriaManager.APP)) { if (mFailNum < RETRY_NUM && needRetry && NetUtils.isConnected(AriaManager.APP)) {
if (mFailTimer != null) {
mFailTimer.purge();
mFailTimer.cancel();
}
mFailTimer = new Timer(true); mFailTimer = new Timer(true);
mFailTimer.schedule(new TimerTask() { mFailTimer.schedule(new TimerTask() {
@Override public void run() { @Override public void run() {
@ -247,12 +249,12 @@ 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) {
String key = null, value = null; String key = null, value = null;
if (0 < record && record < mConfig.END_LOCATION) { if (record >= mConfig.END_LOCATION || isComplete) {
key = mConfig.TEMP_FILE.getName() + "_record_" + mConfig.THREAD_ID;
value = String.valueOf(record);
} else if (record >= mConfig.END_LOCATION || isComplete) {
key = mConfig.TEMP_FILE.getName() + "_state_" + mConfig.THREAD_ID; key = mConfig.TEMP_FILE.getName() + "_state_" + mConfig.THREAD_ID;
value = "1"; value = "1";
} else if (0 < record && record < mConfig.END_LOCATION) {
key = mConfig.TEMP_FILE.getName() + "_record_" + mConfig.THREAD_ID;
value = String.valueOf(record);
} }
if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) { if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
File configFile = new File(mConfigFPath); File configFile = new File(mConfigFPath);

@ -56,7 +56,7 @@ public class StateConstance {
* 所有子线程是否都已经下载失败 * 所有子线程是否都已经下载失败
*/ */
public boolean isFail() { public boolean isFail() {
return FAIL_NUM + COMPLETE_THREAD_NUM >= THREAD_NUM; return COMPLETE_THREAD_NUM != THREAD_NUM && FAIL_NUM + COMPLETE_THREAD_NUM >= THREAD_NUM;
} }
/** /**

@ -76,7 +76,7 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
int len; int len;
while ((len = is.read(buffer)) != -1) { while ((len = is.read(buffer)) != -1) {
if (STATE.isCancel || STATE.isStop){ if (STATE.isCancel || STATE.isStop) {
break; break;
} }
if (mSleepTime > 0) Thread.sleep(mSleepTime); if (mSleepTime > 0) Thread.sleep(mSleepTime);
@ -102,6 +102,10 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
STATE.isRunning = false; STATE.isRunning = false;
mListener.onComplete(); mListener.onComplete();
} }
if (STATE.isFail()) {
STATE.isRunning = false;
mListener.onFail(false);
}
} catch (IOException e) { } catch (IOException e) {
fail(mChildCurrentLocation, "下载失败【" + mConfig.URL + "】", e); fail(mChildCurrentLocation, "下载失败【" + mConfig.URL + "】", e);
} catch (Exception e) { } catch (Exception e) {

@ -100,8 +100,12 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
STATE.isRunning = false; STATE.isRunning = false;
mListener.onComplete(); mListener.onComplete();
} }
if (STATE.isFail()){
STATE.isRunning = false;
mListener.onFail(false);
}
} else { } else {
ALog.i(TAG, "下载任务完成"); ALog.i(TAG, "任务下载完成");
STATE.isRunning = false; STATE.isRunning = false;
mListener.onComplete(); mListener.onComplete();
} }

@ -82,6 +82,10 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
STATE.isRunning = false; STATE.isRunning = false;
mListener.onComplete(); mListener.onComplete();
} }
if (STATE.isFail()){
STATE.isRunning = false;
mListener.onFail(false);
}
} catch (IOException e) { } catch (IOException e) {
fail(mChildCurrentLocation, "上传失败【" + mConfig.URL + "】", e); fail(mChildCurrentLocation, "上传失败【" + mConfig.URL + "】", e);
} catch (Exception e) { } catch (Exception e) {

@ -30,7 +30,6 @@ import com.arialyy.aria.core.command.group.GroupCmdFactory;
import com.arialyy.aria.core.command.normal.AbsNormalCmd; import com.arialyy.aria.core.command.normal.AbsNormalCmd;
import com.arialyy.aria.core.command.normal.NormalCmdFactory; import com.arialyy.aria.core.command.normal.NormalCmdFactory;
import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.download.DownloadGroupTaskEntity; import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.AbsGroupTaskEntity; import com.arialyy.aria.core.inf.AbsGroupTaskEntity;
@ -148,7 +147,6 @@ public class CommonUtil {
for (String str : strs) { for (String str : strs) {
url = url.replaceAll(str, URLEncoder.encode(str, "UTF-8")); url = url.replaceAll(str, URLEncoder.encode(str, "UTF-8"));
} }
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -284,7 +282,6 @@ public class CommonUtil {
*/ */
public static void delDownloadGroupTaskConfig(boolean removeFile, public static void delDownloadGroupTaskConfig(boolean removeFile,
DownloadGroupTaskEntity tEntity) { DownloadGroupTaskEntity tEntity) {
DownloadGroupEntity entity = tEntity.getEntity();
List<DownloadTaskEntity> tasks = List<DownloadTaskEntity> tasks =
DbEntity.findDatas(DownloadTaskEntity.class, "groupName=?", tEntity.key); DbEntity.findDatas(DownloadTaskEntity.class, "groupName=?", tEntity.key);
if (tasks != null && !tasks.isEmpty()) { if (tasks != null && !tasks.isEmpty()) {
@ -293,6 +290,7 @@ public class CommonUtil {
} }
} }
if (tEntity.getEntity() != null) {
File dir = new File(tEntity.getEntity().getDirPath()); File dir = new File(tEntity.getEntity().getDirPath());
if (removeFile) { if (removeFile) {
if (dir.exists()) { if (dir.exists()) {
@ -305,6 +303,7 @@ public class CommonUtil {
} }
tEntity.deleteData(); tEntity.deleteData();
} }
}
/** /**
* 删除上传任务的配置 * 删除上传任务的配置
@ -314,6 +313,9 @@ public class CommonUtil {
*/ */
public static void delUploadTaskConfig(boolean removeFile, UploadTaskEntity tEntity) { public static void delUploadTaskConfig(boolean removeFile, UploadTaskEntity tEntity) {
UploadEntity uEntity = tEntity.getEntity(); UploadEntity uEntity = tEntity.getEntity();
if (uEntity == null) {
return;
}
File file = new File(uEntity.getFilePath()); File file = new File(uEntity.getFilePath());
if (removeFile) { if (removeFile) {
if (file.exists()) { if (file.exists()) {

@ -5,7 +5,7 @@
<download> <download>
<!--设置下载线程,线程下载数改变后,新的下载任务才会生效,如果任务大小小于1m,该设置也不会生效--> <!--设置下载线程,线程下载数改变后,新的下载任务才会生效,如果任务大小小于1m,该设置也不会生效-->
<threadNum value="1"/> <threadNum value="3"/>
<!--设置下载队列最大任务数, 默认为2--> <!--设置下载队列最大任务数, 默认为2-->
<maxTaskNum value="2"/> <maxTaskNum value="2"/>

@ -38,7 +38,7 @@ public class FtpDownloadActivity extends BaseActivity<ActivityFtpDownloadBinding
//private final String URL = "ftp://192.168.1.9:21/下载/AriaPrj.zip"; //private final String URL = "ftp://192.168.1.9:21/下载/AriaPrj.zip";
//private final String URL = "ftp://192.168.1.9:21/下载/[电影天堂www.dy2018.com]赛车总动员3BD中英双字.mp4"; //private final String URL = "ftp://192.168.1.9:21/下载/[电影天堂www.dy2018.com]赛车总动员3BD中英双字.mp4";
//private final String URL = "ftp://h:h@tv.dl1234.com:2199/付岩洞复仇者们05.mkv"; //private final String URL = "ftp://h:h@tv.dl1234.com:2199/付岩洞复仇者们05.mkv";
private final String URL = "ftp://z:z@dygod18.com:21211/[电影天堂www.dy2018.com]英格丽向西行BD中英双字.mp4"; private final String URL = "ftp://z:z@dygod18.com:21211/[破晓电影www.poxiao.com]情遇曼哈顿HD国语中字.mkv";
//private final String URL = "ftp://172.18.104.71:21/upload/AS.zip"; //private final String URL = "ftp://172.18.104.71:21/upload/AS.zip";
@Override protected void init(Bundle savedInstanceState) { @Override protected void init(Bundle savedInstanceState) {

@ -48,7 +48,7 @@ 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";
@ -59,7 +59,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
//不支持断点的链接 //不支持断点的链接
//"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";
//"http://gdown.baidu.com/data/wisegame/0904344dee4a2d92/QQ_718.apk"; "http://gdown.baidu.com/data/wisegame/0904344dee4a2d92/QQ_718.apk";
//"http://172.21.1.99:8080/download/test+ 中文123.zip"; //"http://172.21.1.99:8080/download/test+ 中文123.zip";
@Bind(R.id.start) Button mStart; @Bind(R.id.start) Button mStart;
@Bind(R.id.stop) Button mStop; @Bind(R.id.stop) Button mStop;

Loading…
Cancel
Save