增加获取执行中的任务api
增加获取剩余时间的api 修复重构loader导致的m3u8问题
This commit is contained in:
@@ -41,6 +41,11 @@ public abstract class AbsEntity extends DbEntity implements IEntity, Parcelable,
|
||||
*/
|
||||
@Ignore private int failNum = 0;
|
||||
|
||||
/**
|
||||
* 剩余时间,单位:s
|
||||
*/
|
||||
@Ignore private int timeLeft = Integer.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* 扩展字段
|
||||
*/
|
||||
@@ -81,6 +86,18 @@ public abstract class AbsEntity extends DbEntity implements IEntity, Parcelable,
|
||||
*/
|
||||
private long stopTime = 0;
|
||||
|
||||
/**
|
||||
* 获取剩余时间,单位:s
|
||||
* 如果是m3u8任务,无法获取剩余时间;m2u8任务如果需要获取剩余时间,请设置文件长度{@link #setFileSize(long)}
|
||||
*/
|
||||
public int getTimeLeft() {
|
||||
return timeLeft;
|
||||
}
|
||||
|
||||
public void setTimeLeft(int timeLeft) {
|
||||
this.timeLeft = timeLeft;
|
||||
}
|
||||
|
||||
public boolean isComplete() {
|
||||
return isComplete;
|
||||
}
|
||||
|
||||
@@ -156,10 +156,18 @@ public class RecordHelper {
|
||||
: mTaskRecord.filePath);
|
||||
ThreadRecord tr = mTaskRecord.threadRecords.get(0);
|
||||
if (!file.exists()) {
|
||||
ALog.w(TAG, String.format("文件【%s】不存在,任务将重新开始", file.getPath()));
|
||||
tr.startLocation = 0;
|
||||
tr.isComplete = false;
|
||||
tr.endLocation = mWrapper.getEntity().getFileSize();
|
||||
// 目标文件
|
||||
File targetFile = new File(mTaskRecord.filePath);
|
||||
// 处理组合任务其中一个子任务完成的情况
|
||||
if (tr.isComplete && targetFile.exists() && targetFile.length() == mWrapper.getEntity()
|
||||
.getFileSize()) {
|
||||
tr.isComplete = true;
|
||||
} else {
|
||||
ALog.w(TAG, String.format("文件【%s】不存在,任务将重新开始", file.getPath()));
|
||||
tr.startLocation = 0;
|
||||
tr.isComplete = false;
|
||||
tr.endLocation = mWrapper.getEntity().getFileSize();
|
||||
}
|
||||
} else if (file.length() > mWrapper.getEntity().getFileSize()) {
|
||||
ALog.i(TAG, String.format("文件【%s】错误,任务重新开始", file.getPath()));
|
||||
FileUtil.deleteFile(file);
|
||||
|
||||
@@ -46,7 +46,7 @@ public class SubThreadConfig {
|
||||
public int peerIndex;
|
||||
// 线程任务类型
|
||||
public int threadType = TYPE_HTTP;
|
||||
// 更新间隔,单位:毫秒
|
||||
// 进度更新间隔,单位:毫秒
|
||||
public long updateInterval = 1000;
|
||||
|
||||
/**
|
||||
|
||||
@@ -272,8 +272,8 @@ public abstract class AbsGroupLoader implements ILoaderVisitor, ILoader {
|
||||
mListener.onComplete();
|
||||
return;
|
||||
}
|
||||
startTimer();
|
||||
handlerTask(looper);
|
||||
startTimer();
|
||||
Looper.loop();
|
||||
}
|
||||
|
||||
|
||||
@@ -140,6 +140,13 @@ public abstract class BaseListener<ENTITY extends AbsEntity, TASK_WRAPPER extend
|
||||
mEntity.setPercent((int) (mEntity.getFileSize() <= 0 ? 0
|
||||
: mEntity.getCurrentProgress() * 100 / mEntity.getFileSize()));
|
||||
}
|
||||
if (mEntity.getFileSize() != 0) {
|
||||
if (speed == 0) {
|
||||
mEntity.setTimeLeft(Integer.MAX_VALUE);
|
||||
} else {
|
||||
mEntity.setTimeLeft((int) ((mEntity.getFileSize() - mEntity.getCurrentProgress()) / speed));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,7 +22,6 @@ 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.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;
|
||||
@@ -113,18 +112,25 @@ public class DownloadGroupListener
|
||||
}
|
||||
|
||||
private void handleSubSpeed(DownloadEntity subEntity, long currentProgress) {
|
||||
if (currentProgress == 0){
|
||||
if (currentProgress == 0) {
|
||||
subEntity.setSpeed(0);
|
||||
subEntity.setConvertSpeed("0kb/s");
|
||||
return;
|
||||
}
|
||||
long range = currentProgress - subEntity.getCurrentProgress() ;
|
||||
subEntity.setSpeed(range);
|
||||
long speed = currentProgress - subEntity.getCurrentProgress();
|
||||
subEntity.setSpeed(speed);
|
||||
subEntity.setConvertSpeed(
|
||||
range <= 0 ? "" : String.format("%s/s", CommonUtil.formatFileSize(range)));
|
||||
speed <= 0 ? "" : String.format("%s/s", CommonUtil.formatFileSize(speed)));
|
||||
subEntity.setPercent((int) (subEntity.getFileSize() <= 0 ? 0
|
||||
: subEntity.getCurrentProgress() * 100 / subEntity.getFileSize()));
|
||||
subEntity.setCurrentProgress(currentProgress);
|
||||
|
||||
if (speed == 0) {
|
||||
subEntity.setTimeLeft(Integer.MAX_VALUE);
|
||||
} else {
|
||||
subEntity.setTimeLeft(
|
||||
(int) ((subEntity.getFileSize() - subEntity.getCurrentProgress()) / speed));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,8 +156,6 @@ public class DownloadGroupListener
|
||||
subEntity.setPercent(100);
|
||||
subEntity.setConvertSpeed("0kb/s");
|
||||
subEntity.setSpeed(0);
|
||||
ALog.i(TAG, String.format("任务【%s】完成,将删除线程任务记录", mEntity.getKey()));
|
||||
RecordUtil.delTaskRecord(subEntity.getFilePath(), IRecordHandler.TYPE_DOWNLOAD, false, false);
|
||||
}
|
||||
subEntity.update();
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ import java.util.concurrent.TimeUnit;
|
||||
*/
|
||||
public abstract class AbsNormalLoader implements ILoaderVisitor, ILoader {
|
||||
protected final String TAG = CommonUtil.getClassName(getClass());
|
||||
;
|
||||
private IEventListener mListener;
|
||||
protected AbsTaskWrapper mTaskWrapper;
|
||||
protected File mTempFile;
|
||||
@@ -127,7 +126,6 @@ public abstract class AbsNormalLoader implements ILoaderVisitor, ILoader {
|
||||
isRuning = true;
|
||||
resetState();
|
||||
onPostPre();
|
||||
startTimer();
|
||||
handleTask(looper);
|
||||
Looper.loop();
|
||||
}
|
||||
@@ -149,7 +147,7 @@ public abstract class AbsNormalLoader implements ILoaderVisitor, ILoader {
|
||||
/**
|
||||
* 启动进度获取定时器
|
||||
*/
|
||||
private synchronized void startTimer() {
|
||||
protected synchronized void startTimer() {
|
||||
if (isBreak()) {
|
||||
return;
|
||||
}
|
||||
@@ -157,25 +155,32 @@ public abstract class AbsNormalLoader implements ILoaderVisitor, ILoader {
|
||||
mTimer = new ScheduledThreadPoolExecutor(1);
|
||||
mTimer.scheduleWithFixedDelay(new Runnable() {
|
||||
@Override public void run() {
|
||||
if (mStateManager.isComplete()
|
||||
|| mStateManager.isFail()
|
||||
|| !isRunning()
|
||||
|| isBreak()) {
|
||||
//ALog.d(TAG, "isComplete = " + mStateManager.isComplete()
|
||||
// + "; isFail = " + mStateManager.isFail()
|
||||
// + "; isRunning = " + isRunning()
|
||||
// + "; isBreak = " + isBreak());
|
||||
ThreadTaskManager.getInstance().removeTaskThread(mTaskWrapper.getKey());
|
||||
closeTimer();
|
||||
onDestroy();
|
||||
} else if (mStateManager.getCurrentProgress() >= 0) {
|
||||
mListener.onProgress(mStateManager.getCurrentProgress());
|
||||
// 线程池中是不抛异常的,没有日志,很难定位问题,需要手动try-catch
|
||||
try {
|
||||
if (mStateManager == null) {
|
||||
ALog.e(TAG, "stateManager is null");
|
||||
} else if (mStateManager.isComplete()
|
||||
|| mStateManager.isFail()
|
||||
|| !isRunning()
|
||||
|| isBreak()) {
|
||||
//ALog.d(TAG, "isComplete = " + mStateManager.isComplete()
|
||||
// + "; isFail = " + mStateManager.isFail()
|
||||
// + "; isRunning = " + isRunning()
|
||||
// + "; isBreak = " + isBreak());
|
||||
ThreadTaskManager.getInstance().removeTaskThread(mTaskWrapper.getKey());
|
||||
closeTimer();
|
||||
onDestroy();
|
||||
} else if (mStateManager.getCurrentProgress() >= 0) {
|
||||
mListener.onProgress(mStateManager.getCurrentProgress());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}, delayTimer(), mUpdateInterval, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public synchronized void closeTimer() {
|
||||
private synchronized void closeTimer() {
|
||||
if (mTimer != null && !mTimer.isShutdown()) {
|
||||
mTimer.shutdown();
|
||||
}
|
||||
|
||||
@@ -125,6 +125,9 @@ public class NormalLoader extends AbsNormalLoader {
|
||||
for (IThreadTask threadTask : getTaskList()) {
|
||||
ThreadTaskManager.getInstance().startThread(mTaskWrapper.getKey(), threadTask);
|
||||
}
|
||||
|
||||
// 启动定时器
|
||||
startTimer();
|
||||
}
|
||||
|
||||
@Override public long getCurrentProgress() {
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.arialyy.aria.core.task;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.text.TextUtils;
|
||||
import com.arialyy.aria.core.common.AbsEntity;
|
||||
import com.arialyy.aria.core.inf.IEntity;
|
||||
import com.arialyy.aria.core.inf.IUtil;
|
||||
import com.arialyy.aria.core.inf.TaskSchedulerType;
|
||||
@@ -71,6 +72,25 @@ public abstract class AbsTask<TASK_WRAPPER extends AbsTaskWrapper>
|
||||
return mUtil;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取剩余时间,单位:s
|
||||
* 如果是m3u8任务,无法获取剩余时间;m2u8任务如果需要获取剩余时间,请设置文件长度{@link AbsEntity#setFileSize(long)}
|
||||
*/
|
||||
public int getTimeLeft() {
|
||||
return getTaskWrapper().getEntity().getTimeLeft();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换时间
|
||||
* 时间<1 小时,显示分秒,显示样式 00:20
|
||||
* 时间 ≥1 小时,显示时分秒,显示样式 01:11:12
|
||||
* 时间 ≥1 天,显示天时分,显示样式 1d 01:11
|
||||
* 时间 ≥7 天,显示样式 ∞
|
||||
*/
|
||||
public String getConvertTimeLeft() {
|
||||
return CommonUtil.formatTime(getTaskWrapper().getEntity().getTimeLeft());
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加扩展数据 读取扩展数据{@link #getExpand(String)}
|
||||
*/
|
||||
@@ -194,12 +214,16 @@ public abstract class AbsTask<TASK_WRAPPER extends AbsTaskWrapper>
|
||||
|
||||
@Override public void start(int type) {
|
||||
mSchedulerType = type;
|
||||
mUtil = createUtil();
|
||||
if (mUtil == null){
|
||||
ALog.e(TAG, "任务工具创建失败");
|
||||
return;
|
||||
}
|
||||
if (type == TaskSchedulerType.TYPE_START_AND_RESET_STATE) {
|
||||
if (getUtil().isRunning()) {
|
||||
ALog.e(TAG, String.format("任务【%s】重启失败", getTaskName()));
|
||||
return;
|
||||
}
|
||||
mUtil = createUtil();
|
||||
mUtil.start();
|
||||
ALog.d(TAG, String.format("任务【%s】重启成功", getTaskName()));
|
||||
return;
|
||||
@@ -216,6 +240,11 @@ public abstract class AbsTask<TASK_WRAPPER extends AbsTaskWrapper>
|
||||
}
|
||||
|
||||
@Override public void stop(int type) {
|
||||
mUtil = createUtil();
|
||||
if (mUtil == null){
|
||||
ALog.e(TAG, "任务工具创建失败");
|
||||
return;
|
||||
}
|
||||
isStop = true;
|
||||
mSchedulerType = type;
|
||||
getUtil().stop();
|
||||
@@ -226,6 +255,11 @@ public abstract class AbsTask<TASK_WRAPPER extends AbsTaskWrapper>
|
||||
}
|
||||
|
||||
@Override public void cancel(int type) {
|
||||
mUtil = createUtil();
|
||||
if (mUtil == null){
|
||||
ALog.e(TAG, "任务工具创建失败");
|
||||
return;
|
||||
}
|
||||
isCancel = true;
|
||||
mSchedulerType = type;
|
||||
getUtil().cancel();
|
||||
|
||||
@@ -67,8 +67,8 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
|
||||
private long mRangeProgress, mLastRangeProgress;
|
||||
private IThreadTaskAdapter mAdapter;
|
||||
private ThreadRecord mRecord;
|
||||
private String mThreadNmae;
|
||||
private long updateInterval = 1000; // 更新间隔
|
||||
private String mThreadName;
|
||||
private long updateInterval; // 更新间隔
|
||||
|
||||
private Thread mConfigThread = new Thread(new Runnable() {
|
||||
@Override public void run() {
|
||||
@@ -243,8 +243,8 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
|
||||
}
|
||||
|
||||
@Override public String getThreadName() {
|
||||
return mThreadNmae == null ? CommonUtil.getThreadName(getConfig().url, getThreadId())
|
||||
: mThreadNmae;
|
||||
return mThreadName == null ? (mThreadName =
|
||||
CommonUtil.getThreadName(getConfig().url, getThreadId())) : mThreadName;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -287,7 +287,7 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
|
||||
bundle.putLong(IThreadStateManager.DATA_THREAD_LOCATION, mRangeProgress);
|
||||
msg.what = state;
|
||||
int reqType = getConfig().threadType;
|
||||
if (reqType == ITaskWrapper.M3U8_VOD || reqType == ITaskWrapper.M3U8_LIVE) {
|
||||
if (reqType == SubThreadConfig.TYPE_M3U8_PEER) {
|
||||
sendM3U8Info(state, msg);
|
||||
}
|
||||
|
||||
@@ -299,10 +299,10 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
|
||||
}
|
||||
|
||||
private void sendM3U8Info(int state, Message msg) {
|
||||
Bundle bundle = msg.getData();
|
||||
if (state != IThreadStateManager.STATE_UPDATE_PROGRESS) {
|
||||
msg.obj = this;
|
||||
}
|
||||
Bundle bundle = msg.getData();
|
||||
if ((state == IThreadStateManager.STATE_COMPLETE || state == IThreadStateManager.STATE_FAIL)) {
|
||||
bundle.putString(ISchedulers.DATA_M3U8_URL, getConfig().url);
|
||||
bundle.putString(ISchedulers.DATA_M3U8_PEER_PATH, getConfig().tempFile.getPath());
|
||||
@@ -313,6 +313,8 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
|
||||
@Override public synchronized void updateCompleteState() {
|
||||
ALog.i(TAG, String.format("任务【%s】线程__%s__完成", getTaskWrapper().getKey(), mRecord.threadId));
|
||||
writeConfig(true, mRecord.endLocation);
|
||||
// 进度发送不是实时的,发送完成任务前,需要更新一次进度
|
||||
sendRunningState();
|
||||
updateState(IThreadStateManager.STATE_COMPLETE, null);
|
||||
}
|
||||
|
||||
@@ -334,17 +336,7 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
|
||||
}
|
||||
// 不需要太频繁发送,以减少消息队列的压力
|
||||
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());
|
||||
b.putLong(IThreadStateManager.DATA_ADD_LEN, mRangeProgress - mLastRangeProgress);
|
||||
msg.what = IThreadStateManager.STATE_RUNNING;
|
||||
msg.obj = mRangeProgress;
|
||||
msg.sendToTarget();
|
||||
sendRunningState();
|
||||
mLastRangeProgress = mRangeProgress;
|
||||
mLastSendProgressTime = System.currentTimeMillis();
|
||||
}
|
||||
@@ -358,6 +350,23 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送执行中的数据
|
||||
*/
|
||||
private void sendRunningState() {
|
||||
Message msg = mStateHandler.obtainMessage();
|
||||
Bundle b = msg.getData();
|
||||
if (b == null) {
|
||||
b = new Bundle();
|
||||
msg.setData(b);
|
||||
}
|
||||
b.putString(IThreadStateManager.DATA_THREAD_NAME, getThreadName());
|
||||
b.putLong(IThreadStateManager.DATA_ADD_LEN, mRangeProgress - mLastRangeProgress);
|
||||
msg.what = IThreadStateManager.STATE_RUNNING;
|
||||
msg.obj = mRangeProgress;
|
||||
msg.sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getThreadProgress() {
|
||||
return mRangeProgress;
|
||||
|
||||
@@ -48,6 +48,7 @@ import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -794,6 +795,39 @@ public class CommonUtil {
|
||||
return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "tb";
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换时间
|
||||
* 时间<1 小时,显示分秒,显示样式 00:20
|
||||
* 时间 ≥1 小时,显示时分秒,显示样式 01:11:12
|
||||
* 时间 ≥1 天,显示天时分,显示样式 1d 01:11
|
||||
* 时间 ≥7 天,显示样式 ∞
|
||||
*
|
||||
* @param seconds 单位为s的时间
|
||||
*/
|
||||
public static String formatTime(int seconds) {
|
||||
String standardTime;
|
||||
if (seconds <= 0) {
|
||||
standardTime = "00:00";
|
||||
} else if (seconds < 60) {
|
||||
standardTime = String.format(Locale.getDefault(), "00:%02d", seconds % 60);
|
||||
} else if (seconds < 3600) {
|
||||
standardTime = String.format(Locale.getDefault(), "%02d:%02d", seconds / 60, seconds % 60);
|
||||
} else if (seconds < 86400) {
|
||||
standardTime =
|
||||
String.format(Locale.getDefault(), "%02d:%02d:%02d", seconds / 3600, seconds % 3600 / 60,
|
||||
seconds % 60);
|
||||
} else if (seconds < 604800) {
|
||||
standardTime =
|
||||
String.format(Locale.getDefault(), "%dd %02d:%02d", seconds / 86400,
|
||||
seconds % 86400 / 3600,
|
||||
seconds % 3600);
|
||||
} else {
|
||||
standardTime = "∞";
|
||||
}
|
||||
|
||||
return standardTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过文件名获取下载配置文件路径
|
||||
*
|
||||
|
||||
@@ -128,6 +128,7 @@ public class ComponentUtil {
|
||||
break;
|
||||
}
|
||||
if (className == null) {
|
||||
ALog.e(TAG, "不识别的类名:" + className);
|
||||
return null;
|
||||
}
|
||||
T util = null;
|
||||
|
||||
Reference in New Issue
Block a user