优化代码

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 isCancel = false;
boolean isStop = false; boolean isStop = false;
DownloadStateConstance(int num) { DownloadStateConstance() {
THREAD_NUM = num;
} }
void cleanState() { void cleanState() {
@ -46,7 +45,7 @@ final class DownloadStateConstance {
FAIL_NUM = 0; FAIL_NUM = 0;
} }
void setThreadNum(int threadNum){ void setThreadNum(int threadNum) {
THREAD_NUM = threadNum; THREAD_NUM = threadNum;
} }

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