修复重构loader模块后出现的组合任务的bug

pull/617/head
laoyuyu 5 years ago
parent 102d3ba0f6
commit c39bfbdd88
  1. 4
      Aria/src/main/java/com/arialyy/aria/core/download/CheckDGEntityUtil.java
  2. 11
      FtpComponent/src/main/java/com/arialyy/aria/ftp/download/FtpDGLoader.java
  3. 6
      FtpComponent/src/main/java/com/arialyy/aria/ftp/download/FtpSubDLoaderUtil.java
  4. 4
      HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDGInfoTask.java
  5. 9
      HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDGLoader.java
  6. 3
      HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDGLoaderUtil.java
  7. 6
      HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpSubDLoaderUtil.java
  8. 4
      M3U8Component/src/main/java/com/arialyy/aria/m3u8/live/M3U8LiveLoader.java
  9. 3
      M3U8Component/src/main/java/com/arialyy/aria/m3u8/vod/M3U8VodLoader.java
  10. 4
      M3U8Component/src/main/java/com/arialyy/aria/m3u8/vod/VodStateManager.java
  11. 68
      PublicComponent/src/main/java/com/arialyy/aria/core/common/SubThreadConfig.java
  12. 30
      PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsGroupLoader.java
  13. 21
      PublicComponent/src/main/java/com/arialyy/aria/core/group/AbsSubDLoadUtil.java
  14. 146
      PublicComponent/src/main/java/com/arialyy/aria/core/group/ChildDLoadListener.java
  15. 56
      PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSchedulers.java
  16. 10
      PublicComponent/src/main/java/com/arialyy/aria/core/group/SimpleSubQueue.java
  17. 6
      PublicComponent/src/main/java/com/arialyy/aria/core/inf/IThreadStateManager.java
  18. 30
      PublicComponent/src/main/java/com/arialyy/aria/core/listener/DownloadGroupListener.java
  19. 7
      PublicComponent/src/main/java/com/arialyy/aria/core/listener/IDGroupListener.java
  20. 2
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsNormalTTBuilder.java
  21. 4
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/NormalThreadStateManager.java
  22. 84
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/SubLoader.java
  23. 45
      PublicComponent/src/main/java/com/arialyy/aria/core/manager/ThreadTaskManager.java
  24. 6
      PublicComponent/src/main/java/com/arialyy/aria/core/task/IThreadTask.java
  25. 51
      PublicComponent/src/main/java/com/arialyy/aria/core/task/ThreadTask.java
  26. 5
      PublicComponent/src/main/java/com/arialyy/aria/core/wrapper/ITaskWrapper.java
  27. 14
      PublicComponent/src/main/java/com/arialyy/aria/util/CommonUtil.java
  28. 2
      PublicComponent/src/main/java/com/arialyy/aria/util/RecordUtil.java
  29. 9
      app/src/main/java/com/arialyy/simple/core/download/group/DownloadGroupActivity.java

