laoyuyu 5 years ago
parent b1bc4529c0
commit a2604a9431
  1. 6
      Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
  2. 1
      Aria/src/main/java/com/arialyy/aria/core/common/AbsFileer.java
  3. 5
      Aria/src/main/java/com/arialyy/aria/core/common/AbsThreadTask.java
  4. 3
      Aria/src/main/java/com/arialyy/aria/core/common/NormalFileer.java
  5. 3
      Aria/src/main/java/com/arialyy/aria/core/download/DGTaskWrapper.java
  6. 4
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupListener.java
  7. 2
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTarget.java
  8. 8
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java
  9. 6
      Aria/src/main/java/com/arialyy/aria/core/download/group/AbsGroupUtil.java
  10. 4
      Aria/src/main/java/com/arialyy/aria/core/download/group/ChildDLoadListener.java
  11. 40
      Aria/src/main/java/com/arialyy/aria/core/download/group/DGroupUtil.java
  12. 2
      Aria/src/main/java/com/arialyy/aria/core/download/group/FtpDirDownloadUtil.java
  13. 4
      Aria/src/main/java/com/arialyy/aria/core/download/group/GroupRunState.java
  14. 2
      Aria/src/main/java/com/arialyy/aria/core/download/group/IDGroupListener.java
  15. 29
      Aria/src/main/java/com/arialyy/aria/core/download/group/SimpleSchedulers.java
  16. 10
      Aria/src/main/java/com/arialyy/aria/core/download/group/SubDLoadUtil.java
  17. 4
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsEntity.java
  18. 3
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalEntity.java
  19. 7
      Aria/src/main/java/com/arialyy/aria/orm/DelegateWrapper.java
  20. 26
      Aria/src/main/java/com/arialyy/aria/orm/SqlHelper.java
  21. 8
      DEV_LOG.md
  22. 58
      README.md
  23. 2
      app/src/main/assets/aria_config.xml
  24. 1
      app/src/main/java/com/arialyy/simple/core/download/HttpDownloadModule.java
  25. 9
      app/src/main/java/com/arialyy/simple/core/download/group/DownloadGroupActivity.java
  26. 20
      app/src/main/java/com/arialyy/simple/widget/SubStateLinearLayout.java
  27. 3
      app/src/main/res/values/strings.xml
  28. 2
      build.gradle
  29. BIN
      img/m3u8VodDownload.gif
  30. 7
      py/download.py

@ -92,6 +92,7 @@ import org.xml.sax.SAXException;
private AppConfig mAConfig; private AppConfig mAConfig;
private DGroupConfig mDGConfig; private DGroupConfig mDGConfig;
private Handler mAriaHandler; private Handler mAriaHandler;
private DelegateWrapper mDbWrapper;
private AriaManager(Context context) { private AriaManager(Context context) {
APP = context.getApplicationContext(); APP = context.getApplicationContext();
@ -172,7 +173,7 @@ import org.xml.sax.SAXException;
dbConfig.delete(); dbConfig.delete();
} }
} }
DelegateWrapper.init(context.getApplicationContext()); mDbWrapper = DelegateWrapper.init(context.getApplicationContext());
} }
private void initAria() { private void initAria() {
@ -192,6 +193,9 @@ import org.xml.sax.SAXException;
}; };
String sql = "UPDATE %s SET state=2 WHERE state IN (3,4,5,6)"; String sql = "UPDATE %s SET state=2 WHERE state IN (3,4,5,6)";
for (Class clazz : clazzs) { for (Class clazz : clazzs) {
if (!mDbWrapper.tableExists(clazz)) {
continue;
}
String temp = String.format(sql, clazz.getSimpleName()); String temp = String.format(sql, clazz.getSimpleName());
DbEntity.exeSql(temp); DbEntity.exeSql(temp);
} }

