配置文件修改
This commit is contained in:
@ -33,6 +33,7 @@ import com.arialyy.aria.core.inf.ICmd;
|
||||
import com.arialyy.aria.core.inf.IReceiver;
|
||||
import com.arialyy.aria.core.upload.UploadReceiver;
|
||||
import com.arialyy.aria.orm.DbUtil;
|
||||
import com.arialyy.aria.util.FileUtil;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@ -66,13 +67,7 @@ import org.xml.sax.SAXException;
|
||||
DbUtil.init(context.getApplicationContext());
|
||||
APP = context.getApplicationContext();
|
||||
regAppLifeCallback(context);
|
||||
File dFile = new File(APP.getFilesDir().getPath() + Configuration.DOWNLOAD_CONFIG_FILE);
|
||||
File uFile = new File(APP.getFilesDir().getPath() +Configuration.UPLOAD_CONFIG_FILE);
|
||||
if (!dFile.exists() || !uFile.exists()) {
|
||||
loadConfig();
|
||||
}
|
||||
mDConfig = Configuration.DownloadConfig.getInstance();
|
||||
mUConfig = Configuration.UploadConfig.getInstance();
|
||||
initConfig();
|
||||
}
|
||||
|
||||
public static AriaManager getInstance(Context context) {
|
||||
@ -98,7 +93,7 @@ import org.xml.sax.SAXException;
|
||||
SAXParser parser = factory.newSAXParser();
|
||||
parser.parse(APP.getAssets().open("aria_config.xml"), helper);
|
||||
} catch (ParserConfigurationException | IOException | SAXException e) {
|
||||
e.printStackTrace();
|
||||
Log.d(TAG, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,7 +101,7 @@ import org.xml.sax.SAXException;
|
||||
* 如果需要在代码中修改下载配置,请使用以下方法
|
||||
*
|
||||
* @<code> //修改最大任务队列数
|
||||
* Aria.get(this).getDownloadConfig().setMaxTaskNum(3).saveAll();
|
||||
* Aria.get(this).getDownloadConfig().setMaxTaskNum(3);
|
||||
* </code>
|
||||
*/
|
||||
public Configuration.DownloadConfig getDownloadConfig() {
|
||||
@ -117,7 +112,7 @@ import org.xml.sax.SAXException;
|
||||
* 如果需要在代码中修改下载配置,请使用以下方法
|
||||
*
|
||||
* @<code> //修改最大任务队列数
|
||||
* Aria.get(this).getUploadConfig().setMaxTaskNum(3).saveAll();
|
||||
* Aria.get(this).getUploadConfig().setMaxTaskNum(3);
|
||||
* </code>
|
||||
*/
|
||||
public Configuration.UploadConfig getUploadConfig() {
|
||||
@ -243,6 +238,29 @@ import org.xml.sax.SAXException;
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化配置文件
|
||||
*/
|
||||
private void initConfig() {
|
||||
//File dFile = new File(APP.getFilesDir().getPath() + Configuration.DOWNLOAD_CONFIG_FILE);
|
||||
//File uFile = new File(APP.getFilesDir().getPath() + Configuration.UPLOAD_CONFIG_FILE);
|
||||
File xmlFile = new File(APP.getFilesDir().getPath() + Configuration.XML_FILE);
|
||||
if (!xmlFile.exists()) {
|
||||
loadConfig();
|
||||
} else {
|
||||
try {
|
||||
String md5Code = FileUtil.getFileMD5(xmlFile);
|
||||
if (!FileUtil.checkMD5(md5Code, APP.getAssets().open("aria_config.xml"))) {
|
||||
loadConfig();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
mDConfig = Configuration.DownloadConfig.getInstance();
|
||||
mUConfig = Configuration.UploadConfig.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册APP生命周期回调
|
||||
*/
|
||||
|
@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.arialyy.aria.core;
|
||||
|
||||
import android.util.Log;
|
||||
import com.arialyy.aria.core.queue.DownloadTaskQueue;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.aria.util.ReflectionUtil;
|
||||
@ -32,6 +31,7 @@ import java.util.Properties;
|
||||
class Configuration {
|
||||
static final String DOWNLOAD_CONFIG_FILE = "/Aria/DownloadConfig.properties";
|
||||
static final String UPLOAD_CONFIG_FILE = "/Aria/UploadConfig.properties";
|
||||
static final String XML_FILE = "/Aria/aria_config.xml";
|
||||
|
||||
/**
|
||||
* 通用配置
|
||||
@ -57,11 +57,11 @@ class Configuration {
|
||||
/**
|
||||
* 设置重试间隔,单位为毫秒,默认2000毫秒
|
||||
*/
|
||||
long reTryInterval = 2000;
|
||||
int reTryInterval = 2000;
|
||||
/**
|
||||
* 设置url连接超时时间,单位为毫秒,默认5000毫秒
|
||||
*/
|
||||
long connectTimeOut = 5000;
|
||||
int connectTimeOut = 5000;
|
||||
|
||||
public boolean isOpenBreadCast() {
|
||||
return isOpenBreadCast;
|
||||
@ -95,21 +95,21 @@ class Configuration {
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getReTryInterval() {
|
||||
public int getReTryInterval() {
|
||||
return reTryInterval;
|
||||
}
|
||||
|
||||
public BaseConfig setReTryInterval(long reTryInterval) {
|
||||
public BaseConfig setReTryInterval(int reTryInterval) {
|
||||
this.reTryInterval = reTryInterval;
|
||||
saveKey("reTryInterval", reTryInterval + "");
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getConnectTimeOut() {
|
||||
public int getConnectTimeOut() {
|
||||
return connectTimeOut;
|
||||
}
|
||||
|
||||
public BaseConfig setConnectTimeOut(long connectTimeOut) {
|
||||
public BaseConfig setConnectTimeOut(int connectTimeOut) {
|
||||
this.connectTimeOut = connectTimeOut;
|
||||
saveKey("connectTimeOut", connectTimeOut + "");
|
||||
return this;
|
||||
@ -203,7 +203,7 @@ class Configuration {
|
||||
/**
|
||||
* 设置IO流读取时间,单位为毫秒,默认20000毫秒,该时间不能少于10000毫秒
|
||||
*/
|
||||
long iOTimeOut = 20 * 1000;
|
||||
int iOTimeOut = 20 * 1000;
|
||||
/**
|
||||
* 设置写文件buff大小,该数值大小不能小于2048,数值变小,下载速度会变慢
|
||||
*/
|
||||
@ -221,11 +221,11 @@ class Configuration {
|
||||
*/
|
||||
int threadNum = 3;
|
||||
|
||||
public long getiOTimeOut() {
|
||||
public int getIOTimeOut() {
|
||||
return iOTimeOut;
|
||||
}
|
||||
|
||||
public DownloadConfig setiOTimeOut(long iOTimeOut) {
|
||||
public DownloadConfig setIOTimeOut(int iOTimeOut) {
|
||||
this.iOTimeOut = iOTimeOut;
|
||||
saveKey("iOTimeOut", iOTimeOut + "");
|
||||
return this;
|
||||
|
@ -43,10 +43,19 @@ public class DownloadEntity extends DbEntity implements Parcelable, IEntity {
|
||||
private long completeTime; //完成时间
|
||||
private boolean isRedirect = false;
|
||||
private String redirectUrl = ""; //重定向链接
|
||||
private int threadNum; //下载线程数
|
||||
|
||||
public DownloadEntity() {
|
||||
}
|
||||
|
||||
public int getThreadNum() {
|
||||
return threadNum;
|
||||
}
|
||||
|
||||
public void setThreadNum(int threadNum) {
|
||||
this.threadNum = threadNum;
|
||||
}
|
||||
|
||||
public String getStr() {
|
||||
return str;
|
||||
}
|
||||
@ -191,6 +200,8 @@ public class DownloadEntity extends DbEntity implements Parcelable, IEntity {
|
||||
+ ", redirectUrl='"
|
||||
+ redirectUrl
|
||||
+ '\''
|
||||
+ ", threadNum="
|
||||
+ threadNum
|
||||
+ '}';
|
||||
}
|
||||
|
||||
@ -212,6 +223,7 @@ public class DownloadEntity extends DbEntity implements Parcelable, IEntity {
|
||||
dest.writeLong(this.completeTime);
|
||||
dest.writeByte(this.isRedirect ? (byte) 1 : (byte) 0);
|
||||
dest.writeString(this.redirectUrl);
|
||||
dest.writeInt(this.threadNum);
|
||||
}
|
||||
|
||||
protected DownloadEntity(Parcel in) {
|
||||
@ -228,6 +240,7 @@ public class DownloadEntity extends DbEntity implements Parcelable, IEntity {
|
||||
this.completeTime = in.readLong();
|
||||
this.isRedirect = in.readByte() != 0;
|
||||
this.redirectUrl = in.readString();
|
||||
this.threadNum = in.readInt();
|
||||
}
|
||||
|
||||
@Ignore public static final Creator<DownloadEntity> CREATOR = new Creator<DownloadEntity>() {
|
||||
|
@ -23,10 +23,10 @@ final class DownloadStateConstance {
|
||||
int CANCEL_NUM = 0;
|
||||
int STOP_NUM = 0;
|
||||
int FAIL_NUM = 0;
|
||||
int CONNECT_TIME_OUT = 5000 * 4; //连接超时时间
|
||||
int READ_TIME_OUT = 1000 * 20; //流读取的超时时间
|
||||
int CONNECT_TIME_OUT; //连接超时时间
|
||||
int READ_TIME_OUT; //流读取的超时时间
|
||||
int COMPLETE_THREAD_NUM = 0;
|
||||
int THREAD_NUM = 3;
|
||||
int THREAD_NUM;
|
||||
long CURRENT_LOCATION = 0;
|
||||
boolean isDownloading = false;
|
||||
boolean isCancel = false;
|
||||
|
@ -19,6 +19,7 @@ package com.arialyy.aria.core.download;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import com.arialyy.aria.util.BufferedRandomAccessFile;
|
||||
import com.arialyy.aria.util.CheckUtil;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
@ -34,7 +35,7 @@ import java.util.concurrent.Executors;
|
||||
* Created by lyy on 2015/8/25.
|
||||
* 下载工具类
|
||||
*/
|
||||
public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
private static final String TAG = "DownloadUtil";
|
||||
/**
|
||||
* 线程数
|
||||
@ -46,8 +47,7 @@ public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
private static final long SUB_LEN = 1024 * 1024;
|
||||
//下载监听
|
||||
private IDownloadListener mListener;
|
||||
private int mConnectTimeOut = 5000 * 4; //连接超时时间
|
||||
private int mReadTimeOut = 5000 * 20; //流读取的超时时间
|
||||
private int mConnectTimeOut = 0; //连接超时时间
|
||||
private boolean isNewTask = true;
|
||||
private boolean isSupportBreakpoint = true;
|
||||
private Context mContext;
|
||||
@ -57,34 +57,29 @@ public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
private File mDownloadFile; //下载的文件
|
||||
private File mConfigFile;//下载信息配置文件
|
||||
private SparseArray<Runnable> mTask = new SparseArray<>();
|
||||
private DownloadStateConstance mConstance;
|
||||
private DownloadStateConstance CONSTANCE;
|
||||
|
||||
DownloadUtil(Context context, DownloadTaskEntity entity, IDownloadListener downloadListener) {
|
||||
this(context, entity, downloadListener, 3);
|
||||
}
|
||||
|
||||
DownloadUtil(Context context, DownloadTaskEntity entity, IDownloadListener downloadListener,
|
||||
int threadNum) {
|
||||
//CheckUtil.checkDownloadTaskEntity(entity.downloadEntity);
|
||||
CheckUtil.checkTaskEntity(entity);
|
||||
mDownloadEntity = entity.downloadEntity;
|
||||
mContext = context.getApplicationContext();
|
||||
mDownloadTaskEntity = entity;
|
||||
mListener = downloadListener;
|
||||
THREAD_NUM = threadNum;
|
||||
// 线程下载数改变后,新的下载才会生效
|
||||
mFixedThreadPool = Executors.newFixedThreadPool(Integer.MAX_VALUE);
|
||||
mConstance = new DownloadStateConstance();
|
||||
CONSTANCE = new DownloadStateConstance();
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
mConnectTimeOut = AriaManager.getInstance(mContext).getDownloadConfig().getConnectTimeOut();
|
||||
mDownloadFile = new File(mDownloadTaskEntity.downloadEntity.getDownloadPath());
|
||||
//读取已完成的线程数
|
||||
mConfigFile = new File(
|
||||
mContext.getFilesDir().getPath() + "/temp/" + mDownloadFile.getName() + ".properties");
|
||||
try {
|
||||
if (!mConfigFile.exists()) { //记录文件被删除,则重新下载
|
||||
isNewTask = true;
|
||||
handleNewTask();
|
||||
CommonUtil.createFile(mConfigFile.getPath());
|
||||
} else {
|
||||
isNewTask = !mDownloadFile.exists();
|
||||
@ -99,37 +94,23 @@ public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
return mListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置连接超时时间
|
||||
*/
|
||||
public void setConnectTimeOut(int timeOut) {
|
||||
mConnectTimeOut = timeOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置流读取的超时时间
|
||||
*/
|
||||
public void setReadTimeOut(int readTimeOut) {
|
||||
mReadTimeOut = readTimeOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前下载位置
|
||||
*/
|
||||
@Override public long getCurrentLocation() {
|
||||
return mConstance.CURRENT_LOCATION;
|
||||
return CONSTANCE.CURRENT_LOCATION;
|
||||
}
|
||||
|
||||
@Override public boolean isDownloading() {
|
||||
return mConstance.isDownloading;
|
||||
return CONSTANCE.isDownloading;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消下载
|
||||
*/
|
||||
@Override public void cancelDownload() {
|
||||
mConstance.isCancel = true;
|
||||
mConstance.isDownloading = false;
|
||||
CONSTANCE.isCancel = true;
|
||||
CONSTANCE.isDownloading = false;
|
||||
mFixedThreadPool.shutdown();
|
||||
for (int i = 0; i < THREAD_NUM; i++) {
|
||||
SingleThreadTask task = (SingleThreadTask) mTask.get(i);
|
||||
@ -143,8 +124,8 @@ public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
* 停止下载
|
||||
*/
|
||||
@Override public void stopDownload() {
|
||||
mConstance.isStop = true;
|
||||
mConstance.isDownloading = false;
|
||||
CONSTANCE.isStop = true;
|
||||
CONSTANCE.isDownloading = false;
|
||||
mFixedThreadPool.shutdown();
|
||||
for (int i = 0; i < THREAD_NUM; i++) {
|
||||
SingleThreadTask task = (SingleThreadTask) mTask.get(i);
|
||||
@ -184,7 +165,7 @@ public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
* 多线程断点续传下载文件,开始下载
|
||||
*/
|
||||
@Override public void startDownload() {
|
||||
mConstance.cleanState();
|
||||
CONSTANCE.cleanState();
|
||||
mListener.onPre();
|
||||
new Thread(this).start();
|
||||
}
|
||||
@ -195,7 +176,7 @@ public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
|
||||
private void failDownload(String msg) {
|
||||
Log.e(TAG, msg);
|
||||
mConstance.isDownloading = false;
|
||||
CONSTANCE.isDownloading = false;
|
||||
stopDownload();
|
||||
mListener.onFail();
|
||||
}
|
||||
@ -206,7 +187,7 @@ public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
HttpURLConnection conn = ConnectionHelp.handleConnection(url);
|
||||
conn = ConnectionHelp.setConnectParam(mDownloadTaskEntity, conn);
|
||||
conn.setRequestProperty("Range", "bytes=" + 0 + "-");
|
||||
conn.setConnectTimeout(mConnectTimeOut * 4);
|
||||
conn.setConnectTimeout(mConnectTimeOut);
|
||||
conn.connect();
|
||||
handleConnect(conn);
|
||||
} catch (IOException e) {
|
||||
@ -283,7 +264,7 @@ public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
conn = ConnectionHelp.setConnectParam(mDownloadTaskEntity, conn);
|
||||
conn.setRequestProperty("Cookie", cookies);
|
||||
conn.setRequestProperty("Range", "bytes=" + 0 + "-");
|
||||
conn.setConnectTimeout(mConnectTimeOut * 4);
|
||||
conn.setConnectTimeout(mConnectTimeOut);
|
||||
conn.connect();
|
||||
|
||||
handleConnect(conn);
|
||||
@ -301,7 +282,7 @@ public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
int fileLength = conn.getContentLength();
|
||||
if (fileLength < SUB_LEN) {
|
||||
THREAD_NUM = 1;
|
||||
mConstance.THREAD_NUM = THREAD_NUM;
|
||||
CONSTANCE.THREAD_NUM = THREAD_NUM;
|
||||
}
|
||||
Properties pro = createConfigFile(fileLength);
|
||||
int blockSize = fileLength / THREAD_NUM;
|
||||
@ -322,14 +303,14 @@ public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
//如果有记录,则恢复下载
|
||||
if (!isNewTask && record != null && Long.parseLong(record + "") > 0) {
|
||||
Long r = Long.parseLong(record + "");
|
||||
mConstance.CURRENT_LOCATION += r - startL;
|
||||
CONSTANCE.CURRENT_LOCATION += r - startL;
|
||||
Log.d(TAG, "++++++++++ 线程_" + i + "_恢复下载 ++++++++++");
|
||||
mListener.onChildResume(r);
|
||||
startL = r;
|
||||
recordL[rl] = i;
|
||||
rl++;
|
||||
} else {
|
||||
isNewTask = true;
|
||||
handleNewTask();
|
||||
}
|
||||
if (isNewTask) {
|
||||
recordL[rl] = i;
|
||||
@ -351,7 +332,6 @@ public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
ConfigEntity entity = new ConfigEntity();
|
||||
long len = conn.getContentLength();
|
||||
entity.FILE_SIZE = len;
|
||||
//entity.DOWNLOAD_URL = mDownloadEntity.getDownloadUrl();
|
||||
entity.DOWNLOAD_URL = mDownloadEntity.isRedirect() ? mDownloadEntity.getRedirectUrl()
|
||||
: mDownloadEntity.getDownloadUrl();
|
||||
entity.TEMP_FILE = mDownloadFile;
|
||||
@ -362,8 +342,8 @@ public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
entity.isSupportBreakpoint = isSupportBreakpoint;
|
||||
entity.DOWNLOAD_TASK_ENTITY = mDownloadTaskEntity;
|
||||
THREAD_NUM = 1;
|
||||
mConstance.THREAD_NUM = THREAD_NUM;
|
||||
SingleThreadTask task = new SingleThreadTask(mConstance, mListener, entity);
|
||||
CONSTANCE.THREAD_NUM = THREAD_NUM;
|
||||
SingleThreadTask task = new SingleThreadTask(CONSTANCE, mListener, entity);
|
||||
mTask.put(0, task);
|
||||
mFixedThreadPool.execute(task);
|
||||
mListener.onPostPre(len);
|
||||
@ -385,15 +365,16 @@ public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
//分配每条线程的下载区间
|
||||
pro = CommonUtil.loadConfig(mConfigFile);
|
||||
if (pro.isEmpty()) {
|
||||
isNewTask = true;
|
||||
handleNewTask();
|
||||
} else {
|
||||
THREAD_NUM = pro.keySet().size();
|
||||
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;
|
||||
handleNewTask();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -401,23 +382,31 @@ public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
return pro;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理新任务
|
||||
*/
|
||||
private void handleNewTask() {
|
||||
isNewTask = true;
|
||||
THREAD_NUM = AriaManager.getInstance(mContext).getDownloadConfig().getThreadNum();
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复记录地址
|
||||
*
|
||||
* @return true 表示下载完成
|
||||
*/
|
||||
private boolean resumeRecordLocation(int i, long startL, long endL) {
|
||||
mConstance.CURRENT_LOCATION += endL - startL;
|
||||
CONSTANCE.CURRENT_LOCATION += endL - startL;
|
||||
Log.d(TAG, "++++++++++ 线程_" + i + "_已经下载完成 ++++++++++");
|
||||
mConstance.COMPLETE_THREAD_NUM++;
|
||||
mConstance.STOP_NUM++;
|
||||
mConstance.CANCEL_NUM++;
|
||||
if (mConstance.isComplete()) {
|
||||
CONSTANCE.COMPLETE_THREAD_NUM++;
|
||||
CONSTANCE.STOP_NUM++;
|
||||
CONSTANCE.CANCEL_NUM++;
|
||||
if (CONSTANCE.isComplete()) {
|
||||
if (mConfigFile.exists()) {
|
||||
mConfigFile.delete();
|
||||
}
|
||||
mListener.onComplete();
|
||||
mConstance.isDownloading = false;
|
||||
CONSTANCE.isDownloading = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -439,7 +428,8 @@ public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
entity.CONFIG_FILE_PATH = mConfigFile.getPath();
|
||||
entity.isSupportBreakpoint = isSupportBreakpoint;
|
||||
entity.DOWNLOAD_TASK_ENTITY = mDownloadTaskEntity;
|
||||
SingleThreadTask task = new SingleThreadTask(mConstance, mListener, entity);
|
||||
CONSTANCE.THREAD_NUM = THREAD_NUM;
|
||||
SingleThreadTask task = new SingleThreadTask(CONSTANCE, mListener, entity);
|
||||
mTask.put(i, task);
|
||||
}
|
||||
|
||||
@ -447,10 +437,10 @@ public class DownloadUtil implements IDownloadUtil, Runnable {
|
||||
* 启动单线程下载任务
|
||||
*/
|
||||
private void startSingleTask(int[] recordL) {
|
||||
if (mConstance.CURRENT_LOCATION > 0) {
|
||||
mListener.onResume(mConstance.CURRENT_LOCATION);
|
||||
if (CONSTANCE.CURRENT_LOCATION > 0) {
|
||||
mListener.onResume(CONSTANCE.CURRENT_LOCATION);
|
||||
} else {
|
||||
mListener.onStart(mConstance.CURRENT_LOCATION);
|
||||
mListener.onStart(CONSTANCE.CURRENT_LOCATION);
|
||||
}
|
||||
for (int l : recordL) {
|
||||
if (l == -1) continue;
|
||||
|
@ -15,10 +15,8 @@
|
||||
*/
|
||||
package com.arialyy.aria.core.download;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import com.arialyy.aria.util.BufferedRandomAccessFile;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import java.io.File;
|
||||
@ -34,35 +32,34 @@ import java.util.Properties;
|
||||
* 下载线程
|
||||
*/
|
||||
final class SingleThreadTask implements Runnable {
|
||||
private static final String TAG = "SingleThreadTask";
|
||||
// TODO: 2017/2/22 不能使用1024 否则最大速度不能超过3m
|
||||
private static final int BUF_SIZE = 8192;
|
||||
private static final String TAG = "SingleThreadTask";
|
||||
private DownloadUtil.ConfigEntity mConfigEntity;
|
||||
private String mConfigFPath;
|
||||
private long mChildCurrentLocation = 0;
|
||||
private static final Object LOCK = new Object();
|
||||
private int mBufSize = 8192;
|
||||
//private int mBufSize = 64;
|
||||
private int mBufSize;
|
||||
private IDownloadListener mListener;
|
||||
private DownloadStateConstance mConstance;
|
||||
private DownloadStateConstance CONSTANCE;
|
||||
|
||||
SingleThreadTask(DownloadStateConstance constance, IDownloadListener listener,
|
||||
DownloadUtil.ConfigEntity downloadInfo) {
|
||||
mConstance = constance;
|
||||
AriaManager manager = AriaManager.getInstance(AriaManager.APP);
|
||||
CONSTANCE = constance;
|
||||
CONSTANCE.CONNECT_TIME_OUT = manager.getDownloadConfig().getConnectTimeOut();
|
||||
CONSTANCE.READ_TIME_OUT = manager.getDownloadConfig().getIOTimeOut();
|
||||
mListener = listener;
|
||||
this.mConfigEntity = downloadInfo;
|
||||
if (mConfigEntity.isSupportBreakpoint) {
|
||||
mConfigFPath = downloadInfo.CONFIG_FILE_PATH;
|
||||
}
|
||||
//mBufSize = Configuration_1.getInstance().getMaxSpeed();
|
||||
mBufSize = manager.getDownloadConfig().getBuffSize();
|
||||
}
|
||||
|
||||
@Override public void run() {
|
||||
HttpURLConnection conn = null;
|
||||
InputStream is = null;
|
||||
HttpURLConnection conn;
|
||||
InputStream is;
|
||||
try {
|
||||
URL url = new URL(mConfigEntity.DOWNLOAD_URL);
|
||||
//conn = (HttpURLConnection) url.openConnection();
|
||||
conn = ConnectionHelp.handleConnection(url);
|
||||
if (mConfigEntity.isSupportBreakpoint) {
|
||||
Log.d(TAG, "线程_"
|
||||
@ -79,8 +76,8 @@ final class SingleThreadTask implements Runnable {
|
||||
Log.w(TAG, "该下载不支持断点");
|
||||
}
|
||||
conn = ConnectionHelp.setConnectParam(mConfigEntity.DOWNLOAD_TASK_ENTITY, conn);
|
||||
conn.setConnectTimeout(mConstance.CONNECT_TIME_OUT);
|
||||
conn.setReadTimeout(mConstance.READ_TIME_OUT); //设置读取流的等待时间,必须设置该参数
|
||||
conn.setConnectTimeout(CONSTANCE.CONNECT_TIME_OUT);
|
||||
conn.setReadTimeout(CONSTANCE.READ_TIME_OUT); //设置读取流的等待时间,必须设置该参数
|
||||
is = conn.getInputStream();
|
||||
//创建可设置位置的文件
|
||||
BufferedRandomAccessFile file =
|
||||
@ -92,10 +89,10 @@ final class SingleThreadTask implements Runnable {
|
||||
//当前子线程的下载位置
|
||||
mChildCurrentLocation = mConfigEntity.START_LOCATION;
|
||||
while ((len = is.read(buffer)) != -1) {
|
||||
if (mConstance.isCancel) {
|
||||
if (CONSTANCE.isCancel) {
|
||||
break;
|
||||
}
|
||||
if (mConstance.isStop) {
|
||||
if (CONSTANCE.isStop) {
|
||||
break;
|
||||
}
|
||||
//把下载数据数据写入文件
|
||||
@ -106,11 +103,11 @@ final class SingleThreadTask implements Runnable {
|
||||
//close 为阻塞的,需要使用线程池来处理
|
||||
is.close();
|
||||
conn.disconnect();
|
||||
if (mConstance.isCancel) {
|
||||
if (CONSTANCE.isCancel) {
|
||||
return;
|
||||
}
|
||||
//停止状态不需要删除记录文件
|
||||
if (mConstance.isStop) {
|
||||
if (CONSTANCE.isStop) {
|
||||
return;
|
||||
}
|
||||
//支持断点的处理
|
||||
@ -119,29 +116,29 @@ final class SingleThreadTask implements Runnable {
|
||||
writeConfig(mConfigEntity.TEMP_FILE.getName() + "_state_" + mConfigEntity.THREAD_ID,
|
||||
1 + "");
|
||||
mListener.onChildComplete(mConfigEntity.END_LOCATION);
|
||||
mConstance.COMPLETE_THREAD_NUM++;
|
||||
if (mConstance.isComplete()) {
|
||||
CONSTANCE.COMPLETE_THREAD_NUM++;
|
||||
if (CONSTANCE.isComplete()) {
|
||||
File configFile = new File(mConfigFPath);
|
||||
if (configFile.exists()) {
|
||||
configFile.delete();
|
||||
}
|
||||
mConstance.isDownloading = false;
|
||||
CONSTANCE.isDownloading = false;
|
||||
mListener.onComplete();
|
||||
}
|
||||
} else {
|
||||
Log.i(TAG, "下载任务完成");
|
||||
mConstance.isDownloading = false;
|
||||
CONSTANCE.isDownloading = false;
|
||||
mListener.onComplete();
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
mConstance.FAIL_NUM++;
|
||||
CONSTANCE.FAIL_NUM++;
|
||||
failDownload(mConfigEntity, mChildCurrentLocation, "下载链接异常", e);
|
||||
} catch (IOException e) {
|
||||
mConstance.FAIL_NUM++;
|
||||
CONSTANCE.FAIL_NUM++;
|
||||
failDownload(mConfigEntity, mChildCurrentLocation, "下载失败【" + mConfigEntity.DOWNLOAD_URL + "】",
|
||||
e);
|
||||
} catch (Exception e) {
|
||||
mConstance.FAIL_NUM++;
|
||||
CONSTANCE.FAIL_NUM++;
|
||||
failDownload(mConfigEntity, mChildCurrentLocation, "获取流失败", e);
|
||||
}
|
||||
}
|
||||
@ -153,7 +150,7 @@ final class SingleThreadTask implements Runnable {
|
||||
synchronized (LOCK) {
|
||||
try {
|
||||
if (mConfigEntity.isSupportBreakpoint) {
|
||||
mConstance.STOP_NUM++;
|
||||
CONSTANCE.STOP_NUM++;
|
||||
String location = String.valueOf(mChildCurrentLocation);
|
||||
Log.d(TAG, "thread_"
|
||||
+ mConfigEntity.THREAD_ID
|
||||
@ -161,15 +158,15 @@ final class SingleThreadTask implements Runnable {
|
||||
+ mChildCurrentLocation);
|
||||
writeConfig(mConfigEntity.TEMP_FILE.getName() + "_record_" + mConfigEntity.THREAD_ID,
|
||||
location);
|
||||
if (mConstance.isStop()) {
|
||||
if (CONSTANCE.isStop()) {
|
||||
Log.d(TAG, "++++++++++++++++ onStop +++++++++++++++++");
|
||||
mConstance.isDownloading = false;
|
||||
mListener.onStop(mConstance.CURRENT_LOCATION);
|
||||
CONSTANCE.isDownloading = false;
|
||||
mListener.onStop(CONSTANCE.CURRENT_LOCATION);
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "++++++++++++++++ onStop +++++++++++++++++");
|
||||
mConstance.isDownloading = false;
|
||||
mListener.onStop(mConstance.CURRENT_LOCATION);
|
||||
CONSTANCE.isDownloading = false;
|
||||
mListener.onStop(CONSTANCE.CURRENT_LOCATION);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@ -183,44 +180,20 @@ final class SingleThreadTask implements Runnable {
|
||||
private void progress(long len) {
|
||||
synchronized (LOCK) {
|
||||
mChildCurrentLocation += len;
|
||||
mConstance.CURRENT_LOCATION += len;
|
||||
mListener.onProgress(mConstance.CURRENT_LOCATION);
|
||||
//mHandler.sendEmptyMessage(1);
|
||||
//mHandler.post(t);
|
||||
CONSTANCE.CURRENT_LOCATION += len;
|
||||
mListener.onProgress(CONSTANCE.CURRENT_LOCATION);
|
||||
}
|
||||
}
|
||||
|
||||
Handler mHandler = new Handler(Looper.getMainLooper()) {
|
||||
@Override public void handleMessage(Message msg) {
|
||||
super.handleMessage(msg);
|
||||
mListener.onProgress(mConstance.CURRENT_LOCATION);
|
||||
}
|
||||
};
|
||||
|
||||
Thread t = new Thread(new Runnable() {
|
||||
@Override public void run() {
|
||||
mListener.onProgress(mConstance.CURRENT_LOCATION);
|
||||
}
|
||||
});
|
||||
|
||||
//Handler handler = new Handler(){
|
||||
// @Override public void handleMessage(Message msg) {
|
||||
// super.handleMessage(msg);
|
||||
// mListener.onProgress(mConstance.CURRENT_LOCATION);
|
||||
// }
|
||||
//};
|
||||
|
||||
Thread thread = new Thread();
|
||||
|
||||
/**
|
||||
* 取消下载
|
||||
*/
|
||||
protected void cancel() {
|
||||
synchronized (LOCK) {
|
||||
if (mConfigEntity.isSupportBreakpoint) {
|
||||
mConstance.CANCEL_NUM++;
|
||||
CONSTANCE.CANCEL_NUM++;
|
||||
Log.d(TAG, "++++++++++ thread_" + mConfigEntity.THREAD_ID + "_cancel ++++++++++");
|
||||
if (mConstance.isCancel()) {
|
||||
if (CONSTANCE.isCancel()) {
|
||||
File configFile = new File(mConfigFPath);
|
||||
if (configFile.exists()) {
|
||||
configFile.delete();
|
||||
@ -229,12 +202,12 @@ final class SingleThreadTask implements Runnable {
|
||||
mConfigEntity.TEMP_FILE.delete();
|
||||
}
|
||||
Log.d(TAG, "++++++++++++++++ onCancel +++++++++++++++++");
|
||||
mConstance.isDownloading = false;
|
||||
CONSTANCE.isDownloading = false;
|
||||
mListener.onCancel();
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "++++++++++++++++ onCancel +++++++++++++++++");
|
||||
mConstance.isDownloading = false;
|
||||
CONSTANCE.isDownloading = false;
|
||||
mListener.onCancel();
|
||||
}
|
||||
}
|
||||
@ -247,8 +220,8 @@ final class SingleThreadTask implements Runnable {
|
||||
Exception ex) {
|
||||
synchronized (LOCK) {
|
||||
try {
|
||||
mConstance.isDownloading = false;
|
||||
mConstance.isStop = true;
|
||||
CONSTANCE.isDownloading = false;
|
||||
CONSTANCE.isStop = true;
|
||||
if (ex != null) {
|
||||
Log.e(TAG, CommonUtil.getPrintException(ex));
|
||||
}
|
||||
@ -257,7 +230,7 @@ final class SingleThreadTask implements Runnable {
|
||||
String location = String.valueOf(currentLocation);
|
||||
writeConfig(dEntity.TEMP_FILE.getName() + "_record_" + dEntity.THREAD_ID, location);
|
||||
}
|
||||
if (mConstance.isFail()) {
|
||||
if (CONSTANCE.isFail()) {
|
||||
Log.d(TAG, "++++++++++++++++ onFail +++++++++++++++++");
|
||||
mListener.onFail();
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ import java.util.Map;
|
||||
public class DBConfig {
|
||||
static Map<String, Class> mapping = new HashMap<>();
|
||||
static String DB_NAME;
|
||||
static int VERSION = 2;
|
||||
static int VERSION = 3;
|
||||
|
||||
static {
|
||||
if (TextUtils.isEmpty(DB_NAME)) {
|
||||
|
@ -1,228 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.aria.util;
|
||||
|
||||
import android.util.Log;
|
||||
import com.arialyy.aria.core.AriaManager;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* Created by AriaL on 2016/12/8.
|
||||
* 信息配置
|
||||
*/
|
||||
public class Configuration_1 {
|
||||
private static final String TAG = "Configuration_1";
|
||||
private static final String CONFIG_FILE = "/Aria/ADConfig.properties";
|
||||
/**
|
||||
* 当前调度器最大下载数,默认最大下载数为 “2”
|
||||
*/
|
||||
private static final String DOWNLOAD_NUM = "DOWNLOAD_NUM";
|
||||
/**
|
||||
* 失败重试次数,默认最多重试 10 次
|
||||
*/
|
||||
private static final String RE_TRY_NUM = "RE_TRY_NUM";
|
||||
/**
|
||||
* 是否打开下载广播,默认 false
|
||||
*/
|
||||
private static final String OPEN_BROADCAST = "OPEN_BROADCAST";
|
||||
/**
|
||||
* 失败重试间隔时间,默认 4000 ms
|
||||
*/
|
||||
private static final String RE_TRY_INTERVAL = "RE_TRY_INTERVAL";
|
||||
/**
|
||||
* 超时时间,默认 10000 ms
|
||||
*/
|
||||
private static final String DOWNLOAD_TIME_OUT = "DOWNLOAD_TIME_OUT";
|
||||
/**
|
||||
* 设置最大速度
|
||||
*/
|
||||
private static final String MAX_SPEED = "MAX_SPEED";
|
||||
|
||||
public static boolean isOpenBreadCast = false;
|
||||
|
||||
private static Configuration_1 INSTANCE = null;
|
||||
private File mConfigFile = null;
|
||||
private static final Object LOCK = new Object();
|
||||
|
||||
public static Configuration_1 getInstance() {
|
||||
if (INSTANCE == null) {
|
||||
synchronized (LOCK) {
|
||||
INSTANCE = new Configuration_1();
|
||||
}
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private Configuration_1() {
|
||||
mConfigFile = new File(AriaManager.APP.getFilesDir().getPath() + CONFIG_FILE);
|
||||
try {
|
||||
if (!mConfigFile.exists()) {
|
||||
mConfigFile.getParentFile().mkdirs();
|
||||
mConfigFile.createNewFile();
|
||||
init();
|
||||
} else {
|
||||
isOpenBreadCast = isOpenBroadcast();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
Map<String, String> config = new WeakHashMap<>();
|
||||
config.put(DOWNLOAD_NUM, 2 + "");
|
||||
config.put(RE_TRY_NUM, 10 + "");
|
||||
config.put(OPEN_BROADCAST, false + "");
|
||||
config.put(RE_TRY_INTERVAL, 4000 + "");
|
||||
config.put(DOWNLOAD_TIME_OUT, 10000 + "");
|
||||
config.put(MAX_SPEED, 64 + "");
|
||||
saveConfig(config);
|
||||
}
|
||||
|
||||
private void saveConfig(Map<String, String> config) {
|
||||
if (config == null || config.size() == 0) {
|
||||
return;
|
||||
}
|
||||
Properties properties = CommonUtil.loadConfig(mConfigFile);
|
||||
Set<String> keys = config.keySet();
|
||||
for (String key : keys) {
|
||||
properties.setProperty(key, config.get(key));
|
||||
}
|
||||
CommonUtil.saveConfig(mConfigFile, properties);
|
||||
}
|
||||
|
||||
private void save(String key, String value) {
|
||||
Map<String, String> map = new WeakHashMap<>();
|
||||
map.put(key, value);
|
||||
saveConfig(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置最大下载速度
|
||||
*/
|
||||
public void setMaxSpeed(Speed speed) {
|
||||
save(MAX_SPEED, speed.buf + "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最大速度
|
||||
*/
|
||||
public int getMaxSpeed() {
|
||||
return Integer.parseInt(CommonUtil.loadConfig(mConfigFile).getProperty(MAX_SPEED, "8192"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下载超时时间
|
||||
*
|
||||
* @return 默认4000ms
|
||||
*/
|
||||
public int getTimeOut() {
|
||||
return Integer.parseInt(CommonUtil.loadConfig(mConfigFile).getProperty(DOWNLOAD_TIME_OUT));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置重试间隔
|
||||
*/
|
||||
public void setTimeOut(int timeOut) {
|
||||
if (timeOut < 10000) {
|
||||
Log.w(TAG, "下载超时时间不能小于 10000 ms");
|
||||
return;
|
||||
}
|
||||
save(DOWNLOAD_TIME_OUT, timeOut + "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取失败重试间隔时间
|
||||
*
|
||||
* @return 默认4000ms
|
||||
*/
|
||||
public int getReTryInterval() {
|
||||
return Integer.parseInt(CommonUtil.loadConfig(mConfigFile).getProperty(RE_TRY_INTERVAL));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置重试间隔
|
||||
*/
|
||||
public void setReTryInterval(int reTryInterval) {
|
||||
if (reTryInterval < 4000) {
|
||||
Log.w(TAG, "重试间隔不能小于4000ms");
|
||||
return;
|
||||
}
|
||||
save(RE_TRY_INTERVAL, reTryInterval + "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最大下载数
|
||||
*
|
||||
* @return 默认返回2
|
||||
*/
|
||||
public int getDownloadNum() {
|
||||
return Integer.parseInt(CommonUtil.loadConfig(mConfigFile).getProperty(DOWNLOAD_NUM));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置最大下载数
|
||||
*/
|
||||
public void setDownloadNum(int downloadNum) {
|
||||
if (downloadNum < 1) {
|
||||
Log.w(TAG, "最大下载数不能小于1");
|
||||
return;
|
||||
}
|
||||
save(DOWNLOAD_NUM, downloadNum + "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最大重试数
|
||||
*
|
||||
* @return 默认返回 10
|
||||
*/
|
||||
public int getReTryNum() {
|
||||
return Integer.parseInt(CommonUtil.loadConfig(mConfigFile).getProperty(RE_TRY_NUM));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置重试数
|
||||
*/
|
||||
public void setReTryNum(int reTryNum) {
|
||||
if (reTryNum < 1) {
|
||||
Log.w(TAG, "最大下载数不能小于1");
|
||||
return;
|
||||
}
|
||||
save(RE_TRY_NUM, reTryNum + "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否打开下载广播
|
||||
*
|
||||
* @return 默认false
|
||||
*/
|
||||
public boolean isOpenBroadcast() {
|
||||
return Boolean.parseBoolean(CommonUtil.loadConfig(mConfigFile).getProperty(RE_TRY_NUM));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置是否打开下载广播
|
||||
*/
|
||||
public void setOpenBroadcast(boolean openBroadcast) {
|
||||
isOpenBreadCast = openBroadcast;
|
||||
save(OPEN_BROADCAST, openBroadcast + "");
|
||||
}
|
||||
}
|
@ -15,27 +15,128 @@
|
||||
*/
|
||||
package com.arialyy.aria.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import com.arialyy.aria.window.FileEntity;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Aria.Lao on 2017/3/21.
|
||||
*/
|
||||
|
||||
public class FileUtil {
|
||||
|
||||
Context mContext;
|
||||
private static final String TAG = "FileUtil";
|
||||
|
||||
public FileUtil(Context context) {
|
||||
mContext = context;
|
||||
/**
|
||||
* 通过流创建文件
|
||||
*/
|
||||
public static void createFileFormInputStream(InputStream is, String path) {
|
||||
try {
|
||||
FileOutputStream fos = new FileOutputStream(path);
|
||||
byte[] buf = new byte[1376];
|
||||
while (is.read(buf) > 0) {
|
||||
fos.write(buf, 0, buf.length);
|
||||
}
|
||||
is.close();
|
||||
fos.flush();
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验文件MD5码
|
||||
*/
|
||||
public static boolean checkMD5(String md5, File updateFile) {
|
||||
if (TextUtils.isEmpty(md5) || updateFile == null) {
|
||||
Log.e(TAG, "MD5 string empty or updateFile null");
|
||||
return false;
|
||||
}
|
||||
|
||||
String calculatedDigest = getFileMD5(updateFile);
|
||||
if (calculatedDigest == null) {
|
||||
Log.e(TAG, "calculatedDigest null");
|
||||
return false;
|
||||
}
|
||||
return calculatedDigest.equalsIgnoreCase(md5);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验文件MD5码
|
||||
*/
|
||||
public static boolean checkMD5(String md5, InputStream is) {
|
||||
if (TextUtils.isEmpty(md5) || is == null) {
|
||||
Log.e(TAG, "MD5 string empty or updateFile null");
|
||||
return false;
|
||||
}
|
||||
|
||||
String calculatedDigest = getFileMD5(is);
|
||||
if (calculatedDigest == null) {
|
||||
Log.e(TAG, "calculatedDigest null");
|
||||
return false;
|
||||
}
|
||||
return calculatedDigest.equalsIgnoreCase(md5);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件MD5码
|
||||
*/
|
||||
public static String getFileMD5(File updateFile) {
|
||||
InputStream is;
|
||||
try {
|
||||
is = new FileInputStream(updateFile);
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.e(TAG, "Exception while getting FileInputStream", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
return getFileMD5(is);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件MD5码
|
||||
*/
|
||||
public static String getFileMD5(InputStream is) {
|
||||
MessageDigest digest;
|
||||
try {
|
||||
digest = MessageDigest.getInstance("MD5");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
Log.e(TAG, "Exception while getting digest", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] buffer = new byte[8192];
|
||||
int read;
|
||||
try {
|
||||
while ((read = is.read(buffer)) > 0) {
|
||||
digest.update(buffer, 0, read);
|
||||
}
|
||||
byte[] md5sum = digest.digest();
|
||||
BigInteger bigInt = new BigInteger(1, md5sum);
|
||||
String output = bigInt.toString(16);
|
||||
// Fill to 32 chars
|
||||
output = String.format("%32s", output).replace(' ', '0');
|
||||
return output;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Unable to process file for MD5", e);
|
||||
} finally {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Exception on closing MD5 input stream", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -54,66 +155,4 @@ public class FileUtil {
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件类型
|
||||
*/
|
||||
public FileType getFileType(String path) {
|
||||
String exName = getExName(path);
|
||||
String type = "";
|
||||
FileType fType = null;
|
||||
if (exName.equalsIgnoreCase("apk")) {
|
||||
fType = new FileType("应用", getApkIcon(path));
|
||||
} else if (exName.equalsIgnoreCase("img")
|
||||
|| exName.equalsIgnoreCase("png")
|
||||
|| exName.equalsIgnoreCase("jpg")
|
||||
|| exName.equalsIgnoreCase("jepg")) {
|
||||
//fType = new FileType("图片", )
|
||||
} else if (exName.equalsIgnoreCase("mp3") || exName.equalsIgnoreCase("wm")) {
|
||||
//fType = new FileType("音乐", );
|
||||
} else if (exName.equalsIgnoreCase("mp4")
|
||||
|| exName.equalsIgnoreCase("rm")
|
||||
|| exName.equalsIgnoreCase("rmvb")) {
|
||||
//fType = new FileType("视频", );
|
||||
}
|
||||
return fType;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取扩展名
|
||||
*/
|
||||
public String getExName(String path) {
|
||||
int separatorIndex = path.lastIndexOf(".");
|
||||
return (separatorIndex < 0) ? path : path.substring(separatorIndex + 1, path.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取apk文件的icon
|
||||
*
|
||||
* @param path apk文件路径
|
||||
*/
|
||||
public Drawable getApkIcon(String path) {
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
PackageInfo info = pm.getPackageArchiveInfo(path, PackageManager.GET_ACTIVITIES);
|
||||
if (info != null) {
|
||||
ApplicationInfo appInfo = info.applicationInfo;
|
||||
//android有bug,需要下面这两句话来修复才能获取apk图片
|
||||
appInfo.sourceDir = path;
|
||||
appInfo.publicSourceDir = path;
|
||||
// String packageName = appInfo.packageName; //得到安装包名称
|
||||
// String version=info.versionName; //得到版本信息
|
||||
return pm.getApplicationIcon(appInfo);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
class FileType {
|
||||
String name;
|
||||
Drawable icon;
|
||||
|
||||
public FileType(String name, Drawable icon) {
|
||||
this.name = name;
|
||||
this.icon = icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
129
README.md
129
README.md
@ -1,15 +1,20 @@
|
||||
# Aria
|
||||
</br>
|
||||
Aria,让上传、下载更容易实现</br>
|
||||
Aria项目源于15年工作中遇到的一个文件下载管理的需求,当时被下载折磨的痛不欲生,从那时起便萌生了编写一个简单易用,稳当高效的下载框架,aria经历了1.0到3.0的开发,算是越来越接近当初所制定的目标了。
|
||||
|
||||
Aria有以下特点:
|
||||
- 简单
|
||||
- 可在Dialog、popupWindow等组件中使用
|
||||
- 支持多线程、多任务下载
|
||||
- 支持多任务自动调度
|
||||
- 可以直接获取速度
|
||||
- 支持https地址下载
|
||||
- 支持上传操作
|
||||
+ 简单、方便
|
||||
- 可以在Activity、Service、Fragment、Dialog、popupWindow、Notification等组件中使用
|
||||
- 支持任务自动调度,使用者不需要关心任务状态切换的逻辑
|
||||
- [通过Aria的事件,能很容易获取当前下载任务的下载状态](#二、下载状态获取)
|
||||
- [一句代码就可以动态设置最大下载数](#通过代码修改Aria参数)
|
||||
- [一句代码加可以获取当前的下载速度](#其它好用的API)
|
||||
- [通过修改配置文件很容易就能修改下载线程数](#通过文件修改Aria配置参数)
|
||||
+ 支持https地址下载
|
||||
- 在配置文件中很容易就可以设置CA证书的信息
|
||||
+ 支持300、301、302重定向下载链接下载
|
||||
+ 支持上传操作
|
||||
|
||||
|
||||
Aria怎样使用?
|
||||
* [下载](#使用)
|
||||
@ -20,7 +25,7 @@ Aria怎样使用?
|
||||
## 下载
|
||||
[](https://bintray.com/arialyy/maven/Aria/_latestVersion)</br>
|
||||
```java
|
||||
compile 'com.arialyy.aria:Aria:3.0.3'
|
||||
compile 'com.arialyy.aria:Aria:3.1.0'
|
||||
```
|
||||
|
||||
## 示例
|
||||
@ -72,7 +77,8 @@ compile 'com.arialyy.aria:Aria:3.0.3'
|
||||
Aria.download(this).load(DOWNLOAD_URL).cancel();
|
||||
```
|
||||
|
||||
### 二、如果你希望读取下载进度或下载信息,那么你需要创建事件类,并在onResume(Activity、Fragment)或构造函数(Dialog、PopupWindow),将该事件类注册到Aria管理器。
|
||||
### 二、下载状态获取
|
||||
如果你希望读取下载进度或下载信息,那么你需要创建事件类,并在onResume(Activity、Fragment)或构造函数(Dialog、PopupWindow),将该事件类注册到Aria管理器。
|
||||
* 创建事件类
|
||||
|
||||
```java
|
||||
@ -104,8 +110,99 @@ compile 'com.arialyy.aria:Aria:3.0.3'
|
||||
}
|
||||
```
|
||||
|
||||
### 关于下载的其它api
|
||||
[Download API](https://github.com/AriaLyy/Aria/blob/master/DownloadApi.md)
|
||||
### 三、Aria参数配置
|
||||
#### 通过文件修改Aria配置参数
|
||||
创建`aria_config.xml`文件,将其放在`assets`目录下,添加以下内容
|
||||
```xml
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<aria>
|
||||
|
||||
<!--注意,修改该配置文件中的属性会覆盖代码中所设置的属性-->
|
||||
<download>
|
||||
|
||||
<!--设置下载线程,线程下载数改变后,新的下载任务才会生效-->
|
||||
<threadNum value="4"/>
|
||||
|
||||
<!--是否打开下载广播,默认为false-->
|
||||
<openBroadcast value="false"/>
|
||||
|
||||
<!--设置下载队列最大任务数, 默认为2-->
|
||||
<maxTaskNum value="2"/>
|
||||
|
||||
<!--设置下载失败,重试次数,默认为10-->
|
||||
<reTryNum value="10"/>
|
||||
|
||||
<!--设置重试间隔,单位为毫秒,默认2000毫秒-->
|
||||
<reTryInterval value="2000"/>
|
||||
|
||||
<!--设置url连接超时时间,单位为毫秒,默认5000毫秒-->
|
||||
<connectTimeOut value="5000"/>
|
||||
|
||||
<!--设置IO流读取时间,单位为毫秒,默认20000毫秒,该时间不能少于10000毫秒-->
|
||||
<iOTimeOut value="20000"/>
|
||||
|
||||
<!--设置写文件buff大小,该数值大小不能小于2048,数值变小,下载速度会变慢-->
|
||||
<buffSize value="8192"/>
|
||||
|
||||
<!--设置https ca 证书信息;path 为assets目录下的CA证书完整路径,name 为CA证书名-->
|
||||
<ca name="" path=""/>
|
||||
|
||||
<!--是否需要转换速度单位,转换完成后为:1b/s、1k/s、1m/s、1g/s、1t/s,如果不需要将返回byte长度-->
|
||||
<cnvertSpeed value="false"/>
|
||||
|
||||
</download>
|
||||
|
||||
<upload>
|
||||
<!--是否打开上传广播,默认为false-->
|
||||
<openBroadcast value="false"/>
|
||||
|
||||
<!--设置上传队列最大任务数, 默认为2-->
|
||||
<maxTaskNum value="2"/>
|
||||
|
||||
<!--设置上传失败,重试次数,默认为10-->
|
||||
<reTryNum value="10"/>
|
||||
|
||||
<!--设置重试间隔,单位为毫秒-->
|
||||
<reTryInterval value="2000"/>
|
||||
|
||||
<!--设置url连接超时时间,单位为毫秒,默认5000毫秒-->
|
||||
<connectTimeOut value="5000"/>
|
||||
</upload>
|
||||
|
||||
</aria>
|
||||
```
|
||||
|
||||
#### 通过代码修改Aria参数
|
||||
除了文件方式外修改Aria参数外,同样的,你也可以在代码中动态修改Aria参数</br>
|
||||
通过`Aria.get(this).getDownloadConfig()`或`Aria.get(this).getUploadConfig()`直接获取配置文件,然后修改参数</br>
|
||||
如以下所示:
|
||||
```java
|
||||
// 修改最大下载数,调用完成后,立即生效
|
||||
// 如当前下载任务数是4,修改完成后,当前任务数会被Aria自动调度任务数
|
||||
Aria.get(this).getDownloadConfig().setMaxTaskNum(3);
|
||||
```
|
||||
|
||||
### 其它好用的API
|
||||
* 停止所有任务
|
||||
|
||||
```java
|
||||
Aria.download(this).stopAllTask();
|
||||
```
|
||||
* 删除所有任务
|
||||
|
||||
```java
|
||||
Aria.download(this).removeAllTask();
|
||||
```
|
||||
* 获取当前任务的下载速度
|
||||
速度参数有点特殊,需要[下载事件支持](#下载事件监听)
|
||||
``` java
|
||||
@Override public void onTaskRunning(DownloadTask task) {
|
||||
//如果你打开了速度单位转换配置,将可以通过以下方法获取带单位的下载速度,如:1 m/s
|
||||
String convertSpeed = task.getConvertSpeed();
|
||||
//如果你有自己的单位格式,可以通过以下方法获取原始byte长度
|
||||
long speed = task.getSpeed();
|
||||
}
|
||||
```
|
||||
|
||||
**tips:为了防止内存泄露的情况,事件类需要使用staic进行修饰**
|
||||
|
||||
@ -132,9 +229,7 @@ compile 'com.arialyy.aria:Aria:3.0.3'
|
||||
* 取消上传
|
||||
|
||||
```java
|
||||
Aria.upload(this)
|
||||
.load(filePath)
|
||||
.cancel();
|
||||
Aria.upload(this).load(filePath).cancel();
|
||||
```
|
||||
|
||||
## 其他
|
||||
@ -142,7 +237,11 @@ compile 'com.arialyy.aria:Aria:3.0.3'
|
||||
|
||||
***
|
||||
|
||||
## 后续版本开发规划
|
||||
* 实现上传队列调度功能
|
||||
|
||||
## 开发日志
|
||||
+ v_3.1.0 添加Aria配置文件,优化代码
|
||||
+ v_3.0.3 修复暂停后删除任务,闪退问题,添加删除记录的api
|
||||
+ v_3.0.2 支持30x重定向链接下载
|
||||
+ v_3.0.0 添加上传任务支持,修复一些已发现的bug
|
||||
|
@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<aria>
|
||||
|
||||
|
||||
<!--注意,修改该配置文件中的属性会覆盖代码中所设置的属性-->
|
||||
<download>
|
||||
|
||||
<!--设置下载线程-->
|
||||
<threadNum value="3"/>
|
||||
<!--设置下载线程,线程下载数改变后,新的下载任务才会生效-->
|
||||
<threadNum value="4"/>
|
||||
|
||||
<!--是否打开下载广播,默认为false-->
|
||||
<openBroadcast value="false"/>
|
||||
@ -31,6 +31,9 @@
|
||||
<!--设置https ca 证书信息;path 为assets目录下的CA证书完整路径,name 为CA证书名-->
|
||||
<ca name="" path=""/>
|
||||
|
||||
<!--是否需要转换速度单位,转换完成后为:1b/s、1k/s、1m/s、1g/s、1t/s,如果不需要将返回byte长度-->
|
||||
<cnvertSpeed value="false"/>
|
||||
|
||||
</download>
|
||||
|
||||
<upload>
|
||||
|
Reference in New Issue
Block a user