删除记录bug修复;动态文件长度实现修改;

pull/330/head
laoyuyu 7 years ago
parent 08d705c3f9
commit 76bf0a33a9
  1. 9
      Aria/src/main/java/com/arialyy/aria/core/ConfigHelper.java
  2. 29
      Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java
  3. 5
      Aria/src/main/java/com/arialyy/aria/core/common/StateConstance.java
  4. 6
      Aria/src/main/java/com/arialyy/aria/core/common/TaskRecord.java
  5. 12
      Aria/src/main/java/com/arialyy/aria/core/download/BaseDListener.java
  6. 9
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/Downloader.java
  7. 127
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java
  8. 67
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java
  9. 2
      Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java
  10. 9
      Aria/src/main/java/com/arialyy/aria/core/upload/BaseUListener.java
  11. 5
      Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java
  12. 4
      app/src/main/AndroidManifest.xml
  13. 14
      app/src/main/assets/aria_config.xml
  14. 7
      app/src/main/java/com/arialyy/simple/test/AnyRunActivity.java
  15. 2
      app/src/main/java/com/arialyy/simple/test/AnyRunnModule.java
  16. 25
      aria/src/main/java/com/arialyy/aria/core/Configuration.java

@ -59,9 +59,6 @@ class ConfigHelper extends DefaultHandler {
String value = attributes.getValue("value");
switch (qName) {
case "openDynamicFile":
loadOpenDynamicFile(value);
break;
case "threadNum":
loadThreadNum(value);
break;
@ -117,12 +114,6 @@ class ConfigHelper extends DefaultHandler {
}
}
private void loadOpenDynamicFile(String value) {
if (isDownloadConfig) {
mDownloadConfig.openDynamicFile = checkBoolean(value) ? Boolean.valueOf(value) : false;
}
}
private void loadNotNetRetry(String value) {
if (isDownloadConfig) {
mDownloadConfig.notNetRetry = checkBoolean(value) ? Boolean.valueOf(value) : false;

@ -44,8 +44,11 @@ import java.util.concurrent.Executors;
*/
public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>>
implements Runnable, IUtil {
public static final String STATE = "_state_";
public static final String RECORD = "_record_";
private static final String STATE = "_state_";
private static final String RECORD = "_record_";
/**
* 小于1m的文件不启用多线程
*/
protected static final long SUB_LEN = 1024 * 1024;
private final String TAG = "AbsFileer";
@ -57,16 +60,14 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
protected StateConstance mConstance;
private ExecutorService mFixedThreadPool;
//总线程数
private int mTotalThreadNum;
protected int mTotalThreadNum;
//启动线程数
private int mStartThreadNum;
//已完成的线程数
private int mCompleteThreadNum;
private SparseArray<AbsThreadTask> mTask = new SparseArray<>();
/**
* 小于1m的文件不启用多线程
*/
private Timer mTimer;
@Deprecated
private File mConfigFile;
@ -74,7 +75,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
* 进度刷新间隔
*/
private long mUpdateInterval = 1000;
protected TaskRecord mRecord;
private TaskRecord mRecord;
protected AbsFileer(IEventListener listener, TASK_ENTITY taskEntity) {
mListener = listener;
@ -124,6 +125,16 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
handleBreakpoint();
}
mConstance.START_THREAD_NUM = mTotalThreadNum;
/*
* mTaskEntity.getEntity().getFileSize() != mTempFile.length()为兼容以前老版本代码
* 动态长度条件
* 1总线程数为1并且是新任务
* 2总线程数为1不是新任务但是长度不是文件全长度
*/
if (mTotalThreadNum == 1 && (mTaskEntity.isNewTask()
|| mTaskEntity.getEntity().getFileSize() != mTempFile.length())) {
mConstance.isOpenDynamicFile = true;
}
startTimer();
}
@ -237,7 +248,7 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
* 3数据库记录不存在
* 4不支持断点则是新任务
*/
protected void checkTask() {
private void checkTask() {
mConfigFile = new File(CommonUtil.getFileConfigPath(false, mEntity.getFileName()));
if (mConfigFile.exists()) {
convertDb();
@ -334,8 +345,6 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_ENTITY exte
mRecord.filePath = mTaskEntity.getKey();
mRecord.threadRecords = new ArrayList<>();
mRecord.isGroupRecord = mTaskEntity.getEntity().isGroupChild();
mRecord.isOpenDynamicFile =
AriaManager.getInstance(AriaManager.APP).getDownloadConfig().isOpenDynamicFile();
if (mRecord.isGroupRecord) {
if (mTaskEntity.getEntity() instanceof DownloadEntity) {
mRecord.dGroupName = ((DownloadEntity) mTaskEntity.getEntity()).getGroupName();

@ -30,6 +30,11 @@ public class StateConstance {
public boolean isCancel = false;
public boolean isStop = false;
public TaskRecord TASK_RECORD;
/**
* 是否是使用虚拟文件下载的
* {@code true}{@code false}不是
*/
public boolean isOpenDynamicFile = false;
public StateConstance() {
}

@ -73,10 +73,4 @@ public class TaskRecord extends DbEntity {
@Ignore
@Deprecated
public String uGroupName;
/**
* 是否是使用虚拟文件下载的
* {@code true}{@code false}不是
*/
public boolean isOpenDynamicFile = false;
}

@ -19,8 +19,6 @@ import android.os.Handler;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.TaskRecord;
import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.AbsGroupEntity;
import com.arialyy.aria.core.inf.AbsNormalEntity;
import com.arialyy.aria.core.inf.AbsTask;
import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IDownloadListener;
@ -158,14 +156,16 @@ class BaseDListener<ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity<
mEntity.setState(state);
mEntity.setComplete(state == IEntity.STATE_COMPLETE);
if (state == IEntity.STATE_CANCEL) {
if (mEntity instanceof AbsNormalEntity) {
if (mEntity instanceof DownloadEntity) {
TaskRecord record =
DbEntity.findFirst(TaskRecord.class, "TaskRecord.filePath=?", mTaskEntity.getKey());
if (record != null) {
CommonUtil.delTaskRecord(record, mTaskEntity.isRemoveFile(), (AbsNormalEntity) mEntity);
CommonUtil.delTaskRecord(record, mTaskEntity.isRemoveFile(), (DownloadEntity) mEntity);
} else {
mEntity.deleteData();
}
} else if (mEntity instanceof AbsGroupEntity) {
CommonUtil.delGroupTaskRecord(mTaskEntity.isRemoveFile(), ((AbsGroupEntity) mEntity));
} else if (mEntity instanceof DownloadGroupEntity) {
CommonUtil.delGroupTaskRecord(mTaskEntity.isRemoveFile(), ((DownloadGroupEntity) mEntity));
}
//mEntity.deleteData();
return;

@ -45,23 +45,26 @@ class Downloader extends AbsFileer<DownloadEntity, DownloadTaskEntity> {
}
@Override protected int setNewTaskThreadNum() {
int threadNum = AriaManager.getInstance(mContext).getDownloadConfig().getThreadNum();
return
// 小于1m的文件或是任务组的子任务、使用虚拟文件,线程数都是1
mEntity.getFileSize() <= SUB_LEN
|| mTaskEntity.getRequestType() == AbsTaskEntity.D_FTP_DIR
|| mTaskEntity.getRequestType() == AbsTaskEntity.DG_HTTP
|| mRecord.isOpenDynamicFile
|| threadNum == 1
? 1
: AriaManager.getInstance(mContext).getDownloadConfig().getThreadNum();
: threadNum;
}
@Override protected boolean handleNewTask() {
CommonUtil.createFile(mTempFile.getPath());
BufferedRandomAccessFile file = null;
try {
if (mTotalThreadNum > 1) {
file = new BufferedRandomAccessFile(new File(mTempFile.getPath()), "rwd", 8192);
//设置文件长度
file.setLength(mRecord.isOpenDynamicFile ? 1 : mEntity.getFileSize());
file.setLength(mEntity.getFileSize());
}
return true;
} catch (IOException e) {
failDownload("下载失败【downloadUrl:"

@ -24,8 +24,13 @@ import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.IDownloadListener;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.BufferedRandomAccessFile;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
@ -36,10 +41,6 @@ import org.apache.commons.net.ftp.FTPReply;
class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity> {
private final String TAG = "FtpThreadTask";
private boolean isOpenDynamicFile;
/**
* 2M的动态长度
*/
private final int LEN_INTERVAL = 1024 * 1024 * 2;
FtpThreadTask(StateConstance constance, IDownloadListener listener,
SubThreadConfig<DownloadTaskEntity> downloadInfo) {
@ -49,7 +50,7 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
mReadTimeOut = manager.getDownloadConfig().getIOTimeOut();
mBufSize = manager.getDownloadConfig().getBuffSize();
isNotNetRetry = manager.getDownloadConfig().isNotNetRetry();
isOpenDynamicFile = STATE.TASK_RECORD.isOpenDynamicFile;
isOpenDynamicFile = STATE.isOpenDynamicFile;
setMaxSpeed(manager.getDownloadConfig().getMaxSpeed());
}
@ -58,7 +59,7 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
mChildCurrentLocation = mConfig.START_LOCATION;
FTPClient client = null;
InputStream is = null;
BufferedRandomAccessFile file = null;
try {
ALog.d(TAG, "任务【"
+ mConfig.TEMP_FILE.getName()
@ -94,31 +95,12 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
return;
}
file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", mBufSize);
file.seek(mConfig.START_LOCATION);
byte[] buffer = new byte[mBufSize];
int len;
while ((len = is.read(buffer)) != -1) {
if (STATE.isCancel || STATE.isStop) {
break;
}
if (mSleepTime > 0) Thread.sleep(mSleepTime);
if (isOpenDynamicFile) {
file.setLength(
STATE.CURRENT_LOCATION + LEN_INTERVAL < mEntity.getFileSize() ? STATE.CURRENT_LOCATION
+ LEN_INTERVAL : mEntity.getFileSize());
}
if (mChildCurrentLocation + len >= mConfig.END_LOCATION) {
len = (int) (mConfig.END_LOCATION - mChildCurrentLocation);
file.write(buffer, 0, len);
progress(len);
break;
readDynamicFile(is);
} else {
file.write(buffer, 0, len);
progress(len);
}
readNormal(is);
}
if (STATE.isCancel || STATE.isStop) return;
ALog.i(TAG, "任务【" + mConfig.TEMP_FILE.getName() + "】线程__" + mConfig.THREAD_ID + "__下载完毕");
writeConfig(true, 1);
@ -138,9 +120,6 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
fail(mChildCurrentLocation, "获取流失败", e);
} finally {
try {
if (file != null) {
file.close();
}
if (is != null) {
is.close();
}
@ -153,6 +132,92 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
}
}
/**
* 动态长度文件读取方式
*/
private void readDynamicFile(InputStream is) {
FileOutputStream fos = null;
FileChannel foc = null;
ReadableByteChannel fic = null;
try {
int len;
fos = new FileOutputStream(mConfig.TEMP_FILE, true);
foc = fos.getChannel();
fic = Channels.newChannel(is);
ByteBuffer bf = ByteBuffer.allocate(mBufSize);
while ((len = fic.read(bf)) != -1) {
if (STATE.isCancel || STATE.isStop) {
break;
}
if (mSleepTime > 0) {
Thread.sleep(mSleepTime);
}
bf.flip();
foc.write(bf);
bf.compact();
progress(len);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
fail(mChildCurrentLocation, "下载失败【" + mConfig.URL + "】", e);
} finally {
try {
if (fos != null) {
fos.close();
}
if (foc != null) {
foc.close();
}
if (fic != null) {
fic.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 多线程写文件方式
*/
private void readNormal(InputStream is) {
BufferedRandomAccessFile file = null;
try {
file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", mBufSize);
file.seek(mConfig.START_LOCATION);
byte[] buffer = new byte[mBufSize];
int len;
while ((len = is.read(buffer)) != -1) {
if (STATE.isCancel || STATE.isStop) {
break;
}
if (mSleepTime > 0) Thread.sleep(mSleepTime);
if (mChildCurrentLocation + len >= mConfig.END_LOCATION) {
len = (int) (mConfig.END_LOCATION - mChildCurrentLocation);
file.write(buffer, 0, len);
progress(len);
break;
} else {
file.write(buffer, 0, len);
progress(len);
}
}
} catch (IOException e) {
fail(mChildCurrentLocation, "下载失败【" + mConfig.URL + "】", e);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
if (file != null) {
file.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override protected String getTaskType() {
return "FTP_DOWNLOAD";
}

@ -26,11 +26,16 @@ import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.BufferedRandomAccessFile;
import com.arialyy.aria.util.CommonUtil;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
/**
* Created by lyy on 2017/1/18.
@ -38,10 +43,6 @@ import java.net.URL;
*/
final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEntity> {
private final String TAG = "HttpThreadTask";
/**
* 2M的动态长度
*/
private final int LEN_INTERVAL = 1024 * 1024 * 2;
private boolean isOpenDynamicFile;
HttpThreadTask(StateConstance constance, IDownloadListener listener,
@ -52,7 +53,7 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
mReadTimeOut = manager.getDownloadConfig().getIOTimeOut();
mBufSize = manager.getDownloadConfig().getBuffSize();
isNotNetRetry = manager.getDownloadConfig().isNotNetRetry();
isOpenDynamicFile = STATE.TASK_RECORD.isOpenDynamicFile;
isOpenDynamicFile = STATE.isOpenDynamicFile;
setMaxSpeed(manager.getDownloadConfig().getMaxSpeed());
}
@ -86,16 +87,19 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
conn.setReadTimeout(mReadTimeOut); //设置读取流的等待时间,必须设置该参数
is = new BufferedInputStream(ConnectionHelp.convertInputStream(conn));
if (isOpenDynamicFile) {
readDynamicFile(is);
} else {
//创建可设置位置的文件
file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", mBufSize);
//设置每条线程写入文件的位置
file.seek(mConfig.START_LOCATION);
if (mTaskEntity.isChunked()) {
readChunk(is, file);
} else {
readNormal(is, file);
}
}
if (STATE.isCancel || STATE.isStop) {
return;
@ -124,6 +128,52 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
}
}
/**
* 动态长度文件读取方式
*/
private void readDynamicFile(InputStream is) {
FileOutputStream fos = null;
FileChannel foc = null;
ReadableByteChannel fic = null;
try {
int len;
fos = new FileOutputStream(mConfig.TEMP_FILE, true);
foc = fos.getChannel();
fic = Channels.newChannel(is);
ByteBuffer bf = ByteBuffer.allocate(mBufSize);
while ((len = fic.read(bf)) != -1) {
if (STATE.isCancel || STATE.isStop) {
break;
}
if (mSleepTime > 0) {
Thread.sleep(mSleepTime);
}
bf.flip();
foc.write(bf);
bf.compact();
progress(len);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
fail(mChildCurrentLocation, "下载失败【" + mConfig.URL + "】", e);
} finally {
try {
if (fos != null) {
fos.close();
}
if (foc != null) {
foc.close();
}
if (fic != null) {
fic.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 读取chunk模式的文件流
*
@ -148,11 +198,6 @@ final class HttpThreadTask extends AbsThreadTask<DownloadEntity, DownloadTaskEnt
if (mSleepTime > 0) {
Thread.sleep(mSleepTime);
}
if (isOpenDynamicFile) {
file.setLength(
STATE.CURRENT_LOCATION + LEN_INTERVAL < mEntity.getFileSize() ? STATE.CURRENT_LOCATION
+ LEN_INTERVAL : mEntity.getFileSize());
}
file.write(buffer, 0, len);
progress(len);
}

@ -311,7 +311,9 @@ abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskEntity, TASK extends Abs
private void startNextTask() {
TASK newTask = mQueue.getNextTask();
if (newTask == null) {
if (mQueue.getCurrentExePoolNum() == 0) {
ALog.i(TAG, "没有下一任务");
}
return;
}
if (newTask.getState() == IEntity.STATE_WAIT) {

@ -144,15 +144,16 @@ class BaseUListener<ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity<
mEntity.setState(state);
mEntity.setComplete(state == IEntity.STATE_COMPLETE);
if (state == IEntity.STATE_CANCEL) {
if (mEntity instanceof AbsNormalEntity) {
if (mEntity instanceof UploadEntity) {
TaskRecord record =
DbEntity.findFirst(TaskRecord.class, "TaskRecord.filePath=?", mTaskEntity.getKey());
if (record != null) {
CommonUtil.delTaskRecord(record, mTaskEntity.isRemoveFile(), (AbsNormalEntity) mEntity);
CommonUtil.delTaskRecord(record, mTaskEntity.isRemoveFile(), (UploadEntity) mEntity);
}
} else if (mEntity instanceof AbsGroupEntity) {
CommonUtil.delGroupTaskRecord(mTaskEntity.isRemoveFile(), ((AbsGroupEntity) mEntity));
}
//else if (mEntity instanceof AbsGroupEntity) {
// CommonUtil.delGroupTaskRecord(mTaskEntity.isRemoveFile(), ((AbsGroupEntity) mEntity));
//}
return;
} else if (mEntity.isComplete()) {
mEntity.setCompleteTime(System.currentTimeMillis());

@ -410,12 +410,11 @@ public class CommonUtil {
if (records == null || records.isEmpty()) {
ALog.w(TAG, "组任务记录删除失败,记录为null");
return;
}
} else {
for (TaskRecord tr : records) {
tr.deleteData();
}
}
File dir = new File(groupEntity.getDirPath());
if (removeFile) {

@ -15,10 +15,10 @@
android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar">
<!--android:name=".test.TestGroupActivity"-->
<!--android:name=".test.AnyRunActivity"-->
<!--android:name=".test.TestActivity"-->
<!--android:name=".MainActivity"-->
<activity
android:name=".MainActivity"
android:name=".test.AnyRunActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

@ -11,17 +11,17 @@
<!--注意,修改该配置文件中的属性会覆盖代码中所设置的属性-->
<download>
<!--是否开启动态文件,开启动态文件后初始化时将不占用磁盘空间,下载多少byte,占多少空间,效果见chrome的下载。-->
<!--注意:
1、使用该功能,将自动关闭多线程下载;
2、对于已经采用了多线程的任务,依然采用原来的下载方式;
3、原本参数是true,任务没下载完成,就参数改为false,那么没下载完成的任务还是会按照参数修改前的方式下载;只有新任务才会根据参数调用不同的下载方式。-->
<openDynamicFile value="true"/>
<!--断网的时候是否重试,true:断网也重试;false:断网不重试,直接走失败的回调-->
<notNetRetry value="true"/>
<!--设置下载线程,线程下载数改变后,新的下载任务才会生效,如果任务大小小于1m,该设置也不会生效-->
<!--设置下载线程数,下载线程数不能小于1
注意:
1、线程下载数改变后,新的下载任务才会生效;
2、如果任务大小小于1m,该设置不会生效;
3、从3.4.1开始,如果线程数为1,文件初始化时将不再预占用对应长度的空间,下载多少byte,则占多大的空间;
对于采用多线程的任务或旧任务,依然采用原来的文件空间占用方式;
-->
<threadNum value="3"/>
<!--设置下载队列最大任务数, 默认为2-->

@ -15,9 +15,9 @@ public class AnyRunActivity extends BaseActivity<ActivityTestBinding> {
AnyRunnModule module;
String[] urls;
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://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";
@Override protected int setLayoutId() {
@ -42,7 +42,8 @@ public class AnyRunActivity extends BaseActivity<ActivityTestBinding> {
//}
//for (int i = 0; i < 10; i++) {
module.startFtp(URL);
//module.startFtp(URL);
module.start(URL);
//}
//List<AbsEntity> list = Aria.download(this).getTotalTaskList();
//ALog.d(TAG, "size ==> " + list.size());

@ -68,7 +68,7 @@ public class AnyRunnModule {
.load(url)
//.addHeader("Accept-Encoding", "gzip")
.setRequestMode(RequestEnum.GET)
.setFilePath(Environment.getExternalStorageDirectory().getPath() + "/ggsg123456.apk")
.setFilePath(Environment.getExternalStorageDirectory().getPath() + "/ggsg1234567.apk")
//.resetState()
.start();
//String[] urls = new String[] {

@ -366,6 +366,11 @@ class Configuration {
String caName;
/**
* 下载线程数下载线程数不能小于1
* 注意
* 1线程下载数改变后新的下载任务才会生效
* 2如果任务大小小于1m该设置不会生效
* 3从3.4.1开始如果线程数为1文件初始化时将不再预占用对应长度的空间下载多少byte则占多大的空间
* 对于采用多线程的任务或旧任务依然采用原来的文件空间占用方式
*/
int threadNum = 3;
@ -374,26 +379,6 @@ class Configuration {
*/
int maxSpeed = 0;
/**
* 是否开启动态文件开启动态文件后初始化时将不占用磁盘空间下载多少byte占多少空间效果见chrome的下载
* 注意
* 1使用该功能将自动关闭多线程下载
* 2对于已经采用了多线程的任务依然采用原来的下载方式
* 3原本参数是true任务没下载完成就参数改为false那么没下载完成的任务还是会按照参数修改前的方式下载只有新任务才会根据参数调用不同的下载方式
* {@code true}使用
*/
boolean openDynamicFile = true;
public DownloadConfig setOpenDynamicFile(boolean openDynamicFile) {
this.openDynamicFile = openDynamicFile;
saveKey("openDynamicFile", String.valueOf(openDynamicFile));
return this;
}
public boolean isOpenDynamicFile() {
return openDynamicFile;
}
public DownloadConfig setMaxTaskNum(int maxTaskNum) {
oldMaxTaskNum = this.maxTaskNum;
this.maxTaskNum = maxTaskNum;

Loading…
Cancel
Save