优化代码

pull/330/head
AriaLyy 8 years ago
parent b9f0fe7afc
commit cc57ec35f2
  1. 5
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadStateConstance.java
  2. 131
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadUtil.java

@ -32,8 +32,7 @@ final class DownloadStateConstance {
boolean isCancel = false;
boolean isStop = false;
DownloadStateConstance(int num) {
THREAD_NUM = num;
DownloadStateConstance() {
}
void cleanState() {
@ -46,7 +45,7 @@ final class DownloadStateConstance {
FAIL_NUM = 0;
}
void setThreadNum(int threadNum){
void setThreadNum(int threadNum) {
THREAD_NUM = threadNum;
}

@ -39,8 +39,11 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
/**
* 线程数
*/
private final int THREAD_NUM;
private static final long SUB_LEN = 1024 * 100;
private int THREAD_NUM;
/**
* 小于1m的文件不启用多线程
*/
private static final long SUB_LEN = 1024 * 1024;
//下载监听
private IDownloadListener mListener;
private int mConnectTimeOut = 5000 * 4; //连接超时时间
@ -69,7 +72,7 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
mListener = downloadListener;
THREAD_NUM = threadNum;
mFixedThreadPool = Executors.newFixedThreadPool(Integer.MAX_VALUE);
mConstance = new DownloadStateConstance(THREAD_NUM);
mConstance = new DownloadStateConstance();
init();
}
@ -246,9 +249,61 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
* 处理断点
*/
private void handleBreakpoint(HttpURLConnection conn) throws IOException {
//不支持断点只能单线程下载
if (!isSupportBreakpoint) {
handleNoSupportBreakpointDownload(conn);
return;
}
int fileLength = conn.getContentLength();
if (fileLength < SUB_LEN) {
THREAD_NUM = 1;
mConstance.THREAD_NUM = THREAD_NUM;
}
Properties pro = createConfigFile(fileLength);
int blockSize = fileLength / THREAD_NUM;
int[] recordL = new int[THREAD_NUM];
int rl = 0;
for (int i = 0; i < THREAD_NUM; i++) {
recordL[i] = -1;
}
for (int i = 0; i < THREAD_NUM; i++) {
long startL = i * blockSize, endL = (i + 1) * blockSize;
Object state = pro.getProperty(mDownloadFile.getName() + "_state_" + i);
if (state != null && Integer.parseInt(state + "") == 1) { //该线程已经完成
if (resumeRecordLocation(i, startL, endL)) return;
continue;
}
//分配下载位置
Object record = pro.getProperty(mDownloadFile.getName() + "_record_" + i);
//如果有记录,则恢复下载
if (!isNewTask && record != null && Long.parseLong(record + "") > 0) {
Long r = Long.parseLong(record + "");
mConstance.CURRENT_LOCATION += r - startL;
Log.d(TAG, "++++++++++ 线程_" + i + "_恢复下载 ++++++++++");
mListener.onChildResume(r);
startL = r;
recordL[rl] = i;
rl++;
} else {
isNewTask = true;
}
if (isNewTask) {
recordL[rl] = i;
rl++;
}
if (i == (THREAD_NUM - 1)) {
//如果整个文件的大小不为线程个数的整数倍,则最后一个线程的结束位置即为文件的总长度
endL = fileLength;
}
addSingleTask(i, startL, endL, fileLength);
}
startSingleTask(recordL);
}
/**
* 处理不支持断点的下载
*/
private void handleNoSupportBreakpointDownload(HttpURLConnection conn){
ConfigEntity entity = new ConfigEntity();
long len = conn.getContentLength();
entity.FILE_SIZE = len;
@ -264,9 +319,13 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
mFixedThreadPool.execute(task);
mListener.onPostPre(len);
mListener.onStart(0);
return;
}
int fileLength = conn.getContentLength();
/**
* 创建配置文件
*/
private Properties createConfigFile(long fileLength) throws IOException {
Properties pro = null;
//必须建一个文件
CommonUtil.createFile(mDownloadFile.getPath());
BufferedRandomAccessFile file =
@ -275,7 +334,6 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
file.setLength(fileLength);
mListener.onPostPre(fileLength);
//分配每条线程的下载区间
Properties pro = null;
pro = CommonUtil.loadConfig(mConfigFile);
if (pro.isEmpty()) {
isNewTask = true;
@ -291,16 +349,15 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
}
}
}
int blockSize = fileLength / THREAD_NUM;
int[] recordL = new int[THREAD_NUM];
int rl = 0;
for (int i = 0; i < THREAD_NUM; i++) {
recordL[i] = -1;
return pro;
}
for (int i = 0; i < THREAD_NUM; i++) {
long startL = i * blockSize, endL = (i + 1) * blockSize;
Object state = pro.getProperty(mDownloadFile.getName() + "_state_" + i);
if (state != null && Integer.parseInt(state + "") == 1) { //该线程已经完成
/**
* 恢复记录地址
*
* @return true 表示下载完成
*/
private boolean resumeRecordLocation(int i, long startL, long endL) {
mConstance.CURRENT_LOCATION += endL - startL;
Log.d(TAG, "++++++++++ 线程_" + i + "_已经下载完成 ++++++++++");
mConstance.COMPLETE_THREAD_NUM++;
@ -312,32 +369,15 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
}
mListener.onComplete();
mConstance.isDownloading = false;
return;
return true;
}
continue;
}
//分配下载位置
Object record = pro.getProperty(mDownloadFile.getName() + "_record_" + i);
//如果有记录,则恢复下载
if (!isNewTask && record != null && Long.parseLong(record + "") > 0) {
Long r = Long.parseLong(record + "");
mConstance.CURRENT_LOCATION += r - startL;
Log.d(TAG, "++++++++++ 线程_" + i + "_恢复下载 ++++++++++");
mListener.onChildResume(r);
startL = r;
recordL[rl] = i;
rl++;
} else {
isNewTask = true;
}
if (isNewTask) {
recordL[rl] = i;
rl++;
}
if (i == (THREAD_NUM - 1)) {
//如果整个文件的大小不为线程个数的整数倍,则最后一个线程的结束位置即为文件的总长度
endL = fileLength;
return false;
}
/**
* 创建单线程任务
*/
private void addSingleTask(int i, long startL, long endL, long fileLength) {
ConfigEntity entity = new ConfigEntity();
entity.FILE_SIZE = fileLength;
entity.DOWNLOAD_URL = mDownloadEntity.getDownloadUrl();
@ -351,6 +391,11 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
SingleThreadTask task = new SingleThreadTask(mConstance, mListener, entity);
mTask.put(i, task);
}
/**
* 启动单线程下载任务
*/
private void startSingleTask(int[] recordL) {
if (mConstance.CURRENT_LOCATION > 0) {
mListener.onResume(mConstance.CURRENT_LOCATION);
} else {
@ -370,14 +415,14 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
*/
final static class ConfigEntity {
//文件大小
long FILE_SIZE;
String DOWNLOAD_URL;
int THREAD_ID;
long FILE_SIZE;
long START_LOCATION;
long END_LOCATION;
File TEMP_FILE;
boolean isSupportBreakpoint = true;
String DOWNLOAD_URL;
String CONFIG_FILE_PATH;
DownloadTaskEntity DOWNLOAD_TASK_ENTITY;
boolean isSupportBreakpoint = true;
}
}
Loading…
Cancel
Save