优化代码

This commit is contained in:
AriaLyy
2017-03-17 11:47:54 +08:00
parent b9f0fe7afc
commit cc57ec35f2
2 changed files with 141 additions and 97 deletions

View File

@ -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;
} }

View File

@ -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,51 +249,17 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
* 处理断点 * 处理断点
*/ */
private void handleBreakpoint(HttpURLConnection conn) throws IOException { private void handleBreakpoint(HttpURLConnection conn) throws IOException {
//不支持断点只能单线程下载 //不支持断点只能单线程下载
if (!isSupportBreakpoint) { if (!isSupportBreakpoint) {
ConfigEntity entity = new ConfigEntity(); handleNoSupportBreakpointDownload(conn);
long len = conn.getContentLength();
entity.FILE_SIZE = len;
entity.DOWNLOAD_URL = mDownloadEntity.getDownloadUrl();
entity.TEMP_FILE = mDownloadFile;
entity.THREAD_ID = 0;
entity.START_LOCATION = 0;
entity.END_LOCATION = entity.FILE_SIZE;
entity.CONFIG_FILE_PATH = mConfigFile.getPath();
entity.isSupportBreakpoint = isSupportBreakpoint;
entity.DOWNLOAD_TASK_ENTITY = mDownloadTaskEntity;
SingleThreadTask task = new SingleThreadTask(mConstance, mListener, entity);
mFixedThreadPool.execute(task);
mListener.onPostPre(len);
mListener.onStart(0);
return; return;
} }
int fileLength = conn.getContentLength(); int fileLength = conn.getContentLength();
//必须建一个文件 if (fileLength < SUB_LEN) {
CommonUtil.createFile(mDownloadFile.getPath()); THREAD_NUM = 1;
BufferedRandomAccessFile file = mConstance.THREAD_NUM = THREAD_NUM;
new BufferedRandomAccessFile(new File(mDownloadFile.getPath()), "rwd", 8192);
//设置文件长度
file.setLength(fileLength);
mListener.onPostPre(fileLength);
//分配每条线程的下载区间
Properties pro = null;
pro = CommonUtil.loadConfig(mConfigFile);
if (pro.isEmpty()) {
isNewTask = true;
} else {
for (int i = 0; i < THREAD_NUM; i++) {
if (pro.getProperty(mDownloadFile.getName() + "_record_" + i) == null) {
Object state = pro.getProperty(mDownloadFile.getName() + "_state_" + i);
if (state != null && Integer.parseInt(state + "") == 1) {
continue;
}
isNewTask = true;
break;
}
}
} }
Properties pro = createConfigFile(fileLength);
int blockSize = fileLength / THREAD_NUM; int blockSize = fileLength / THREAD_NUM;
int[] recordL = new int[THREAD_NUM]; int[] recordL = new int[THREAD_NUM];
int rl = 0; int rl = 0;
@ -301,19 +270,7 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
long startL = i * blockSize, endL = (i + 1) * blockSize; long startL = i * blockSize, endL = (i + 1) * blockSize;
Object state = pro.getProperty(mDownloadFile.getName() + "_state_" + i); Object state = pro.getProperty(mDownloadFile.getName() + "_state_" + i);
if (state != null && Integer.parseInt(state + "") == 1) { //该线程已经完成 if (state != null && Integer.parseInt(state + "") == 1) { //该线程已经完成
mConstance.CURRENT_LOCATION += endL - startL; if (resumeRecordLocation(i, startL, endL)) return;
Log.d(TAG, "++++++++++ 线程_" + i + "_已经下载完成 ++++++++++");
mConstance.COMPLETE_THREAD_NUM++;
mConstance.STOP_NUM++;
mConstance.CANCEL_NUM++;
if (mConstance.isComplete()) {
if (mConfigFile.exists()) {
mConfigFile.delete();
}
mListener.onComplete();
mConstance.isDownloading = false;
return;
}
continue; continue;
} }
//分配下载位置 //分配下载位置
@ -338,6 +295,89 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
//如果整个文件的大小不为线程个数的整数倍,则最后一个线程的结束位置即为文件的总长度 //如果整个文件的大小不为线程个数的整数倍,则最后一个线程的结束位置即为文件的总长度
endL = fileLength; 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;
entity.DOWNLOAD_URL = mDownloadEntity.getDownloadUrl();
entity.TEMP_FILE = mDownloadFile;
entity.THREAD_ID = 0;
entity.START_LOCATION = 0;
entity.END_LOCATION = entity.FILE_SIZE;
entity.CONFIG_FILE_PATH = mConfigFile.getPath();
entity.isSupportBreakpoint = isSupportBreakpoint;
entity.DOWNLOAD_TASK_ENTITY = mDownloadTaskEntity;
SingleThreadTask task = new SingleThreadTask(mConstance, mListener, entity);
mFixedThreadPool.execute(task);
mListener.onPostPre(len);
mListener.onStart(0);
}
/**
* 创建配置文件
*/
private Properties createConfigFile(long fileLength) throws IOException {
Properties pro = null;
//必须建一个文件
CommonUtil.createFile(mDownloadFile.getPath());
BufferedRandomAccessFile file =
new BufferedRandomAccessFile(new File(mDownloadFile.getPath()), "rwd", 8192);
//设置文件长度
file.setLength(fileLength);
mListener.onPostPre(fileLength);
//分配每条线程的下载区间
pro = CommonUtil.loadConfig(mConfigFile);
if (pro.isEmpty()) {
isNewTask = true;
} else {
for (int i = 0; i < THREAD_NUM; i++) {
if (pro.getProperty(mDownloadFile.getName() + "_record_" + i) == null) {
Object state = pro.getProperty(mDownloadFile.getName() + "_state_" + i);
if (state != null && Integer.parseInt(state + "") == 1) {
continue;
}
isNewTask = true;
break;
}
}
}
return pro;
}
/**
* 恢复记录地址
*
* @return true 表示下载完成
*/
private boolean resumeRecordLocation(int i, long startL, long endL) {
mConstance.CURRENT_LOCATION += endL - startL;
Log.d(TAG, "++++++++++ 线程_" + i + "_已经下载完成 ++++++++++");
mConstance.COMPLETE_THREAD_NUM++;
mConstance.STOP_NUM++;
mConstance.CANCEL_NUM++;
if (mConstance.isComplete()) {
if (mConfigFile.exists()) {
mConfigFile.delete();
}
mListener.onComplete();
mConstance.isDownloading = false;
return true;
}
return false;
}
/**
* 创建单线程任务
*/
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;
} }
} }