优化代码

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

@ -20,20 +20,19 @@ package com.arialyy.aria.core.download;
* 下载状态常量 * 下载状态常量
*/ */
final class DownloadStateConstance { final class DownloadStateConstance {
int CANCEL_NUM = 0; int CANCEL_NUM = 0;
int STOP_NUM = 0; int STOP_NUM = 0;
int FAIL_NUM = 0; int FAIL_NUM = 0;
int CONNECT_TIME_OUT = 5000 * 4; //连接超时时间 int CONNECT_TIME_OUT = 5000 * 4; //连接超时时间
int READ_TIME_OUT = 1000 * 20; //流读取的超时时间 int READ_TIME_OUT = 1000 * 20; //流读取的超时时间
int COMPLETE_THREAD_NUM = 0; int COMPLETE_THREAD_NUM = 0;
int THREAD_NUM = 3; int THREAD_NUM = 3;
long CURRENT_LOCATION = 0; long CURRENT_LOCATION = 0;
boolean isDownloading = false; boolean isDownloading = false;
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,20 +39,23 @@ 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; //连接超时时间
private int mReadTimeOut = 5000 * 20; //流读取的超时时间 private int mReadTimeOut = 5000 * 20; //流读取的超时时间
private boolean isNewTask = true; private boolean isNewTask = true;
private boolean isSupportBreakpoint = true; private boolean isSupportBreakpoint = true;
private Context mContext; private Context mContext;
private DownloadEntity mDownloadEntity; private DownloadEntity mDownloadEntity;
private DownloadTaskEntity mDownloadTaskEntity; private DownloadTaskEntity mDownloadTaskEntity;
private ExecutorService mFixedThreadPool; private ExecutorService mFixedThreadPool;
private File mDownloadFile; //下载的文件 private File mDownloadFile; //下载的文件
private File mConfigFile;//下载信息配置文件 private File mConfigFile;//下载信息配置文件
private SparseArray<Runnable> mTask = new SparseArray<>(); private SparseArray<Runnable> mTask = new SparseArray<>();
private DownloadStateConstance mConstance; private DownloadStateConstance mConstance;
@ -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,19 +295,107 @@ final class DownloadUtil implements IDownloadUtil, Runnable {
//如果整个文件的大小不为线程个数的整数倍,则最后一个线程的结束位置即为文件的总长度 //如果整个文件的大小不为线程个数的整数倍,则最后一个线程的结束位置即为文件的总长度
endL = fileLength; endL = fileLength;
} }
ConfigEntity entity = new ConfigEntity(); addSingleTask(i, startL, endL, fileLength);
entity.FILE_SIZE = fileLength;
entity.DOWNLOAD_URL = mDownloadEntity.getDownloadUrl();
entity.TEMP_FILE = mDownloadFile;
entity.THREAD_ID = i;
entity.START_LOCATION = startL;
entity.END_LOCATION = endL;
entity.CONFIG_FILE_PATH = mConfigFile.getPath();
entity.isSupportBreakpoint = isSupportBreakpoint;
entity.DOWNLOAD_TASK_ENTITY = mDownloadTaskEntity;
SingleThreadTask task = new SingleThreadTask(mConstance, mListener, entity);
mTask.put(i, task);
} }
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();
entity.FILE_SIZE = fileLength;
entity.DOWNLOAD_URL = mDownloadEntity.getDownloadUrl();
entity.TEMP_FILE = mDownloadFile;
entity.THREAD_ID = i;
entity.START_LOCATION = startL;
entity.END_LOCATION = endL;
entity.CONFIG_FILE_PATH = mConfigFile.getPath();
entity.isSupportBreakpoint = isSupportBreakpoint;
entity.DOWNLOAD_TASK_ENTITY = mDownloadTaskEntity;
SingleThreadTask task = new SingleThreadTask(mConstance, mListener, entity);
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; int THREAD_ID;
String DOWNLOAD_URL; long FILE_SIZE;
int THREAD_ID; long START_LOCATION;
long START_LOCATION; long END_LOCATION;
long END_LOCATION; File TEMP_FILE;
File TEMP_FILE; String DOWNLOAD_URL;
boolean isSupportBreakpoint = true; String CONFIG_FILE_PATH;
String CONFIG_FILE_PATH;
DownloadTaskEntity DOWNLOAD_TASK_ENTITY; DownloadTaskEntity DOWNLOAD_TASK_ENTITY;
boolean isSupportBreakpoint = true;
} }
} }
Loading…
Cancel
Save