@ -116,7 +116,7 @@ public class CheckDGEntityUtil implements ICheckEntityUtil {
@Override
public boolean checkEntity() {
if (mWrapper.getErrorEvent() != null) {
ALog.e(TAG, String.format("下载失败,%s", mWrapper.getErrorEvent().errorMsg));
ALog.e(TAG, String.format("操作失败,%s", mWrapper.getErrorEvent().errorMsg));
return false;
}
@ -195,7 +195,7 @@ public class CheckDGEntityUtil implements ICheckEntityUtil {
*/
private boolean checkUrls() {
if (mEntity.getUrls().isEmpty()) {
ALog.e(TAG, "下载失败,子任务下载列表为null");
ALog.e(TAG, "操作失败,子任务下载列表为null");
return false;
}

@ -45,13 +45,18 @@ final class FtpDGLoader extends AbsGroupLoader {
@Override
protected AbsSubDLoadUtil createSubLoader(DTaskWrapper wrapper, boolean needGetFileInfo) {
return new FtpSubDLoaderUtil(wrapper, getScheduler(), needGetFileInfo);
return new FtpSubDLoaderUtil(wrapper, getScheduler(), needGetFileInfo, getKey());
}
/**
* 启动子任务下载
*/
private void startSub() {
if (isBreak()) {
return;
}
onPostStart();
// ftp需要获取完成只任务信息才更新只任务数量
getState().setSubSize(getWrapper().getSubTaskWrapper().size());
@ -70,12 +75,12 @@ final class FtpDGLoader extends AbsGroupLoader {
startSub();
} else {
ALog.e(TAG, "获取任务信息失败,code:" + info.code);
mListener.onFail(false, null);
getListener().onFail(false, null);
}
}
@Override public void onFail(AbsEntity entity, BaseException e, boolean needRetry) {
mListener.onFail(needRetry, e);
getListener().onFail(needRetry, e);
}
});
}

@ -31,14 +31,16 @@ final class FtpSubDLoaderUtil extends AbsSubDLoadUtil {
* @param schedulers 调度器
* @param needGetInfo {@code true} 需要获取文件信息{@code false} 不需要获取文件信息
*/
FtpSubDLoaderUtil(DTaskWrapper taskWrapper, Handler schedulers, boolean needGetInfo) {
super(taskWrapper, schedulers, needGetInfo);
FtpSubDLoaderUtil(DTaskWrapper taskWrapper, Handler schedulers, boolean needGetInfo,
String parentKey) {
super(taskWrapper, schedulers, needGetInfo, parentKey);
}
@Override protected SubLoader getLoader() {
if (mDLoader == null) {
mDLoader = new SubLoader(getWrapper(), getSchedulers());
mDLoader.setNeedGetInfo(isNeedGetInfo());
mDLoader.setParentKey(getParentKey());
}
return mDLoader;
}

@ -66,7 +66,7 @@ public final class HttpDGInfoTask implements IInfoTask {
}
};
public HttpDGInfoTask(DGTaskWrapper wrapper, DownloadGroupListener listener) {
HttpDGInfoTask(DGTaskWrapper wrapper, DownloadGroupListener listener) {
this.wrapper = wrapper;
this.listener = listener;
}
@ -76,7 +76,7 @@ public final class HttpDGInfoTask implements IInfoTask {
if (mPool != null && !getLenComplete) {
ALog.d(TAG, "获取长度未完成的情况下,停止组合任务");
mPool.shutdown();
//mListener.onStop(0);
listener.onStop(0);
return;
}
// 处理组合任务大小未知的情况

@ -22,7 +22,7 @@ import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.group.AbsGroupLoader;
import com.arialyy.aria.core.group.AbsSubDLoadUtil;
import com.arialyy.aria.core.listener.IEventListener;
import com.arialyy.aria.core.listener.DownloadGroupListener;
import com.arialyy.aria.core.loader.IInfoTask;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.exception.BaseException;
@ -31,7 +31,7 @@ import com.arialyy.aria.exception.BaseException;
* http 组合任务加载器
*/
final class HttpDGLoader extends AbsGroupLoader {
HttpDGLoader(AbsTaskWrapper groupWrapper, IEventListener listener) {
HttpDGLoader(AbsTaskWrapper groupWrapper, DownloadGroupListener listener) {
super(groupWrapper, listener);
}
@ -44,13 +44,14 @@ final class HttpDGLoader extends AbsGroupLoader {
@Override
protected AbsSubDLoadUtil createSubLoader(DTaskWrapper wrapper, boolean needGetFileInfo) {
return new HttpSubDLoaderUtil(wrapper, getScheduler(), needGetFileInfo);
return new HttpSubDLoaderUtil(wrapper, getScheduler(), needGetFileInfo, getKey());
}
private void startSub() {
if (isBreak()) {
return;
}
onPostStart();
for (DTaskWrapper wrapper : getWrapper().getSubTaskWrapper()) {
DownloadEntity dEntity = wrapper.getEntity();
startSubLoader(createSubLoader(wrapper, dEntity.getFileSize() < 0));
@ -65,7 +66,7 @@ final class HttpDGLoader extends AbsGroupLoader {
}
@Override public void onFail(AbsEntity entity, BaseException e, boolean needRetry) {
mListener.onFail(needRetry, e);
getListener().onFail(needRetry, e);
}
});
}

@ -36,7 +36,8 @@ public final class HttpDGLoaderUtil extends AbsGroupLoaderUtil {
}
@Override protected AbsGroupLoader getLoader() {
return mLoader == null ? new HttpDGLoader(getTaskWrapper(), getListener()) : mLoader;
return mLoader == null ? new HttpDGLoader(getTaskWrapper(),
(DownloadGroupListener) getListener()) : mLoader;
}
@Override protected LoaderStructure buildLoaderStructure() {

@ -32,14 +32,16 @@ final class HttpSubDLoaderUtil extends AbsSubDLoadUtil {
* @param schedulers 调度器
* @param needGetInfo {@code true} 需要获取文件信息{@code false} 不需要获取文件信息
*/
HttpSubDLoaderUtil(DTaskWrapper taskWrapper, Handler schedulers, boolean needGetInfo) {
super(taskWrapper, schedulers, needGetInfo);
HttpSubDLoaderUtil(DTaskWrapper taskWrapper, Handler schedulers, boolean needGetInfo,
String parentKey) {
super(taskWrapper, schedulers, needGetInfo, parentKey);
}
@Override protected SubLoader getLoader() {
if (mDLoader == null) {
mDLoader = new SubLoader(getWrapper(), getSchedulers());
mDLoader.setNeedGetInfo(isNeedGetInfo());
mDLoader.setParentKey(getParentKey());
}
return mDLoader;
}

@ -31,6 +31,7 @@ import com.arialyy.aria.core.manager.ThreadTaskManager;
import com.arialyy.aria.core.processor.ILiveTsUrlConverter;
import com.arialyy.aria.core.processor.ITsMergeHandler;
import com.arialyy.aria.core.task.ThreadTask;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.exception.BaseException;
import com.arialyy.aria.exception.M3U8Exception;
import com.arialyy.aria.exception.TaskException;
@ -180,7 +181,8 @@ final class M3U8LiveLoader extends BaseM3U8Loader {
config.record = record;
config.stateHandler = mStateHandler;
config.peerIndex = indexId;
config.threadType = SubThreadConfig.getThreadType(ITaskWrapper.M3U8_LIVE);
config.updateInterval = SubThreadConfig.getUpdateInterval(ITaskWrapper.M3U8_LIVE);
if (!config.tempFile.exists()) {
FileUtil.createFile(config.tempFile);
}

@ -34,6 +34,7 @@ import com.arialyy.aria.core.loader.IThreadTaskBuilder;
import com.arialyy.aria.core.manager.ThreadTaskManager;
import com.arialyy.aria.core.processor.IVodTsUrlConverter;
import com.arialyy.aria.core.task.ThreadTask;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.exception.BaseException;
import com.arialyy.aria.exception.M3U8Exception;
import com.arialyy.aria.m3u8.BaseM3U8Loader;
@ -473,6 +474,8 @@ final class M3U8VodLoader extends BaseM3U8Loader {
config.record = record;
config.stateHandler = mStateHandler;
config.peerIndex = index;
config.threadType = SubThreadConfig.getThreadType(ITaskWrapper.M3U8_LIVE);
config.updateInterval = SubThreadConfig.getUpdateInterval(ITaskWrapper.M3U8_LIVE);
if (!config.tempFile.exists()) {
FileUtil.createFile(config.tempFile);
}

@ -113,8 +113,8 @@ public final class VodStateManager implements IThreadStateManager {
if (isFail()) {
ALog.d(TAG, String.format("vod任务【%s】失败", loader.getTempFile().getName()));
Bundle b = msg.getData();
listener.onFail(b.getBoolean(KEY_RETRY, true),
(BaseException) b.getSerializable(KEY_ERROR_INFO));
listener.onFail(b.getBoolean(DATA_RETRY, true),
(BaseException) b.getSerializable(DATA_ERROR_INFO));
quitLooper();
}
break;

@ -16,14 +16,21 @@
package com.arialyy.aria.core.common;
import android.os.Handler;
import com.arialyy.aria.core.AriaConfig;
import com.arialyy.aria.core.ThreadRecord;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import java.io.File;
/**
* 子线程下载信息类
*/
public class SubThreadConfig {
public static final int TYPE_HTTP = 1;
public static final int TYPE_FTP = 2;
public static final int TYPE_M3U8_PEER = 3;
public static final int TYPE_HTTP_DG_SUB = 4;
public static final int TYPE_FTP_DG_SUB = 5;
public AbsTaskWrapper taskWrapper;
public boolean isBlock = false;
@ -37,4 +44,65 @@ public class SubThreadConfig {
public Handler stateHandler;
// m3u8切片索引
public int peerIndex;
// 线程任务类型
public int threadType = TYPE_HTTP;
// 更新间隔,单位:毫秒
public long updateInterval = 1000;
/**
* 转换线程任务类型
*
* @param requestType {@link AbsTaskWrapper#getRequestType()}
* @return {@link #threadType}
*/
public static int getThreadType(int requestType) {
int threadType = SubThreadConfig.TYPE_HTTP;
switch (requestType) {
case ITaskWrapper.D_HTTP:
case ITaskWrapper.U_HTTP:
threadType = SubThreadConfig.TYPE_HTTP;
break;
case ITaskWrapper.D_FTP:
case ITaskWrapper.U_FTP:
threadType = SubThreadConfig.TYPE_FTP;
break;
case ITaskWrapper.D_FTP_DIR:
threadType = SubThreadConfig.TYPE_FTP_DG_SUB;
break;
case ITaskWrapper.DG_HTTP:
threadType = SubThreadConfig.TYPE_HTTP_DG_SUB;
break;
case ITaskWrapper.M3U8_LIVE:
case ITaskWrapper.M3U8_VOD:
threadType = SubThreadConfig.TYPE_M3U8_PEER;
break;
}
return threadType;
}
/**
* 根据配置肚脐更新间隔
*
* @param requestType {@link AbsTaskWrapper#getRequestType()}
* @return {@link #updateInterval}
*/
public static long getUpdateInterval(int requestType) {
long updateInterval = 1000;
switch (requestType) {
case ITaskWrapper.D_HTTP:
case ITaskWrapper.D_FTP:
case ITaskWrapper.M3U8_LIVE:
case ITaskWrapper.M3U8_VOD:
updateInterval = AriaConfig.getInstance().getDConfig().getUpdateInterval();
break;
case ITaskWrapper.D_FTP_DIR:
case ITaskWrapper.DG_HTTP:
updateInterval = AriaConfig.getInstance().getDGConfig().getUpdateInterval();
break;
case ITaskWrapper.U_HTTP:
case ITaskWrapper.U_FTP:
updateInterval = AriaConfig.getInstance().getUConfig().getUpdateInterval();
}
return updateInterval;
}
}

@ -45,7 +45,7 @@ public abstract class AbsGroupLoader implements ILoaderVisitor, ILoader {
protected final String TAG = CommonUtil.getClassName(getClass());
private long mCurrentLocation = 0;
protected IDGroupListener mListener;
private IDGroupListener mListener;
private ScheduledThreadPoolExecutor mTimer;
private long mUpdateInterval;
private boolean isStop = false, isCancel = false;
@ -76,6 +76,10 @@ public abstract class AbsGroupLoader implements ILoaderVisitor, ILoader {
*/
protected abstract AbsSubDLoadUtil createSubLoader(DTaskWrapper wrapper, boolean needGetFileInfo);
protected IDGroupListener getListener() {
return mListener;
}
protected DGTaskWrapper getWrapper() {
return mGTWrapper;
}
@ -113,7 +117,7 @@ public abstract class AbsGroupLoader implements ILoaderVisitor, ILoader {
getWrapper().setState(IEntity.STATE_POST_PRE);
}
mState.updateProgress(mCurrentLocation);
mScheduler = new Handler(looper, SimpleSchedulers.newInstance(mState));
mScheduler = new Handler(looper, SimpleSchedulers.newInstance(mState, mGTWrapper.getKey()));
}
@Override public String getKey() {
@ -248,18 +252,26 @@ public abstract class AbsGroupLoader implements ILoaderVisitor, ILoader {
mListener.onComplete();
return;
}
mListener.onPostPre(mGTWrapper.getEntity().getFileSize());
if (mCurrentLocation > 0) {
mListener.onResume(mCurrentLocation);
} else {
mListener.onStart(mCurrentLocation);
}
startTimer();
handlerTask(looper);
Looper.loop();
}
/**
* 组合任务获取完成子任务的信息后调用
*/
protected void onPostStart() {
if (isBreak()) {
return;
}
getListener().onPostPre(getWrapper().getEntity().getFileSize());
if (getWrapper().getEntity().getFileSize() > 0) {
getListener().onResume(getWrapper().getEntity().getCurrentProgress());
} else {
getListener().onStart(getWrapper().getEntity().getCurrentProgress());
}
}
private synchronized void startTimer() {
mState.isRunning = true;
mTimer = new ScheduledThreadPoolExecutor(1);

@ -34,19 +34,19 @@ public abstract class AbsSubDLoadUtil implements IUtil, Runnable {
protected SubLoader mDLoader;
private DTaskWrapper mWrapper;
private Handler mSchedulers;
private ChildDLoadListener mListener;
private boolean needGetInfo;
private boolean isStop = false, isCancel = false;
private String parentKey;
/**
* @param schedulers 调度器
* @param needGetInfo {@code true} 需要获取文件信息{@code false} 不需要获取文件信息
*/
protected AbsSubDLoadUtil(DTaskWrapper taskWrapper, Handler schedulers, boolean needGetInfo) {
protected AbsSubDLoadUtil(DTaskWrapper taskWrapper, Handler schedulers, boolean needGetInfo, String parentKey) {
mWrapper = taskWrapper;
mSchedulers = schedulers;
this.parentKey = parentKey;
this.needGetInfo = needGetInfo;
mListener = new ChildDLoadListener(mSchedulers, AbsSubDLoadUtil.this);
mDLoader = getLoader();
}
@ -57,6 +57,10 @@ public abstract class AbsSubDLoadUtil implements IUtil, Runnable {
protected abstract LoaderStructure buildLoaderStructure();
public String getParentKey() {
return parentKey;
}
protected boolean isNeedGetInfo() {
return needGetInfo;
}
@ -66,7 +70,7 @@ public abstract class AbsSubDLoadUtil implements IUtil, Runnable {
}
@Override public String getKey() {
return mWrapper.getKey();
return mDLoader.getKey();
}
public DTaskWrapper getWrapper() {
@ -77,15 +81,10 @@ public abstract class AbsSubDLoadUtil implements IUtil, Runnable {
return mWrapper.getEntity();
}
public ChildDLoadListener getListener() {
return mListener;
}
@Override public void run() {
if (isStop || isCancel) {
return;
}
mListener.onPre();
buildLoaderStructure();
mDLoader.run();
}
@ -107,10 +106,6 @@ public abstract class AbsSubDLoadUtil implements IUtil, Runnable {
}
}
public SubLoader getDownloader() {
return mDLoader;
}
/**
* @deprecated 子任务不实现这个
*/

@ -1,146 +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.core.group;
import android.os.Handler;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.listener.IDLoadListener;
import com.arialyy.aria.core.listener.ISchedulers;
import com.arialyy.aria.exception.BaseException;
import com.arialyy.aria.util.CommonUtil;
/**
* 子任务事件监听
*/
public class ChildDLoadListener implements IDLoadListener {
private DownloadEntity subEntity;
private int RUN_SAVE_INTERVAL = 5 * 1000; //5s保存一次下载中的进度
private long lastSaveTime;
private long lastLen;
private Handler schedulers;
private AbsSubDLoadUtil loader;
ChildDLoadListener(Handler schedulers, AbsSubDLoadUtil loader) {
this.loader = loader;
this.schedulers = schedulers;
subEntity = loader.getEntity();
subEntity.setFailNum(0);
lastLen = subEntity.getCurrentProgress();
lastSaveTime = System.currentTimeMillis();
}
@Override public void supportBreakpoint(boolean support) {
}
@Override public void onPre() {
saveData(IEntity.STATE_PRE, subEntity.getCurrentProgress());
}
@Override public void onPostPre(long fileSize) {
subEntity.setFileSize(fileSize);
subEntity.setConvertFileSize(CommonUtil.formatFileSize(fileSize));
saveData(IEntity.STATE_POST_PRE, subEntity.getCurrentProgress());
sendToTarget(ISchedulers.POST_PRE, loader);
}
@Override public void onResume(long resumeLocation) {
lastLen = resumeLocation;
saveData(IEntity.STATE_POST_PRE, subEntity.getCurrentProgress());
sendToTarget(ISchedulers.START, loader);
}
@Override public void onStart(long startLocation) {
lastLen = startLocation;
saveData(IEntity.STATE_POST_PRE, subEntity.getCurrentProgress());
sendToTarget(ISchedulers.START, loader);
}
@Override public void onProgress(long currentLocation) {
long diff = currentLocation - lastLen;
//mCurrentLocation += speed;
subEntity.setCurrentProgress(currentLocation);
handleSpeed(diff);
sendToTarget(ISchedulers.RUNNING, loader);
if (System.currentTimeMillis() - lastSaveTime >= RUN_SAVE_INTERVAL) {
saveData(IEntity.STATE_RUNNING, currentLocation);
lastSaveTime = System.currentTimeMillis();
}
lastLen = currentLocation;
}
@Override public void onStop(long stopLocation) {
handleSpeed(0);
saveData(IEntity.STATE_STOP, stopLocation);
sendToTarget(ISchedulers.STOP, loader);
}
/**
* 组合任务子任务不允许删除
*/
@Deprecated
@Override public void onCancel() {
}
@Override public void onComplete() {
subEntity.setComplete(true);
saveData(IEntity.STATE_COMPLETE, subEntity.getFileSize());
handleSpeed(0);
sendToTarget(ISchedulers.COMPLETE, loader);
}
@Override public void onFail(boolean needRetry, BaseException e) {
subEntity.setFailNum(subEntity.getFailNum() + 1);
saveData(IEntity.STATE_FAIL, subEntity.getCurrentProgress());
handleSpeed(0);
sendToTarget(ISchedulers.FAIL, loader);
}
private void handleSpeed(long speed) {
subEntity.setSpeed(speed);
subEntity.setConvertSpeed(
speed <= 0 ? "" : String.format("%s/s", CommonUtil.formatFileSize(speed)));
subEntity.setPercent((int) (subEntity.getFileSize() <= 0 ? 0
: subEntity.getCurrentProgress() * 100 / subEntity.getFileSize()));
}
private void saveData(int state, long location) {
loader.getWrapper().setState(state);
subEntity.setState(state);
subEntity.setComplete(state == IEntity.STATE_COMPLETE);
if (state == IEntity.STATE_CANCEL) {
subEntity.deleteData();
} else if (state == IEntity.STATE_STOP) {
subEntity.setStopTime(System.currentTimeMillis());
} else if (subEntity.isComplete()) {
subEntity.setCompleteTime(System.currentTimeMillis());
subEntity.setCurrentProgress(subEntity.getFileSize());
} else if (location > 0) {
subEntity.setCurrentProgress(location);
}
}
/**
* 发送状态到子任务调度器{@link SimpleSchedulers}让调度器处理任务调度
*
* @param state {@link ISchedulers}
*/
private void sendToTarget(int state, AbsSubDLoadUtil util) {
schedulers.obtainMessage(state, util).sendToTarget();
}
}

@ -16,6 +16,7 @@
package com.arialyy.aria.core.group;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import com.arialyy.aria.core.AriaConfig;
@ -37,45 +38,56 @@ class SimpleSchedulers implements Handler.Callback {
private static final String TAG = "SimpleSchedulers";
private SimpleSubQueue mQueue;
private GroupRunState mGState;
private String mKey; // 组合任务的key
private SimpleSchedulers(GroupRunState state) {
private SimpleSchedulers(GroupRunState state, String key) {
mQueue = state.queue;
mGState = state;
mKey = key;
}
static SimpleSchedulers newInstance(GroupRunState state) {
return new SimpleSchedulers(state);
static SimpleSchedulers newInstance(GroupRunState state, String key) {
return new SimpleSchedulers(state, key);
}
@Override public boolean handleMessage(Message msg) {
// todo key 应该从bundle中获取
String key = (String) msg.obj;
AbsSubDLoadUtil loader = mQueue.getLoaderUtil(key);
if (loader == null) {
ALog.e(TAG, "子任务loder不存在,key:" + key);
Bundle b = msg.getData();
if (b == null) {
ALog.w(TAG, "组合任务子任务调度数据为空");
return true;
}
String threadName = b.getString(IThreadStateManager.DATA_THREAD_NAME);
AbsSubDLoadUtil loaderUtil = mQueue.getLoaderUtil(threadName);
if (loaderUtil == null) {
ALog.e(TAG, String.format("子任务loader不存在,state:%s,key:%s", msg.what, threadName));
return true;
}
// todo 处理的是子任务的线程,需要删除 ThreadTaskManager.removeSingleTaskThread 删除线程任务
long curLocation = b.getLong(IThreadStateManager.DATA_THREAD_LOCATION,
loaderUtil.getLoader().getWrapper().getEntity().getCurrentProgress());
// 处理状态
switch (msg.what) {
case IThreadStateManager.STATE_RUNNING:
mGState.listener.onSubRunning(loader.getEntity());
long range = (long) msg.obj;
mGState.listener.onSubRunning(loaderUtil.getEntity(), range);
break;
case PRE:
mGState.listener.onSubPre(loader.getEntity());
mGState.updateCount(loader.getKey());
case IThreadStateManager.STATE_PRE:
mGState.listener.onSubPre(loaderUtil.getEntity());
mGState.updateCount(loaderUtil.getKey());
break;
case START:
mGState.listener.onSubStart(loader.getEntity());
case IThreadStateManager.STATE_START:
mGState.listener.onSubStart(loaderUtil.getEntity());
break;
case IThreadStateManager.STATE_STOP:
handleStop(loader);
handleStop(loaderUtil, curLocation);
ThreadTaskManager.getInstance().removeSingleTaskThread(mKey, threadName);
break;
case IThreadStateManager.STATE_COMPLETE:
handleComplete(loader);
handleComplete(loaderUtil);
ThreadTaskManager.getInstance().removeSingleTaskThread(mKey, threadName);
break;
case IThreadStateManager.STATE_FAIL:
handleFail(loader);
handleFail(loaderUtil);
ThreadTaskManager.getInstance().removeSingleTaskThread(mKey, threadName);
break;
}
return true;
@ -96,7 +108,7 @@ class SimpleSchedulers implements Handler.Callback {
final int reTryNum = num;
if ((!NetUtils.isConnected(AriaConfig.getInstance().getAPP()) && !isNotNetRetry)
|| loaderUtil.getDownloader() == null // 如果获取不到文件信息,loader为空
|| loaderUtil.getLoader() == null // 如果获取不到文件信息,loader为空
|| loaderUtil.getEntity().getFailNum() > reTryNum) {
mQueue.removeTaskFromExecQ(loaderUtil);
mGState.listener.onSubFail(loaderUtil.getEntity(), new TaskException(TAG,
@ -136,8 +148,8 @@ class SimpleSchedulers implements Handler.Callback {
* 1所有的子任务已经停止则认为组合任务停止
* 2completeNum + failNum + stopNum = subSize则认为组合任务停止
*/
private synchronized void handleStop(AbsSubDLoadUtil loadUtil) {
mGState.listener.onSubStop(loadUtil.getEntity());
private synchronized void handleStop(AbsSubDLoadUtil loadUtil, long curLocation) {
mGState.listener.onSubStop(loadUtil.getEntity(), curLocation);
mGState.countStopNum(loadUtil.getKey());
if (mGState.getStopNum() == mGState.getSubSize()
|| mGState.getStopNum()

@ -17,6 +17,7 @@ package com.arialyy.aria.core.group;
import com.arialyy.aria.core.config.Configuration;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
@ -29,7 +30,7 @@ import java.util.Set;
* 组合任务队列该队列生命周期和{@link AbsGroupLoaderUtil}生命周期一致
*/
class SimpleSubQueue implements ISubQueue<AbsSubDLoadUtil> {
private static final String TAG = "SimpleSubQueue";
private final String TAG = CommonUtil.getClassName(getClass());
/**
* 缓存下载器
*/
@ -162,12 +163,7 @@ class SimpleSubQueue implements ISubQueue<AbsSubDLoadUtil> {
}
@Override public void removeTaskFromExecQ(AbsSubDLoadUtil fileer) {
if (mExec.containsKey(fileer.getKey())) {
if (fileer.isRunning()) {
fileer.stop();
}
mExec.remove(fileer.getKey());
}
mExec.remove(fileer.getKey());
}
@Override public void removeTask(AbsSubDLoadUtil fileer) {

@ -32,8 +32,10 @@ public interface IThreadStateManager extends ILoaderComponent {
int STATE_UPDATE_PROGRESS = 0x06;
int STATE_PRE = 0x07;
int STATE_START = 0x08;
String KEY_RETRY = "KEY_RETRY";
String KEY_ERROR_INFO = "KEY_ERROR_INFO";
String DATA_RETRY = "DATA_RETRY";
String DATA_ERROR_INFO = "DATA_ERROR_INFO";
String DATA_THREAD_NAME = "DATA_THREAD_NAME";
String DATA_THREAD_LOCATION = "DATA_THREAD_LOCATION";
/**
* 任务是否已经失败

@ -21,8 +21,8 @@ import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupEntity;
import com.arialyy.aria.core.group.GroupSendParams;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.inf.TaskSchedulerType;
import com.arialyy.aria.core.loader.IRecordHandler;
import com.arialyy.aria.core.task.AbsTask;
import com.arialyy.aria.core.task.DownloadGroupTask;
import com.arialyy.aria.exception.BaseException;
@ -47,6 +47,7 @@ public class DownloadGroupListener
@Override
public void onSubPre(DownloadEntity subEntity) {
handleSpeed(subEntity, 0);
saveSubState(IEntity.STATE_PRE, subEntity);
sendInState2Target(ISchedulers.SUB_PRE, subEntity);
}
@ -58,12 +59,15 @@ public class DownloadGroupListener
@Override
public void onSubStart(DownloadEntity subEntity) {
handleSpeed(subEntity, 0);
saveSubState(IEntity.STATE_RUNNING, subEntity);
sendInState2Target(ISchedulers.SUB_START, subEntity);
}
@Override
public void onSubStop(DownloadEntity subEntity) {
public void onSubStop(DownloadEntity subEntity, long stopLocation) {
subEntity.setCurrentProgress(stopLocation);
handleSpeed(subEntity, 0);
saveSubState(IEntity.STATE_STOP, subEntity);
saveCurrentLocation();
sendInState2Target(ISchedulers.SUB_STOP, subEntity);
@ -71,6 +75,7 @@ public class DownloadGroupListener
@Override
public void onSubComplete(DownloadEntity subEntity) {
handleSpeed(subEntity, 0);
saveSubState(IEntity.STATE_COMPLETE, subEntity);
saveCurrentLocation();
sendInState2Target(ISchedulers.SUB_COMPLETE, subEntity);
@ -78,6 +83,7 @@ public class DownloadGroupListener
@Override
public void onSubFail(DownloadEntity subEntity, BaseException e) {
handleSpeed(subEntity, 0);
saveSubState(IEntity.STATE_FAIL, subEntity);
saveCurrentLocation();
sendInState2Target(ISchedulers.SUB_FAIL, subEntity);
@ -89,13 +95,16 @@ public class DownloadGroupListener
@Override
public void onSubCancel(DownloadEntity subEntity) {
handleSpeed(subEntity, 0);
saveSubState(IEntity.STATE_CANCEL, subEntity);
saveCurrentLocation();
sendInState2Target(ISchedulers.SUB_CANCEL, subEntity);
}
@Override
public void onSubRunning(DownloadEntity subEntity) {
public void onSubRunning(DownloadEntity subEntity, long currentProgress) {
handleSpeed(subEntity, currentProgress);
if (System.currentTimeMillis() - mLastSaveTime >= RUN_SAVE_INTERVAL) {
saveSubState(IEntity.STATE_RUNNING, subEntity);
mLastSaveTime = System.currentTimeMillis();
@ -103,6 +112,21 @@ public class DownloadGroupListener
sendInState2Target(ISchedulers.SUB_RUNNING, subEntity);
}
private void handleSpeed(DownloadEntity subEntity, long currentProgress) {
if (currentProgress == 0){
subEntity.setSpeed(0);
subEntity.setConvertSpeed("0kb/s");
return;
}
long range = currentProgress - subEntity.getCurrentProgress() ;
subEntity.setSpeed(range);
subEntity.setConvertSpeed(
range <= 0 ? "" : String.format("%s/s", CommonUtil.formatFileSize(range)));
subEntity.setPercent((int) (subEntity.getFileSize() <= 0 ? 0
: subEntity.getCurrentProgress() * 100 / subEntity.getFileSize()));
subEntity.setCurrentProgress(currentProgress);
}
/**
* 将任务状态发送给下载器
*

@ -16,7 +16,6 @@
package com.arialyy.aria.core.listener;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.listener.IDLoadListener;
import com.arialyy.aria.exception.BaseException;
/**
@ -45,7 +44,7 @@ public interface IDGroupListener extends IDLoadListener {
/**
* 子任务停止下载
*/
void onSubStop(DownloadEntity subEntity);
void onSubStop(DownloadEntity subEntity, long stopLocation);
/**
* 子任务下载完成
@ -64,6 +63,8 @@ public interface IDGroupListener extends IDLoadListener {
/**
* 子任务执行中
*
* @param currentProgress 当前进度
*/
void onSubRunning(DownloadEntity subEntity);
void onSubRunning(DownloadEntity subEntity, long currentProgress);
}

@ -84,6 +84,8 @@ public abstract class AbsNormalTTBuilder implements IThreadTaskBuilder {
config.taskWrapper = mWrapper;
config.record = record;
config.stateHandler = mStateHandler;
config.threadType = SubThreadConfig.getThreadType(mWrapper.getRequestType());
config.updateInterval = SubThreadConfig.getUpdateInterval(mWrapper.getRequestType());
return createThreadTask(config);
}

@ -90,8 +90,8 @@ public class NormalThreadStateManager implements IThreadStateManager {
mFailNum++;
if (isFail()) {
Bundle b = msg.getData();
mListener.onFail(b.getBoolean(KEY_RETRY, false),
(BaseException) b.getSerializable(KEY_ERROR_INFO));
mListener.onFail(b.getBoolean(DATA_RETRY, false),
(BaseException) b.getSerializable(DATA_ERROR_INFO));
quitLooper();
}
break;

@ -15,13 +15,17 @@
*/
package com.arialyy.aria.core.loader;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.common.CompleteInfo;
import com.arialyy.aria.core.inf.IThreadStateManager;
import com.arialyy.aria.core.listener.ISchedulers;
import com.arialyy.aria.core.manager.ThreadTaskManager;
import com.arialyy.aria.core.task.IThreadTask;
import com.arialyy.aria.core.task.ThreadTask;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.exception.BaseException;
import com.arialyy.aria.util.ALog;
@ -42,29 +46,84 @@ public final class SubLoader implements ILoader, ILoaderVisitor {
private IThreadTaskBuilder ttBuild;
private IRecordHandler recordHandler;
private IThreadTask threadTask;
private String parentKey;
public SubLoader(AbsTaskWrapper wrapper, Handler schedulers) {
this.wrapper = wrapper;
this.schedulers = schedulers;
}
public AbsTaskWrapper getWrapper() {
return wrapper;
}
/**
* 发送状态到调度器
*
* @param state {@link IThreadStateManager}
*/
private void sendNormalState(int state) {
Message msg = schedulers.obtainMessage();
Bundle b = msg.getData();
if (b == null) {
b = new Bundle();
}
b.putString(IThreadStateManager.DATA_THREAD_NAME, getKey());
msg.what = state;
msg.setData(b);
msg.sendToTarget();
}
/**
* 发送失败的状态
*/
private void sendFailState(boolean needRetry) {
Message msg = schedulers.obtainMessage();
Bundle b = msg.getData();
if (b == null) {
b = new Bundle();
}
b.putString(IThreadStateManager.DATA_THREAD_NAME, getKey());
b.putBoolean(IThreadStateManager.DATA_RETRY, needRetry);
msg.what = IThreadStateManager.STATE_FAIL;
msg.setData(b);
msg.sendToTarget();
}
private void handlerTask() {
List<IThreadTask> task =
ttBuild.buildThreadTask(recordHandler.getRecord(wrapper.getEntity().getFileSize()),
schedulers);
TaskRecord record = recordHandler.getRecord(wrapper.getEntity().getFileSize());
if (record.threadRecords != null
&& !record.threadRecords.isEmpty()
&& record.threadRecords.get(0).isComplete) {
ALog.d(TAG, "子任务已完成,key:" + wrapper.getKey());
sendNormalState(IThreadStateManager.STATE_COMPLETE);
return;
}
List<IThreadTask> task = ttBuild.buildThreadTask(record, schedulers);
if (task == null || task.isEmpty()) {
ALog.e(TAG, "创建子任务的线程任务失败,key:" + getKey());
//schedulers.obtainMessage(ISchedulers.FAIL, SubLoader.this).sendToTarget();
ALog.e(TAG, "创建子任务的线程任务失败,key:" + wrapper.getKey());
sendFailState(false);
return;
}
if (TextUtils.isEmpty(parentKey)) {
ALog.e(TAG, "parentKey为空");
sendFailState(false);
return;
}
sendNormalState(IThreadStateManager.STATE_PRE);
threadTask = task.get(0);
try {
ThreadTaskManager.getInstance().startThread(getKey(), threadTask);
ThreadTaskManager.getInstance().startThread(parentKey, threadTask);
sendNormalState(IThreadStateManager.STATE_START);
} catch (Exception e) {
e.printStackTrace();
}
}
public void setParentKey(String parentKey) {
this.parentKey = parentKey;
}
public void setNeedGetInfo(boolean needGetInfo) {
this.needGetInfo = needGetInfo;
}
@ -91,7 +150,7 @@ public final class SubLoader implements ILoader, ILoaderVisitor {
}
@Override public boolean isRunning() {
return !threadTask.isBreak();
return threadTask != null && !threadTask.isBreak();
}
@Override public void cancel() {
@ -112,8 +171,13 @@ public final class SubLoader implements ILoader, ILoaderVisitor {
return false;
}
/**
* 线程名一个子任务的loader只有一个线程使用线程名标示key
*
* @return {@link ThreadTask#getThreadName()}
*/
@Override public String getKey() {
return wrapper.getKey();
return CommonUtil.getThreadName(wrapper.getKey(), 0);
}
/**
@ -136,7 +200,7 @@ public final class SubLoader implements ILoader, ILoaderVisitor {
}
@Override public void onFail(AbsEntity entity, BaseException e, boolean needRetry) {
schedulers.obtainMessage(ISchedulers.FAIL, SubLoader.this).sendToTarget();
sendFailState(needRetry);
}
});
}

@ -16,6 +16,7 @@
package com.arialyy.aria.core.manager;
import android.text.TextUtils;
import com.arialyy.aria.core.task.IThreadTask;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.util.ALog;
@ -24,7 +25,6 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
@ -153,6 +153,49 @@ public class ThreadTaskManager {
}
}
/**
* 根据线程名删除任务的中的线程
*
* @param key 任务的key如果是组合任务则为组合任务的key
* @param threadName 线程名
* @return true 删除线程成功false 删除线程失败
*/
public boolean removeSingleTaskThread(String key, String threadName) {
try {
LOCK.tryLock(2, TimeUnit.SECONDS);
if (mExePool.isShutdown()) {
ALog.e(TAG, "线程池已经关闭");
return false;
}
if (TextUtils.isEmpty(threadName)) {
ALog.e(TAG, "线程名为空");
return false;
}
key = getKey(key);
Set<FutureContainer> temp = mThreadTasks.get(key);
if (temp != null && temp.size() > 0) {
FutureContainer tempC = null;
for (FutureContainer container : temp) {
if (container.threadTask.getThreadName().equals(threadName)) {
tempC = container;
break;
}
}
if (tempC != null) {
tempC.threadTask.destroy();
temp.remove(tempC);
return true;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
LOCK.unlock();
}
return false;
}
/**
* 删除单个线程任务
*

@ -90,7 +90,11 @@ public interface IThreadTask extends Callable<IThreadTask> {
/**
* 获取线程id
* @return
*/
int getThreadId();
/**
* 线程名字命名规则md5(任务地址 + 线程id)
*/
String getThreadName();
}

@ -53,7 +53,7 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
private IEntity mEntity;
protected AbsTaskWrapper mTaskWrapper;
private int mFailTimes = 0;
private long mLastSaveTime;
private long mLastSaveTime, mLastSendProgressTime;
private boolean isNotNetRetry; //断网情况是否重试
private boolean taskBreak = false; //任务跳出
private boolean isDestroy = false;
@ -67,6 +67,8 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
private long mRangeProgress;
private IThreadTaskAdapter mAdapter;
private ThreadRecord mRecord;
private String mThreadNmae;
private long updateInterval = 1000; // 更新间隔
private Thread mConfigThread = new Thread(new Runnable() {
@Override public void run() {
@ -87,6 +89,7 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
isNotNetRetry = AriaConfig.getInstance().getAConfig().isNotNetRetry();
mRangeProgress = mRecord.startLocation;
updateInterval = config.updateInterval;
}
/**
@ -219,7 +222,7 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
blockFile.getName(), blockFile.length(), mRecord.blockLen, mRecord.startLocation,
mRecord.endLocation));
if (blockFile.exists()) {
blockFile.delete();
FileUtil.deleteFile(blockFile);
ALog.i(TAG, String.format("删除分块【%s】成功", blockFile.getName()));
}
retryBlockTask(isBreak());
@ -232,19 +235,24 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
return mRecord.threadId;
}
@Override public String getThreadName() {
return mThreadNmae == null ? CommonUtil.getThreadName(getConfig().url, getThreadId())
: mThreadNmae;
}
/**
* 停止任务
*/
@Override
public void stop() {
isStop = true;
final long stopLocation = mRangeProgress;
updateState(IThreadStateManager.STATE_STOP, null);
if (mTaskWrapper.getRequestType() == ITaskWrapper.M3U8_VOD) {
writeConfig(false, getConfig().tempFile.length());
ALog.i(TAG, String.format("任务【%s】已停止", getFileName()));
} else {
if (mTaskWrapper.isSupportBP()) {
final long stopLocation = mRangeProgress;
ALog.d(TAG,
String.format("任务【%s】thread__%s__停止【当前线程停止位置:%s】", getFileName(),
mRecord.threadId, stopLocation));
@ -264,12 +272,14 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
@Override
public synchronized void updateState(int state, Bundle bundle) {
Message msg = mStateHandler.obtainMessage();
msg.what = state;
if (bundle != null) {
msg.setData(bundle);
if (bundle == null) {
bundle = new Bundle();
}
int reqType = mTaskWrapper.getRequestType();
msg.setData(bundle);
bundle.putString(IThreadStateManager.DATA_THREAD_NAME, getThreadName());
bundle.putLong(IThreadStateManager.DATA_THREAD_LOCATION, mRangeProgress);
msg.what = state;
int reqType = getConfig().threadType;
if (reqType == ITaskWrapper.M3U8_VOD || reqType == ITaskWrapper.M3U8_LIVE) {
sendM3U8Info(state, msg);
}
@ -287,9 +297,6 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
}
Bundle bundle = msg.getData();
if ((state == IThreadStateManager.STATE_COMPLETE || state == IThreadStateManager.STATE_FAIL)) {
if (bundle == null) {
bundle = new Bundle();
}
bundle.putString(ISchedulers.DATA_M3U8_URL, getConfig().url);
bundle.putString(ISchedulers.DATA_M3U8_PEER_PATH, getConfig().tempFile.getPath());
bundle.putInt(ISchedulers.DATA_M3U8_PEER_INDEX, getConfig().peerIndex);
@ -318,7 +325,21 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
if (!loopThread.isAlive() || loopThread.isInterrupted()) {
return;
}
mStateHandler.obtainMessage(IThreadStateManager.STATE_RUNNING, len).sendToTarget();
// 不需要太频繁发送,以减少消息队列的压力
if (System.currentTimeMillis() - mLastSendProgressTime > updateInterval) {
Message msg = mStateHandler.obtainMessage();
Bundle b = msg.getData();
if (b == null) {
b = new Bundle();
msg.setData(b);
}
b.putString(IThreadStateManager.DATA_THREAD_NAME, getThreadName());
msg.what = IThreadStateManager.STATE_RUNNING;
msg.obj = mRangeProgress;
msg.sendToTarget();
mLastSendProgressTime = System.currentTimeMillis();
}
if (System.currentTimeMillis() - mLastSaveTime > 5000
&& mRangeProgress < mRecord.endLocation) {
mLastSaveTime = System.currentTimeMillis();
@ -435,7 +456,7 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
*/
if (blockFileLen > threadRect) {
ALog.i(TAG, String.format("分块【%s】错误,将重新下载该分块", temp.getName()));
temp.delete();
FileUtil.deleteFile(temp);
mRecord.startLocation = mRecord.endLocation - mRecord.blockLen;
mRecord.isComplete = false;
} else if (blockFileLen < mRecord.blockLen) {
@ -459,9 +480,9 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
*/
private void sendFailMsg(BaseException e, boolean needRetry) {
Bundle b = new Bundle();
b.putBoolean(IThreadStateManager.KEY_RETRY, needRetry);
b.putBoolean(IThreadStateManager.DATA_RETRY, needRetry);
if (e != null) {
b.putSerializable(IThreadStateManager.KEY_ERROR_INFO, e);
b.putSerializable(IThreadStateManager.DATA_ERROR_INFO, e);
updateState(IThreadStateManager.STATE_FAIL, b);
} else {
updateState(IThreadStateManager.STATE_FAIL, b);

@ -97,7 +97,10 @@ public interface ITaskWrapper {
IEntity getEntity();
/**
* 获取任务唯一标志
* 获取任务唯一标志
* 下载任务对应文件的下载地址
* 上传任务对应需要上传的文件路径
* 组合任务对应组合任务的groupHash
*/
String getKey();
}

@ -61,6 +61,16 @@ public class CommonUtil {
public static final String SERVER_CHARSET = "ISO-8859-1";
private static long lastClickTime;
/**
* 获取线程名称命名规则md5(任务地址 + 线程id)
*
* @param url 任务地址
* @param threadId 线程id
*/
public static String getThreadName(String url, int threadId) {
return getStrMd5(url.concat(String.valueOf(threadId)));
}
/**
* 检查sql的expression是否合法
*
@ -436,7 +446,7 @@ public class CommonUtil {
md.update(str.getBytes());
return new BigInteger(1, md.digest()).toString(16);
} catch (NoSuchAlgorithmException e) {
ALog.e(TAG, e.getMessage());
e.printStackTrace();
}
return "";
}
@ -633,7 +643,7 @@ public class CommonUtil {
ignore.add(field);
}
}
if (!ignore.isEmpty()){
if (!ignore.isEmpty()) {
fields.removeAll(ignore);
}
return fields;

@ -85,7 +85,7 @@ public class RecordUtil {
DbEntity.findRelationData(RecordWrapper.class, "dGroupHash=?", groupEntity.getGroupHash());
if (records == null || records.isEmpty()) {
ALog.w(TAG, "组任务记录删除失败,记录为null");
ALog.w(TAG, "组任务记录删除");
} else {
for (RecordWrapper record : records) {
if (record == null || record.taskRecord == null) {

@ -67,6 +67,7 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
getBinding().setProgress(entity.isComplete() ? 100
: (int) (entity.getCurrentProgress() * 100 / entity.getFileSize()));
}
ALog.d(TAG, "progress = " + getBinding().getProgress());
ALog.d(TAG,
"size = " + entity.getSubEntities().size() + "; len = " + entity.getConvertFileSize());
}
@ -133,11 +134,11 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
}
@DownloadGroup.onPre() protected void onPre(DownloadGroupTask task) {
L.d(TAG, "group pre");
L.d(TAG, "group pre, p = " + task.getPercent());
}
@DownloadGroup.onTaskPre() protected void onTaskPre(DownloadGroupTask task) {
L.d(TAG, "group task pre");
L.d(TAG, "group task pre, p = " + task.getPercent());
getBinding().setFileSize(task.getConvertFileSize());
if (mChildList.getSubData().size() <= 0) {
mChildList.addData(task.getEntity().getSubEntities());
@ -146,7 +147,7 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
@DownloadGroup.onTaskStart() void taskStart(DownloadGroupTask task) {
getBinding().setFileSize(task.getConvertFileSize());
L.d(TAG, "group task create");
L.d(TAG, "group task create, p = " + task.getPercent());
}
@DownloadGroup.onTaskRunning() protected void running(DownloadGroupTask task) {
@ -163,7 +164,7 @@ public class DownloadGroupActivity extends BaseActivity<ActivityDownloadGroupBin
}
@DownloadGroup.onTaskResume() void taskResume(DownloadGroupTask task) {
L.d(TAG, "group task resume");
L.d(TAG, "group task resume, p = " + task.getPercent());
}
@DownloadGroup.onTaskStop() void taskStop(DownloadGroupTask task) {

Loading…
Cancel
Save