@ -160,7 +160,6 @@ public abstract class AbsFileer<ENTITY extends AbsNormalEntity, TASK_WRAPPER ext
} }
public synchronized void closeTimer() { public synchronized void closeTimer() {
ALog.i(TAG, "关闭定时器");
if (mTimer != null && !mTimer.isShutdown()) { if (mTimer != null && !mTimer.isShutdown()) {
mTimer.shutdown(); mTimer.shutdown();
} }

@ -173,9 +173,10 @@ public abstract class AbsThreadTask<ENTITY extends AbsNormalEntity, TASK_WRAPPER
*/ */
public void setMaxSpeed(int speed) { public void setMaxSpeed(int speed) {
if (mSpeedBandUtil != null) { if (mSpeedBandUtil == null) {
mSpeedBandUtil.setMaxRate(speed); mSpeedBandUtil = new BandwidthLimiter(getMaxSpeed(), getConfig().startThreadNum);
} }
mSpeedBandUtil.setMaxRate(speed);
} }
/** /**

@ -18,9 +18,7 @@ package com.arialyy.aria.core.common;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import com.arialyy.aria.core.download.BaseDListener; import com.arialyy.aria.core.download.BaseDListener;
import com.arialyy.aria.core.event.Event;
import com.arialyy.aria.core.event.EventMsgUtil; import com.arialyy.aria.core.event.EventMsgUtil;
import com.arialyy.aria.core.event.SpeedEvent;
import com.arialyy.aria.core.inf.AbsNormalEntity; import com.arialyy.aria.core.inf.AbsNormalEntity;
import com.arialyy.aria.core.inf.AbsTaskWrapper; import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.core.inf.IEventListener; import com.arialyy.aria.core.inf.IEventListener;
@ -190,6 +188,7 @@ public abstract class NormalFileer<ENTITY extends AbsNormalEntity, TASK_WRAPPER
if (mListener instanceof BaseDListener) { if (mListener instanceof BaseDListener) {
((BaseDListener) mListener).supportBreakpoint(false); ((BaseDListener) mListener).supportBreakpoint(false);
} }
mStartThreadNum = 1;
AbsThreadTask task = createSingThreadTask(mRecord.threadRecords.get(0), 1); AbsThreadTask task = createSingThreadTask(mRecord.threadRecords.get(0), 1);
if (task == null) return; if (task == null) return;

@ -46,9 +46,6 @@ public class DGTaskWrapper extends AbsGroupTaskWrapper<DownloadGroupEntity, DTas
this.unknownSize = unknownSize; this.unknownSize = unknownSize;
} }
/**
* 组名
*/
@Override public String getKey() { @Override public String getKey() {
return getEntity().getKey(); return getEntity().getKey();
} }

@ -18,7 +18,7 @@ package com.arialyy.aria.core.download;
import android.os.Handler; import android.os.Handler;
import com.arialyy.aria.core.common.BaseListener; import com.arialyy.aria.core.common.BaseListener;
import com.arialyy.aria.core.common.RecordHandler; import com.arialyy.aria.core.common.RecordHandler;
import com.arialyy.aria.core.download.group.IDownloadGroupListener; import com.arialyy.aria.core.download.group.IDGroupListener;
import com.arialyy.aria.core.inf.GroupSendParams; import com.arialyy.aria.core.inf.GroupSendParams;
import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.TaskSchedulerType; import com.arialyy.aria.core.inf.TaskSchedulerType;
@ -34,7 +34,7 @@ import com.arialyy.aria.util.RecordUtil;
*/ */
class DownloadGroupListener class DownloadGroupListener
extends BaseListener<DownloadGroupEntity, DGTaskWrapper, DownloadGroupTask> extends BaseListener<DownloadGroupEntity, DGTaskWrapper, DownloadGroupTask>
implements IDownloadGroupListener { implements IDGroupListener {
private GroupSendParams<DownloadGroupTask, DownloadEntity> mSeedEntity; private GroupSendParams<DownloadGroupTask, DownloadEntity> mSeedEntity;
DownloadGroupListener(DownloadGroupTask task, Handler outHandler) { DownloadGroupListener(DownloadGroupTask task, Handler outHandler) {

@ -107,7 +107,7 @@ public class DownloadGroupTarget extends AbsDGTarget<DownloadGroupTarget> {
/** /**
* 如果无法获取到组合任务到总长度请调用该方法 * 如果无法获取到组合任务到总长度请调用该方法
* 请注意 * 请注意
* 1如果组合任务到子任务数过多请不要使用该标志位否则Aria将需要消耗大量的时间获取组合任务的总长度 * 1如果组合任务到子任务数过多请不要使用该标志位否则Aria将需要消耗大量的时间获取组合任务的总长度直到获取完成组合任务总长度后才会执行下载
* 2如果你的知道组合任务的总长度请使用{@link #setFileSize(long)}设置组合任务的长度 * 2如果你的知道组合任务的总长度请使用{@link #setFileSize(long)}设置组合任务的长度
* 3由于网络或其它原因的存在这种方式获取的组合任务大小有可能是不准确的 * 3由于网络或其它原因的存在这种方式获取的组合任务大小有可能是不准确的
*/ */

@ -20,9 +20,9 @@ import android.os.Looper;
import android.text.TextUtils; import android.text.TextUtils;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.common.IUtil; import com.arialyy.aria.core.common.IUtil;
import com.arialyy.aria.core.download.group.DownloadGroupUtil; import com.arialyy.aria.core.download.group.DGroupUtil;
import com.arialyy.aria.core.download.group.FtpDirDownloadUtil; import com.arialyy.aria.core.download.group.FtpDirDownloadUtil;
import com.arialyy.aria.core.download.group.IDownloadGroupListener; import com.arialyy.aria.core.download.group.IDGroupListener;
import com.arialyy.aria.core.inf.AbsGroupTask; import com.arialyy.aria.core.inf.AbsGroupTask;
import com.arialyy.aria.core.inf.AbsTaskWrapper; import com.arialyy.aria.core.inf.AbsTaskWrapper;
import com.arialyy.aria.core.scheduler.ISchedulers; import com.arialyy.aria.core.scheduler.ISchedulers;
@ -57,9 +57,9 @@ public class DownloadGroupTask extends AbsGroupTask<DGTaskWrapper> {
@Override protected synchronized IUtil createUtil() { @Override protected synchronized IUtil createUtil() {
switch (mTaskWrapper.getRequestType()) { switch (mTaskWrapper.getRequestType()) {
case AbsTaskWrapper.D_HTTP: case AbsTaskWrapper.D_HTTP:
return new DownloadGroupUtil((IDownloadGroupListener) mListener, mTaskWrapper); return new DGroupUtil((IDGroupListener) mListener, mTaskWrapper);
case AbsTaskWrapper.D_FTP_DIR: case AbsTaskWrapper.D_FTP_DIR:
return new FtpDirDownloadUtil((IDownloadGroupListener) mListener, mTaskWrapper); return new FtpDirDownloadUtil((IDGroupListener) mListener, mTaskWrapper);
} }
return null; return null;
} }

@ -44,7 +44,7 @@ public abstract class AbsGroupUtil implements IUtil, Runnable {
int HTTP_GROUP = 0xa2; int HTTP_GROUP = 0xa2;
private long mCurrentLocation = 0; private long mCurrentLocation = 0;
protected IDownloadGroupListener mListener; protected IDGroupListener mListener;
private ScheduledThreadPoolExecutor mTimer; private ScheduledThreadPoolExecutor mTimer;
private long mUpdateInterval; private long mUpdateInterval;
private boolean isStop = false, isCancel = false; private boolean isStop = false, isCancel = false;
@ -55,7 +55,7 @@ public abstract class AbsGroupUtil implements IUtil, Runnable {
DGTaskWrapper mGTWrapper; DGTaskWrapper mGTWrapper;
GroupRunState mState; GroupRunState mState;
AbsGroupUtil(IDownloadGroupListener listener, DGTaskWrapper groupWrapper) { AbsGroupUtil(IDGroupListener listener, DGTaskWrapper groupWrapper) {
mListener = listener; mListener = listener;
mGTWrapper = groupWrapper; mGTWrapper = groupWrapper;
mUpdateInterval = Configuration.getInstance().downloadCfg.getUpdateInterval(); mUpdateInterval = Configuration.getInstance().downloadCfg.getUpdateInterval();
@ -195,7 +195,7 @@ public abstract class AbsGroupUtil implements IUtil, Runnable {
/** /**
* onStop前的操作 * onStop前的操作
* *
* @return 返回{@code true}直接回调{@link IDownloadGroupListener#onStop(long)} * @return 返回{@code true}直接回调{@link IDGroupListener#onStop(long)}
*/ */
protected boolean onPreStop() { protected boolean onPreStop() {

@ -26,7 +26,7 @@ import com.arialyy.aria.util.CommonUtil;
/** /**
* 子任务事件监听 * 子任务事件监听
*/ */
class ChildDownloadListener implements IDownloadListener { class ChildDLoadListener implements IDownloadListener {
private DownloadEntity subEntity; private DownloadEntity subEntity;
private int RUN_SAVE_INTERVAL = 5 * 1000; //5s保存一次下载中的进度 private int RUN_SAVE_INTERVAL = 5 * 1000; //5s保存一次下载中的进度
private long lastSaveTime; private long lastSaveTime;
@ -34,7 +34,7 @@ class ChildDownloadListener implements IDownloadListener {
private Handler schedulers; private Handler schedulers;
private SubDLoadUtil loader; private SubDLoadUtil loader;
ChildDownloadListener(Handler schedulers, SubDLoadUtil loader) { ChildDLoadListener(Handler schedulers, SubDLoadUtil loader) {
this.loader = loader; this.loader = loader;
this.schedulers = schedulers; this.schedulers = schedulers;
subEntity = loader.getEntity(); subEntity = loader.getEntity();

@ -25,11 +25,12 @@ import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.downloader.HttpFileInfoThread; import com.arialyy.aria.core.download.downloader.HttpFileInfoThread;
import com.arialyy.aria.core.inf.AbsEntity; import com.arialyy.aria.core.inf.AbsEntity;
import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.IHttpFileLenAdapter;
import com.arialyy.aria.exception.AriaIOException; import com.arialyy.aria.exception.AriaIOException;
import com.arialyy.aria.exception.BaseException; import com.arialyy.aria.exception.BaseException;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@ -37,13 +38,14 @@ import java.util.concurrent.Executors;
* Created by AriaL on 2017/6/30. * Created by AriaL on 2017/6/30.
* 任务组下载工具 * 任务组下载工具
*/ */
public class DownloadGroupUtil extends AbsGroupUtil implements IUtil { public class DGroupUtil extends AbsGroupUtil implements IUtil {
private static final String TAG = "DownloadGroupUtil"; private static final String TAG = "DownloadGroupUtil";
private final Object LOCK = new Object(); private final Object LOCK = new Object();
private ExecutorService mPool = null; private ExecutorService mPool = null;
private boolean getLenComplete = false; private boolean getLenComplete = false;
private List<DTaskWrapper> mTempWrapper = new ArrayList<>();
public DownloadGroupUtil(IDownloadGroupListener listener, DGTaskWrapper taskWrapper) { public DGroupUtil(IDGroupListener listener, DGTaskWrapper taskWrapper) {
super(listener, taskWrapper); super(listener, taskWrapper);
} }
@ -101,18 +103,18 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
int failCount; int failCount;
@Override public void run() { @Override public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (DTaskWrapper dTaskWrapper : mGTWrapper.getSubTaskWrapper()) { for (DTaskWrapper dTaskWrapper : mGTWrapper.getSubTaskWrapper()) {
cloneHeader(dTaskWrapper); cloneHeader(dTaskWrapper);
mPool.submit(new HttpFileInfoThread(dTaskWrapper, new OnFileInfoCallback() { mPool.submit(new HttpFileInfoThread(dTaskWrapper, new OnFileInfoCallback() {
@Override public void onComplete(String url, CompleteInfo info) { @Override public void onComplete(String url, CompleteInfo info) {
if (!mGTWrapper.isUnknownSize()) {
createAndStartSubLoader((DTaskWrapper) info.wrapper, false); createAndStartSubLoader((DTaskWrapper) info.wrapper, false);
} else {
mTempWrapper.add((DTaskWrapper) info.wrapper);
}
count++; count++;
checkGetSizeComplete(count, failCount); checkGetSizeComplete(count, failCount);
ALog.d(TAG, "获取子任务信息完成");
} }
@Override public void onFail(AbsEntity entity, BaseException e, boolean needRetry) { @Override public void onFail(AbsEntity entity, BaseException e, boolean needRetry) {
@ -122,6 +124,7 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
mListener.onSubFail((DownloadEntity) entity, new AriaIOException(TAG, mListener.onSubFail((DownloadEntity) entity, new AriaIOException(TAG,
String.format("子任务获取文件长度失败,url:%s", ((DownloadEntity) entity).getUrl()))); String.format("子任务获取文件长度失败,url:%s", ((DownloadEntity) entity).getUrl())));
checkGetSizeComplete(count, failCount); checkGetSizeComplete(count, failCount);
mState.countFailNum(entity.getKey());
} }
})); }));
} }
@ -133,6 +136,11 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
* 检查组合任务大小是否获取完成获取完成后取消阻塞并设置组合任务大小 * 检查组合任务大小是否获取完成获取完成后取消阻塞并设置组合任务大小
*/ */
private void checkGetSizeComplete(int count, int failCount) { private void checkGetSizeComplete(int count, int failCount) {
if (failCount == mGTWrapper.getSubTaskWrapper().size()) {
mListener.onFail(false, new AriaIOException(TAG, "获取子任务长度失败"));
notifyLock();
return;
}
if (count == mGTWrapper.getSubTaskWrapper().size()) { if (count == mGTWrapper.getSubTaskWrapper().size()) {
long size = 0; long size = 0;
for (DTaskWrapper wrapper : mGTWrapper.getSubTaskWrapper()) { for (DTaskWrapper wrapper : mGTWrapper.getSubTaskWrapper()) {
@ -142,14 +150,18 @@ public class DownloadGroupUtil extends AbsGroupUtil implements IUtil {
mGTWrapper.getEntity().setFileSize(size); mGTWrapper.getEntity().setFileSize(size);
mGTWrapper.getEntity().update(); mGTWrapper.getEntity().update();
getLenComplete = true; getLenComplete = true;
ALog.d(TAG, String.format("获取组合任务长度完成,len:%s", size)); ALog.d(TAG, String.format("获取组合任务长度完成,组合任务总长度:%s,失败的只任务数:%s", size, failCount));
} else if (failCount == mGTWrapper.getSubTaskWrapper().size()) { // 未知大小的组合任务,延迟下载
mListener.onFail(true, new AriaIOException(TAG, "获取子任务长度失败")); if (mGTWrapper.isUnknownSize()) {
for (DTaskWrapper wrapper : mTempWrapper) {
createAndStartSubLoader(wrapper, false);
}
} }
IHttpFileLenAdapter lenAdapter = mGTWrapper.asHttp().getFileLenAdapter(); notifyLock();
if (lenAdapter != null && lenAdapter.getClass().isAnonymousClass()) {
mGTWrapper.asHttp().setFileLenAdapter(null);
} }
}
private void notifyLock() {
synchronized (LOCK) { synchronized (LOCK) {
LOCK.notifyAll(); LOCK.notifyAll();
} }

@ -30,7 +30,7 @@ import com.arialyy.aria.exception.BaseException;
public class FtpDirDownloadUtil extends AbsGroupUtil { public class FtpDirDownloadUtil extends AbsGroupUtil {
private String TAG = "FtpDirDownloadUtil"; private String TAG = "FtpDirDownloadUtil";
public FtpDirDownloadUtil(IDownloadGroupListener listener, DGTaskWrapper taskEntity) { public FtpDirDownloadUtil(IDGroupListener listener, DGTaskWrapper taskEntity) {
super(listener, taskEntity); super(listener, taskEntity);
} }

@ -51,7 +51,7 @@ class GroupRunState {
/** /**
* 组合任务监听 * 组合任务监听
*/ */
IDownloadGroupListener listener; IDGroupListener listener;
/** /**
* 子任务队列 * 子任务队列
@ -71,7 +71,7 @@ class GroupRunState {
private String mGroupHash; private String mGroupHash;
GroupRunState(String groupHash, IDownloadGroupListener listener, int subSize, GroupRunState(String groupHash, IDGroupListener listener, int subSize,
SimpleSubQueue queue) { SimpleSubQueue queue) {
this.listener = listener; this.listener = listener;
this.queue = queue; this.queue = queue;

@ -23,7 +23,7 @@ import com.arialyy.aria.exception.BaseException;
* Created by Aria.Lao on 2017/7/20. * Created by Aria.Lao on 2017/7/20.
* 下载任务组事件 * 下载任务组事件
*/ */
public interface IDownloadGroupListener extends IDownloadListener { public interface IDGroupListener extends IDownloadListener {
/** /**
* 子任务预处理 * 子任务预处理

@ -79,7 +79,7 @@ class SimpleSchedulers implements ISchedulers {
* 2stopNum + failNum + completeNum + cacheNum == subSize则认为组合任务停止 * 2stopNum + failNum + completeNum + cacheNum == subSize则认为组合任务停止
* 3failNum == subSize只有全部的子任务都失败了才能任务组合任务失败 * 3failNum == subSize只有全部的子任务都失败了才能任务组合任务失败
*/ */
private synchronized void handleFail(final SubDLoadUtil loader) { private synchronized void handleFail(final SubDLoadUtil loaderUtil) {
Configuration config = Configuration.getInstance(); Configuration config = Configuration.getInstance();
long interval = config.dGroupCfg.getSubReTryInterval(); long interval = config.dGroupCfg.getSubReTryInterval();
@ -88,32 +88,34 @@ class SimpleSchedulers implements ISchedulers {
final int reTryNum = num; final int reTryNum = num;
if ((!NetUtils.isConnected(AriaManager.APP) && !isNotNetRetry) if ((!NetUtils.isConnected(AriaManager.APP) && !isNotNetRetry)
|| loader.getEntity().getFailNum() > reTryNum) { || loaderUtil.getDownloader() == null // 如果获取不到文件信息,loader为空
mQueue.removeTaskFromExecQ(loader); || loaderUtil.getEntity().getFailNum() > reTryNum) {
mGState.listener.onSubFail(loader.getEntity(), new TaskException(TAG, mQueue.removeTaskFromExecQ(loaderUtil);
String.format("任务组子任务【%s】下载失败,下载地址【%s】", loader.getEntity().getFileName(), mGState.listener.onSubFail(loaderUtil.getEntity(), new TaskException(TAG,
loader.getEntity().getUrl()))); String.format("任务组子任务【%s】下载失败,下载地址【%s】", loaderUtil.getEntity().getFileName(),
mGState.countFailNum(loader.getKey()); loaderUtil.getEntity().getUrl())));
mGState.countFailNum(loaderUtil.getKey());
if (mGState.getFailNum() == mGState.getSubSize() if (mGState.getFailNum() == mGState.getSubSize()
|| mGState.getStopNum() + mGState.getFailNum() + mGState.getCompleteNum() || mGState.getStopNum() + mGState.getFailNum() + mGState.getCompleteNum()
== mGState.getSubSize()) { == mGState.getSubSize()) {
mQueue.clear(); mQueue.clear();
mGState.isRunning = false; mGState.isRunning = false;
mGState.listener.onFail(true, new TaskException(TAG, mGState.listener.onFail(false, new TaskException(TAG,
String.format("任务组【%s】下载失败", mGState.getGroupHash()))); String.format("任务组【%s】下载失败", mGState.getGroupHash())));
} else { } else {
startNext(); startNext();
} }
return; return;
} }
final ScheduledThreadPoolExecutor timer = new ScheduledThreadPoolExecutor(1);
// 如果获取不到文件信息,loader为空
final ScheduledThreadPoolExecutor timer = new ScheduledThreadPoolExecutor(1);
timer.schedule(new Runnable() { timer.schedule(new Runnable() {
@Override public void run() { @Override public void run() {
AbsEntity entity = loader.getEntity(); AbsEntity entity = loaderUtil.getEntity();
if (entity.getFailNum() <= reTryNum) { if (entity.getFailNum() <= reTryNum) {
ALog.d(TAG, String.format("任务【%s】开始重试", loader.getEntity().getFileName())); ALog.d(TAG, String.format("任务【%s】开始重试", loaderUtil.getEntity().getFileName()));
loader.reStart(); loaderUtil.reStart();
} else { } else {
startNext(); startNext();
} }
@ -159,7 +161,8 @@ class SimpleSchedulers implements ISchedulers {
mGState.updateCompleteNum(); mGState.updateCompleteNum();
ALog.d(TAG, String.format("总任务数:%s,完成的任务数:%s,失败的任务数:%s,停止的任务数:%s", mGState.getSubSize(), ALog.d(TAG, String.format("总任务数:%s,完成的任务数:%s,失败的任务数:%s,停止的任务数:%s", mGState.getSubSize(),
mGState.getCompleteNum(), mGState.getFailNum(), mGState.getStopNum())); mGState.getCompleteNum(), mGState.getFailNum(), mGState.getStopNum()));
if (mGState.getCompleteNum() == mGState.getSubSize()) { if (mGState.getCompleteNum() + mGState.getFailNum() + mGState.getStopNum()
== mGState.getSubSize()) {
if (mGState.getStopNum() == 0 && mGState.getFailNum() == 0) { if (mGState.getStopNum() == 0 && mGState.getFailNum() == 0) {
mGState.listener.onComplete(); mGState.listener.onComplete();
} else { } else {

@ -38,7 +38,7 @@ class SubDLoadUtil implements IUtil {
private Downloader mDownloader; private Downloader mDownloader;
private DTaskWrapper mWrapper; private DTaskWrapper mWrapper;
private Handler mSchedulers; private Handler mSchedulers;
private ChildDownloadListener mListener; private ChildDLoadListener mListener;
private boolean needGetInfo; private boolean needGetInfo;
/** /**
@ -49,7 +49,7 @@ class SubDLoadUtil implements IUtil {
mWrapper = taskWrapper; mWrapper = taskWrapper;
mSchedulers = schedulers; mSchedulers = schedulers;
this.needGetInfo = needGetInfo; this.needGetInfo = needGetInfo;
mListener = new ChildDownloadListener(mSchedulers, SubDLoadUtil.this); mListener = new ChildDLoadListener(mSchedulers, SubDLoadUtil.this);
} }
@Override public String getKey() { @Override public String getKey() {
@ -73,6 +73,10 @@ class SubDLoadUtil implements IUtil {
} }
} }
public Downloader getDownloader() {
return mDownloader;
}
@Override public long getFileSize() { @Override public long getFileSize() {
return mDownloader == null ? -1 : mDownloader.getFileSize(); return mDownloader == null ? -1 : mDownloader.getFileSize();
} }
@ -112,7 +116,7 @@ class SubDLoadUtil implements IUtil {
} }
@Override public void onFail(AbsEntity entity, BaseException e, boolean needRetry) { @Override public void onFail(AbsEntity entity, BaseException e, boolean needRetry) {
mSchedulers.obtainMessage(ISchedulers.FAIL, SubDLoadUtil.this); mSchedulers.obtainMessage(ISchedulers.FAIL, SubDLoadUtil.this).sendToTarget();
} }
})).start(); })).start();
} else { } else {

@ -18,8 +18,10 @@ package com.arialyy.aria.core.inf;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.orm.annotation.Default;
import com.arialyy.aria.orm.annotation.Ignore; import com.arialyy.aria.orm.annotation.Ignore;
import java.io.Serializable; import java.io.Serializable;
/** /**
* Created by AriaL on 2017/6/29. * Created by AriaL on 2017/6/29.
*/ */
@ -53,6 +55,7 @@ public abstract class AbsEntity extends DbEntity implements IEntity, Parcelable,
/** /**
* 任务状态{@link IEntity} * 任务状态{@link IEntity}
*/ */
@Default("3")
private int state = STATE_WAIT; private int state = STATE_WAIT;
/** /**
* 当前下载进度 * 当前下载进度
@ -68,6 +71,7 @@ public abstract class AbsEntity extends DbEntity implements IEntity, Parcelable,
*/ */
private int percent; private int percent;
@Default("false")
private boolean isComplete = false; private boolean isComplete = false;
/** /**

@ -17,6 +17,7 @@ package com.arialyy.aria.core.inf;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import com.arialyy.aria.orm.annotation.Default;
/** /**
* Created by AriaL on 2017/6/3. * Created by AriaL on 2017/6/3.
@ -36,8 +37,10 @@ public abstract class AbsNormalEntity extends AbsEntity implements Parcelable {
/** /**
* 是否是任务组里面的下载实体 * 是否是任务组里面的下载实体
*/ */
@Default("false")
private boolean isGroupChild = false; private boolean isGroupChild = false;
@Default("false")
private boolean isRedirect = false; //是否重定向 private boolean isRedirect = false; //是否重定向
private String redirectUrl; //重定向链接 private String redirectUrl; //重定向链接

@ -40,13 +40,16 @@ public class DelegateWrapper {
mDManager = DelegateManager.getInstance(); mDManager = DelegateManager.getInstance();
} }
public static void init(Context context) { public static DelegateWrapper init(Context context) {
if (INSTANCE == null) {
synchronized (DelegateWrapper.class) { synchronized (DelegateWrapper.class) {
if (INSTANCE == null) { if (INSTANCE == null) {
INSTANCE = new DelegateWrapper(context); INSTANCE = new DelegateWrapper(context);
} }
} }
} }
return INSTANCE;
}
static DelegateWrapper getInstance() { static DelegateWrapper getInstance() {
if (INSTANCE == null) { if (INSTANCE == null) {
@ -189,7 +192,7 @@ public class DelegateWrapper {
/** /**
* 查找某张表是否存在 * 查找某张表是否存在
*/ */
boolean tableExists(Class clazz) { public boolean tableExists(Class clazz) {
return mDManager.getDelegate(DelegateCommon.class).tableExists(mDb, clazz); return mDManager.getDelegate(DelegateCommon.class).tableExists(mDb, clazz);
} }

@ -95,7 +95,7 @@ final class SqlHelper extends SQLiteOpenHelper {
@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion < newVersion) { if (oldVersion < newVersion) {
if (oldVersion < 31) { if (oldVersion < 31) {
handle314AriaUpdate(db); handleLowAriaUpdate(db);
} else if (oldVersion < 45) { } else if (oldVersion < 45) {
handle360AriaUpdate(db); handle360AriaUpdate(db);
} else if (oldVersion < 51) { } else if (oldVersion < 51) {
@ -203,7 +203,6 @@ final class SqlHelper extends SQLiteOpenHelper {
String newParamStr = oldParamStr; String newParamStr = oldParamStr;
// 处理字段名称改变 // 处理字段名称改变
if (modifyColumns != null) { if (modifyColumns != null) {
//newParamStr = params.toString();
Map<String, String> columnMap = modifyColumns.get(tableName); Map<String, String> columnMap = modifyColumns.get(tableName);
if (columnMap != null && !columnMap.isEmpty()) { if (columnMap != null && !columnMap.isEmpty()) {
Set<String> keys = columnMap.keySet(); Set<String> keys = columnMap.keySet();
@ -223,7 +222,7 @@ final class SqlHelper extends SQLiteOpenHelper {
} }
//删除中介表 //删除中介表
mDelegate.dropTable(db, tableName + "_temp"); mDelegate.dropTable(db, tableName + "_temp");
}else { } else {
mDelegate.createTable(db, clazz); mDelegate.createTable(db, clazz);
} }
} }
@ -289,9 +288,9 @@ final class SqlHelper extends SQLiteOpenHelper {
} }
/** /**
* 处理3.4版本之前数据库迁移主要是修改子表外键字段对应的值 * 处理低版本的数据库迁移主要是修改子表外键字段对应的值
*/ */
private void handle314AriaUpdate(SQLiteDatabase db) { private void handleLowAriaUpdate(SQLiteDatabase db) {
String[] taskTables = String[] taskTables =
new String[] { "UploadTaskEntity", "DownloadTaskEntity", "DownloadGroupTaskEntity" }; new String[] { "UploadTaskEntity", "DownloadTaskEntity", "DownloadGroupTaskEntity" };
for (String taskTable : taskTables) { for (String taskTable : taskTables) {
@ -305,6 +304,9 @@ final class SqlHelper extends SQLiteOpenHelper {
String[] keys = new String[] { "downloadPath", "groupName" }; String[] keys = new String[] { "downloadPath", "groupName" };
int i = 0; int i = 0;
for (String tableName : tables) { for (String tableName : tables) {
if (!mDelegate.tableExists(db, tableName)) {
continue;
}
String pColumn = keys[i]; String pColumn = keys[i];
String nullSql = String nullSql =
String.format("DELETE FROM %s WHERE %s='' OR %s IS NULL", tableName, pColumn, pColumn); String.format("DELETE FROM %s WHERE %s='' OR %s IS NULL", tableName, pColumn, pColumn);
@ -323,10 +325,16 @@ final class SqlHelper extends SQLiteOpenHelper {
} }
Map<String, Map<String, String>> modifyColumnMap = new HashMap<>(); Map<String, Map<String, String>> modifyColumnMap = new HashMap<>();
Map<String, String> map = new HashMap<>(); Map<String, String> dMap = new HashMap<>();
map.put("groupName", "groupHash"); dMap.put("groupName", "groupHash");
modifyColumnMap.put("DownloadEntity", map); // 处理数据库版本小于3的字段改变
modifyColumnMap.put("DownloadGroupEntity", map); dMap.put("downloadUrl", "url");
dMap.put("isDownloadComplete", "isComplete");
modifyColumnMap.put("DownloadEntity", dMap);
Map<String, String> dGMap = new HashMap<>();
dGMap.put("groupName", "groupHash");
modifyColumnMap.put("DownloadGroupEntity", dGMap);
Map<String, List<String>> delColumnMap = new HashMap<>(); Map<String, List<String>> delColumnMap = new HashMap<>();
List<String> dEntityDel = new ArrayList<>(); List<String> dEntityDel = new ArrayList<>();

@ -3,9 +3,12 @@
- fix bug https://github.com/AriaLyy/Aria/issues/403 - fix bug https://github.com/AriaLyy/Aria/issues/403
- fix bug https://github.com/AriaLyy/Aria/issues/414 - fix bug https://github.com/AriaLyy/Aria/issues/414
- fix bug https://github.com/AriaLyy/Aria/issues/406 - fix bug https://github.com/AriaLyy/Aria/issues/406
- fix bug https://github.com/AriaLyy/Aria/issues/407
- fix bug https://github.com/AriaLyy/Aria/issues/416
- fix bug https://github.com/AriaLyy/Aria/issues/420
- fix bug https://github.com/AriaLyy/Aria/issues/422
- 新增ftp上传拦截器 https://github.com/AriaLyy/Aria/issues/402 - 新增ftp上传拦截器 https://github.com/AriaLyy/Aria/issues/402
- 重构线程任务模块 - 重构线程任务模块
- 修复一个低版本数据库升级的问题 https://github.com/AriaLyy/Aria/issues/407
- 新增m3u8协议的文件下载 - 新增m3u8协议的文件下载
- 修复拦截器可能出现的空指针问题 - 修复拦截器可能出现的空指针问题
- 移除`DownloadGroupEntity`字段`groupHash`的主键约束,`DownloadEntity`字段`groupHash`的外键约束,`TaskRecord`字段`dGroupHash`的外键约束 - 移除`DownloadGroupEntity`字段`groupHash`的主键约束,`DownloadEntity`字段`groupHash`的外键约束,`TaskRecord`字段`dGroupHash`的外键约束
@ -14,7 +17,8 @@
- 优化网络连接状态获取的逻辑 - 优化网络连接状态获取的逻辑
- 修复配置文件的某些配置失效的问题 - 修复配置文件的某些配置失效的问题
- 新增m3u8切片状态注解`@M3U8.onPeerStart`,`@M3U8.onPeerComplete`,`@M3U8.onPeerFail` - 新增m3u8切片状态注解`@M3U8.onPeerStart`,`@M3U8.onPeerComplete`,`@M3U8.onPeerFail`
- 新增动态指定m3u8协议视频的下载功能(边下边播) - 新增动态指定m3u8协议视频的下载功能(边下边播下载支持),[详情](https://aria.laoyuyu.me/aria_doc/download/m3u8_vod.html)
- 优化`unknownSize`的处理,https://github.com/AriaLyy/Aria/issues/419,需要注意,如果组合任务只任务数过多,将需要更多时间才能进入下载流程
+ v_3.6.4 (2019/5/16) + v_3.6.4 (2019/5/16)
- 优化任务接收器的代码结构 - 优化任务接收器的代码结构
- 修复`DbEntity.saveAll()`失败的问题 - 修复`DbEntity.saveAll()`失败的问题

@ -17,6 +17,8 @@ Aria有以下特点:
- 在配置文件中很容易就可以设置CA证书的信息 - 在配置文件中很容易就可以设置CA证书的信息
+ 支持[多线程分块下载](https://aria.laoyuyu.me/aria_doc/start/config.html),能更有效的发挥机器IO性能 + 支持[多线程分块下载](https://aria.laoyuyu.me/aria_doc/start/config.html),能更有效的发挥机器IO性能
+ 支持300、301、302重定向下载链接下载 + 支持300、301、302重定向下载链接下载
+ 支持m3u8协议的文件下载[m3u8下载](https://aria.laoyuyu.me/aria_doc/download/m3u8.html)
+ 支持m3u8边下边看的下载支持,[点击查看详情](https://aria.laoyuyu.me/aria_doc/download/m3u8_vod.html)
+ 下载支持文件长度动态增加,文件下载初始化时将不再占用过多的内存空间,见[动态长度配置](https://aria.laoyuyu.me/aria_doc/start/config.html#%E4%B8%8B%E8%BD%BD%E5%8A%A8%E6%80%81%E6%96%87%E4%BB%B6%E8%AF%B4%E6%98%8E) + 下载支持文件长度动态增加,文件下载初始化时将不再占用过多的内存空间,见[动态长度配置](https://aria.laoyuyu.me/aria_doc/start/config.html#%E4%B8%8B%E8%BD%BD%E5%8A%A8%E6%80%81%E6%96%87%E4%BB%B6%E8%AF%B4%E6%98%8E)
[怎样使用Aria?](#使用) [怎样使用Aria?](#使用)
@ -36,14 +38,17 @@ Aria有以下特点:
<img src="https://github.com/AriaLyy/DownloadUtil/blob/master/img/group_task.gif" width="360" height="640"/> <img src="https://github.com/AriaLyy/DownloadUtil/blob/master/img/group_task.gif" width="360" height="640"/>
* m3u8下载
![m3u8点播文件边下边看](https://github.com/AriaLyy/Aria/blob/master/img/m3u8VodDownload.gif)
## 引入库 ## 引入库
[![Core](https://api.bintray.com/packages/arialyy/maven/AriaApi/images/download.svg)](https://bintray.com/arialyy/maven/AriaApi/_latestVersion) [![Core](https://api.bintray.com/packages/arialyy/maven/AriaApi/images/download.svg)](https://bintray.com/arialyy/maven/AriaApi/_latestVersion)
[![Compiler](https://api.bintray.com/packages/arialyy/maven/AriaCompiler/images/download.svg)](https://bintray.com/arialyy/maven/AriaCompiler/_latestVersion) [![Compiler](https://api.bintray.com/packages/arialyy/maven/AriaCompiler/images/download.svg)](https://bintray.com/arialyy/maven/AriaCompiler/_latestVersion)
```java ```java
compile 'com.arialyy.aria:aria-core:3.6.4' compile 'com.arialyy.aria:aria-core:3.6.5'
annotationProcessor 'com.arialyy.aria:aria-compiler:3.6.4' annotationProcessor 'com.arialyy.aria:aria-compiler:3.6.5'
``` ```
如果出现android support依赖错误,请将 `compile 'com.arialyy.aria:aria-core:<last-version>'`替换为 如果出现android support依赖错误,请将 `compile 'com.arialyy.aria:aria-core:<last-version>'`替换为
``` ```
@ -113,36 +118,25 @@ protected void onCreate(Bundle savedInstanceState) {
### 版本日志 ### 版本日志
+ v_3.6.4 (2019/5/16) + v_3.6.5
- 优化任务接收器的代码结构 - fix bug https://github.com/AriaLyy/Aria/issues/403
- 修复`DbEntity.saveAll()`失败的问题 - fix bug https://github.com/AriaLyy/Aria/issues/414
- 修复分块任务重命名失败的问题 - fix bug https://github.com/AriaLyy/Aria/issues/406
- fix bug https://github.com/AriaLyy/Aria/issues/379 - fix bug https://github.com/AriaLyy/Aria/issues/407
- 移除`getDownloadTask(String url)`、`getGroupTask(List<String> urls)`、`getFtpDirTask(String path)` - fix bug https://github.com/AriaLyy/Aria/issues/416
等获取任务的api,如果你希望获取对应状态,请使用实体的状态判断,如:`getDownloadEntity()`、`getDownloadGroupEntity()` - fix bug https://github.com/AriaLyy/Aria/issues/420
`getFtpDirEntity()` - fix bug https://github.com/AriaLyy/Aria/issues/422
- fix bug https://github.com/AriaLyy/Aria/issues/388 - 新增ftp上传拦截器 https://github.com/AriaLyy/Aria/issues/402
- 修复使用`Content-Disposition`的文件名时,第一次下载无法重命名文件的问题 - 重构线程任务模块
- 修复使用`Content-Disposition`的文件名时,多次重命名文件的问题 - 新增m3u8协议的文件下载
- 组合任务新增`unknownSize()`,用于处理组合任务大小ø未知的情况,https://github.com/AriaLyy/Aria/issues/380 - 修复拦截器可能出现的空指针问题
- 优化`AbsThreadTask`代码 - 移除`DownloadGroupEntity`字段`groupHash`的主键约束,`DownloadEntity`字段`groupHash`的外键约束,`TaskRecord`字段`dGroupHash`的外键约束
- 新增文件长度处理功能 https://github.com/AriaLyy/Aria/issues/393 - 优化关联查询的性能
```java - 修复任务记录删除失败的问题
.setFileLenAdapter(new IHttpFileLenAdapter() { - 优化网络连接状态获取的逻辑
@Override public long handleFileLen(Map<String, List<String>> headers) { - 修复配置文件的某些配置失效的问题
... - 新增m3u8切片状态注解`@M3U8.onPeerStart`,`@M3U8.onPeerComplete`,`@M3U8.onPeerFail`
// 处理header中的文件长度 - 新增动态指定m3u8协议视频的下载功能(边下边播下载支持),[详情](https://aria.laoyuyu.me/aria_doc/download/m3u8_vod.html)
return fileLen;
}
})
```
- 修复组合任务多次回调`onStop`注解的问题
- 优化`isRunning()`的逻辑,任务是否在执行的判断将更加准确
- 修复多次重复快速点击`暂停、开始`时,任务有可能重复下载的问题
- 修复组合任务中没有等待中的只任务实体保存失败的问题
- 新增组合任务url重复检查 https://github.com/AriaLyy/Aria/issues/395
- 初始化任务时,如果url、path有错误将会回调`@Download.onTaskFail`、`@Upload.onTaskFail`、`@DownGroup.onTaskFail`
[更多版本记录](https://github.com/AriaLyy/Aria/blob/master/DEV_LOG.md) [更多版本记录](https://github.com/AriaLyy/Aria/blob/master/DEV_LOG.md)

@ -22,7 +22,7 @@
<download> <download>
<!--设置任务最大下载速度,0表示不限速,单位为:kb--> <!--设置任务最大下载速度,0表示不限速,单位为:kb-->
<maxSpeed value="128"/> <maxSpeed value="0"/>
<!-- <!--
多线程下载是否使用块下载模式,{@code true}使用,{@code false}不使用 多线程下载是否使用块下载模式,{@code true}使用,{@code false}不使用

@ -34,6 +34,7 @@ public class HttpDownloadModule extends BaseViewModule {
private final String defUrl = private final String defUrl =
"http://hzdown.muzhiwan.com/2017/05/08/nl.noio.kingdom_59104935e56f0.apk"; "http://hzdown.muzhiwan.com/2017/05/08/nl.noio.kingdom_59104935e56f0.apk";
//"http://9.9.9.205:5000/download/Cyberduck-6.9.4.30164.zip";
//"http://202.98.201.103:7000/vrs/TPK/ZTC440402001Z.tpk"; //"http://202.98.201.103:7000/vrs/TPK/ZTC440402001Z.tpk";
private final String defFilePath = private final String defFilePath =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath()

@ -97,8 +97,8 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
Environment.getExternalStorageDirectory().getPath() + "/Download/group_test_2") Environment.getExternalStorageDirectory().getPath() + "/Download/group_test_2")
.setGroupAlias("任务组测试") .setGroupAlias("任务组测试")
//.setSubFileName(getModule(GroupModule.class).getSubName2()) //.setSubFileName(getModule(GroupModule.class).getSubName2())
.setSubFileName(getModule(GroupModule.class).getSubName()) //.setSubFileName(getModule(GroupModule.class).getSubName())
.unknownSize() //.unknownSize()
.setFileLenAdapter(new IHttpFileLenAdapter() { .setFileLenAdapter(new IHttpFileLenAdapter() {
@Override public long handleFileLen(Map<String, List<String>> headers) { @Override public long handleFileLen(Map<String, List<String>> headers) {
@ -111,7 +111,7 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
return Long.parseLong(temp); return Long.parseLong(temp);
} }
}) })
//.setFileSize(114981416) .setFileSize(114981416)
//.updateUrls(temp) //.updateUrls(temp)
.start(); .start();
getBinding().setStateStr(getString(R.string.stop)); getBinding().setStateStr(getString(R.string.stop));
@ -170,6 +170,7 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
@DownloadGroup.onTaskStop() void taskStop(DownloadGroupTask task) { @DownloadGroup.onTaskStop() void taskStop(DownloadGroupTask task) {
L.d(TAG, "group task stop"); L.d(TAG, "group task stop");
getBinding().setSpeed(""); getBinding().setSpeed("");
getBinding().setStateStr(getString(R.string.start));
} }
@DownloadGroup.onTaskCancel() void taskCancel(DownloadGroupTask task) { @DownloadGroup.onTaskCancel() void taskCancel(DownloadGroupTask task) {
@ -182,6 +183,7 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
@DownloadGroup.onTaskFail() void taskFail(DownloadGroupTask task) { @DownloadGroup.onTaskFail() void taskFail(DownloadGroupTask task) {
L.d(TAG, "group task fail"); L.d(TAG, "group task fail");
getBinding().setStateStr(getString(R.string.resume)); getBinding().setStateStr(getString(R.string.resume));
getBinding().setSpeed("");
} }
@DownloadGroup.onTaskComplete() void taskComplete(DownloadGroupTask task) { @DownloadGroup.onTaskComplete() void taskComplete(DownloadGroupTask task) {
@ -236,6 +238,7 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
@DownloadGroup.onSubTaskComplete void onSubTaskComplete(DownloadGroupTask groupTask, @DownloadGroup.onSubTaskComplete void onSubTaskComplete(DownloadGroupTask groupTask,
DownloadEntity subEntity) { DownloadEntity subEntity) {
mChildList.updateChildState(subEntity);
} }
@DownloadGroup.onSubTaskFail void onSubTaskFail(DownloadGroupTask groupTask, @DownloadGroup.onSubTaskFail void onSubTaskFail(DownloadGroupTask groupTask,

@ -18,7 +18,6 @@ package com.arialyy.simple.widget;
import android.content.Context; import android.content.Context;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -36,6 +35,7 @@ import java.util.WeakHashMap;
*/ */
public class SubStateLinearLayout extends LinearLayout implements View.OnClickListener { public class SubStateLinearLayout extends LinearLayout implements View.OnClickListener {
private final String TAG = "SubStateLinearLayout"; private final String TAG = "SubStateLinearLayout";
interface OnShowCallback { interface OnShowCallback {
void onShow(boolean visibility); void onShow(boolean visibility);
} }
@ -100,7 +100,7 @@ public class SubStateLinearLayout extends LinearLayout implements View.OnClickLi
public void updateChildProgress(List<DownloadEntity> entities) { public void updateChildProgress(List<DownloadEntity> entities) {
for (DownloadEntity entity : entities) { for (DownloadEntity entity : entities) {
Integer i = mPosition.get(entity.getDownloadPath()); Integer i = mPosition.get(entity.getFilePath());
if (i == null) return; if (i == null) return;
int position = i; int position = i;
if (position != -1) { if (position != -1) {
@ -112,6 +112,22 @@ public class SubStateLinearLayout extends LinearLayout implements View.OnClickLi
} }
} }
public void updateChildState(DownloadEntity entity) {
Integer i = mPosition.get(entity.getFilePath());
if (i == null) return;
int position = i;
if (position != -1) {
TextView child = ((TextView) getChildAt(position));
if (entity.isComplete()) {
child.setText(entity.getFileName() + " | " + getResources().getText(R.string.complete));
} else {
int p = getPercent(entity);
child.setText(entity.getFileName() + ": " + p + "%" + " | " + entity.getConvertSpeed());
}
child.invalidate();
}
}
private TextView createView(int position, DownloadEntity entity) { private TextView createView(int position, DownloadEntity entity) {
TextView view = TextView view =
(TextView) LayoutInflater.from(getContext()).inflate(R.layout.layout_child_state, null); (TextView) LayoutInflater.from(getContext()).inflate(R.layout.layout_child_state, null);

@ -12,6 +12,7 @@
<string name="start">开始</string> <string name="start">开始</string>
<string name="resume">恢复</string> <string name="resume">恢复</string>
<string name="delete">删除</string> <string name="delete">删除</string>
<string name="complete">完成</string>
<string name="code_simple">代码示例:</string> <string name="code_simple">代码示例:</string>
<string name="download_success">下载完成</string> <string name="download_success">下载完成</string>
<string name="download_fail">下载失败</string> <string name="download_fail">下载失败</string>
@ -125,7 +126,7 @@
<string-array name="group_urls_1"> <string-array name="group_urls_1">
<item>http://hzdown.muzhiwan.com/2017/05/08/nl.noio.kingdom_59104935e56f0.apk</item> <item>http://hzdown.muzhiwan.com/2017/05/08/nl.noio.kingdom_59104935e56f0.apk</item>
<!--<item>https://atom-installer.github.com/v1.13.0/AtomSetup.exe</item>--> <item>https://atom-installer.github.com/v1.13.0/AtomSetup.exe1</item>
<item>http://hzdown.muzhiwan.com/2017/09/05/com.mir.iphone.empire83jie.mzw_59ae6d5a3638d.apk</item> <item>http://hzdown.muzhiwan.com/2017/09/05/com.mir.iphone.empire83jie.mzw_59ae6d5a3638d.apk</item>
</string-array> </string-array>

@ -43,7 +43,7 @@ task clean(type: Delete) {
ext { ext {
userOrg = 'arialyy' userOrg = 'arialyy'
groupId = 'com.arialyy.aria' groupId = 'com.arialyy.aria'
publishVersion = '3.6.5_beta_3' publishVersion = '3.6.5'
// publishVersion = '1.0.4' //FTP插件 // publishVersion = '1.0.4' //FTP插件
repoName='maven' repoName='maven'
desc = 'android 下载框架' desc = 'android 下载框架'

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 MiB

After

Width:  |  Height:  |  Size: 2.0 MiB

@ -1,4 +1,5 @@
# coding=utf-8 # coding=utf-8
#!/usr/bin/python3
import os import os
from flask import Flask, send_from_directory, request from flask import Flask, send_from_directory, request
@ -12,8 +13,8 @@ def downloader(filename):
不支持断点的下载 不支持断点的下载
""" """
data = request.values.get('key') data = request.values.get('key')
print data print(data)
dirpath = 'D:/test' dirpath = '/Users/aria/dev/ftp'
return send_from_directory(dirpath, filename, as_attachment=True) # as_attachment=True 一定要写,不然会变成打开,而不是下载 return send_from_directory(dirpath, filename, as_attachment=True) # as_attachment=True 一定要写,不然会变成打开,而不是下载
@ -24,7 +25,7 @@ def downloader1():
""" """
filename = request.values.get('filename') filename = request.values.get('filename')
data = request.values.get('key') data = request.values.get('key')
print data print(data)
dirpath = 'D:/test' dirpath = 'D:/test'
return send_from_directory(dirpath, filename, as_attachment=True) # as_attachment=True 一定要写,不然会变成打开,而不是下载 return send_from_directory(dirpath, filename, as_attachment=True) # as_attachment=True 一定要写,不然会变成打开,而不是下载

Loading…
Cancel
Save