parent
dbddf3b4e2
commit
b976348ffe
@ -1,34 +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.command.group; |
||||
|
||||
import com.arialyy.aria.core.inf.AbsGroupTaskWrapper; |
||||
|
||||
/** |
||||
* Created by AriaL on 2017/6/29. |
||||
* 删除任务组子任务 |
||||
*/ |
||||
class GroupCancelCmd<T extends AbsGroupTaskWrapper> extends AbsGroupCmd<T> { |
||||
GroupCancelCmd(T entity) { |
||||
super(entity); |
||||
} |
||||
|
||||
@Override public void executeCmd() { |
||||
if (checkTask()) { |
||||
tempTask.cancelSubTask(childUrl); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,146 @@ |
||||
/* |
||||
* 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.download.group; |
||||
|
||||
import android.os.Handler; |
||||
import com.arialyy.aria.core.download.DownloadEntity; |
||||
import com.arialyy.aria.core.inf.IDownloadListener; |
||||
import com.arialyy.aria.core.inf.IEntity; |
||||
import com.arialyy.aria.core.scheduler.ISchedulers; |
||||
import com.arialyy.aria.exception.BaseException; |
||||
import com.arialyy.aria.util.CommonUtil; |
||||
|
||||
/** |
||||
* 子任务事件监听 |
||||
*/ |
||||
class ChildDownloadListener implements IDownloadListener { |
||||
private DownloadEntity subEntity; |
||||
private int RUN_SAVE_INTERVAL = 5 * 1000; //5s保存一次下载中的进度
|
||||
private long lastSaveTime; |
||||
private long lastLen; |
||||
private Handler schedulers; |
||||
private SubDownloadLoader loader; |
||||
|
||||
ChildDownloadListener(Handler schedulers, SubDownloadLoader 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, -1); |
||||
} |
||||
|
||||
@Override public void onPostPre(long fileSize) { |
||||
subEntity.setFileSize(fileSize); |
||||
subEntity.setConvertFileSize(CommonUtil.formatFileSize(fileSize)); |
||||
saveData(IEntity.STATE_POST_PRE, -1); |
||||
sendToTarget(ISchedulers.POST_PRE, loader); |
||||
} |
||||
|
||||
@Override public void onResume(long resumeLocation) { |
||||
lastLen = resumeLocation; |
||||
saveData(IEntity.STATE_POST_PRE, IEntity.STATE_RUNNING); |
||||
sendToTarget(ISchedulers.START, loader); |
||||
} |
||||
|
||||
@Override public void onStart(long startLocation) { |
||||
lastLen = startLocation; |
||||
saveData(IEntity.STATE_POST_PRE, IEntity.STATE_RUNNING); |
||||
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, lastLen); |
||||
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, SubDownloadLoader util) { |
||||
schedulers.obtainMessage(state, util).sendToTarget(); |
||||
} |
||||
} |
@ -0,0 +1,169 @@ |
||||
/* |
||||
* 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.download.group; |
||||
|
||||
import com.arialyy.aria.core.inf.AbsTaskWrapper; |
||||
import java.util.HashSet; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* 组合任务执行中的状态信息 |
||||
*/ |
||||
class GroupRunState { |
||||
/** |
||||
* 子任务数 |
||||
*/ |
||||
private int mSubSize; |
||||
|
||||
/** |
||||
* 已经完成的任务数 |
||||
*/ |
||||
private int mCompleteNum; |
||||
|
||||
/** |
||||
* 失败的任务数 |
||||
*/ |
||||
private int mFailNum; |
||||
|
||||
/** |
||||
* 停止的任务数 |
||||
*/ |
||||
private int mStopNum; |
||||
|
||||
/** |
||||
* 当前进度 |
||||
*/ |
||||
private long mProgress; |
||||
|
||||
/** |
||||
* 组合任务监听 |
||||
*/ |
||||
IDownloadGroupListener listener; |
||||
|
||||
/** |
||||
* 子任务队列 |
||||
*/ |
||||
SimpleSubQueue queue; |
||||
|
||||
/** |
||||
* 是否在执行 |
||||
*/ |
||||
boolean isRunning = false; |
||||
|
||||
/** |
||||
* 子任务失败、停止记录,用于当子任务失败重新被用户点击开始时,更新{@link #mStopNum}或{@link #mFailNum} |
||||
* 保存的数据为:子任务key |
||||
*/ |
||||
private Set<String> mFailTemp = new HashSet<>(), mStopTemp = new HashSet<>(); |
||||
|
||||
private String mGroupHash; |
||||
|
||||
GroupRunState(String groupHash, IDownloadGroupListener listener, int subSize, |
||||
SimpleSubQueue queue) { |
||||
this.listener = listener; |
||||
this.queue = queue; |
||||
mSubSize = subSize; |
||||
mGroupHash = groupHash; |
||||
} |
||||
|
||||
String getGroupHash() { |
||||
return mGroupHash; |
||||
} |
||||
|
||||
/** |
||||
* 获取组合任务子任务数 |
||||
*/ |
||||
int getSubSize() { |
||||
return mSubSize; |
||||
} |
||||
|
||||
/** |
||||
* 获取失败的数量 |
||||
*/ |
||||
int getFailNum() { |
||||
return mFailNum; |
||||
} |
||||
|
||||
/** |
||||
* 获取停止的数量 |
||||
*/ |
||||
int getStopNum() { |
||||
return mStopNum; |
||||
} |
||||
|
||||
/** |
||||
* 获取完成的数量 |
||||
*/ |
||||
int getCompleteNum() { |
||||
return mCompleteNum; |
||||
} |
||||
|
||||
/** |
||||
* 获取当前组合任务总进度 |
||||
*/ |
||||
long getProgress() { |
||||
return mProgress; |
||||
} |
||||
|
||||
/** |
||||
* 更新完成的数量,mCompleteNum + 1 |
||||
*/ |
||||
void updateCompleteNum() { |
||||
mCompleteNum++; |
||||
} |
||||
|
||||
/** |
||||
* 更新任务进度 |
||||
*/ |
||||
void updateProgress(long newProgress) { |
||||
this.mProgress = newProgress; |
||||
} |
||||
|
||||
/** |
||||
* 当子任务开始时,更新停止\失败的任务数 |
||||
* |
||||
* @param key {@link AbsTaskWrapper#getKey()} |
||||
*/ |
||||
void updateCount(String key) { |
||||
if (mFailTemp.contains(key)) { |
||||
mFailTemp.remove(key); |
||||
mFailNum--; |
||||
} else if (mStopTemp.contains(key)) { |
||||
mStopTemp.remove(key); |
||||
mStopNum--; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 统计子任务停止的数量 |
||||
* |
||||
* @param key {@link AbsTaskWrapper#getKey()} |
||||
*/ |
||||
void countStopNum(String key) { |
||||
mStopTemp.add(key); |
||||
mStopNum++; |
||||
} |
||||
|
||||
/** |
||||
* 统计子任务失败的数量 |
||||
* |
||||
* @param key {@link AbsTaskWrapper#getKey()} |
||||
*/ |
||||
void countFailNum(String key) { |
||||
mFailTemp.add(key); |
||||
mFailNum++; |
||||
} |
||||
} |
@ -0,0 +1,113 @@ |
||||
/* |
||||
* 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.download.group; |
||||
|
||||
import android.os.Handler; |
||||
import com.arialyy.aria.core.common.CompleteInfo; |
||||
import com.arialyy.aria.core.common.IUtil; |
||||
import com.arialyy.aria.core.common.OnFileInfoCallback; |
||||
import com.arialyy.aria.core.download.DTaskWrapper; |
||||
import com.arialyy.aria.core.download.DownloadEntity; |
||||
import com.arialyy.aria.core.download.downloader.Downloader; |
||||
import com.arialyy.aria.core.download.downloader.HttpFileInfoThread; |
||||
import com.arialyy.aria.core.scheduler.ISchedulers; |
||||
import com.arialyy.aria.exception.BaseException; |
||||
|
||||
/** |
||||
* 子任务下载工具,负责创建{@link Downloader} |
||||
*/ |
||||
class SubDownloadLoader implements IUtil { |
||||
|
||||
private Downloader mDownloader; |
||||
private DTaskWrapper mWrapper; |
||||
private Handler mSchedulers; |
||||
private ChildDownloadListener mListener; |
||||
|
||||
SubDownloadLoader(Handler schedulers, DTaskWrapper taskWrapper) { |
||||
mWrapper = taskWrapper; |
||||
mSchedulers = schedulers; |
||||
mListener = new ChildDownloadListener(mSchedulers, SubDownloadLoader.this); |
||||
} |
||||
|
||||
@Override public String getKey() { |
||||
return mWrapper.getKey(); |
||||
} |
||||
|
||||
public DTaskWrapper getWrapper() { |
||||
return mWrapper; |
||||
} |
||||
|
||||
public DownloadEntity getEntity() { |
||||
return mWrapper.getEntity(); |
||||
} |
||||
|
||||
/** |
||||
* 重新开始任务 |
||||
*/ |
||||
void reStart() { |
||||
if (mDownloader != null) { |
||||
mDownloader.retryTask(); |
||||
} |
||||
} |
||||
|
||||
@Override public long getFileSize() { |
||||
return mDownloader == null ? -1 : mDownloader.getFileSize(); |
||||
} |
||||
|
||||
@Override public long getCurrentLocation() { |
||||
return mDownloader == null ? -1 : mDownloader.getCurrentLocation(); |
||||
} |
||||
|
||||
@Override public boolean isRunning() { |
||||
return mDownloader != null && mDownloader.isRunning(); |
||||
} |
||||
|
||||
@Override public void cancel() { |
||||
if (mDownloader != null) { |
||||
mDownloader.cancel(); |
||||
} |
||||
} |
||||
|
||||
@Override public void stop() { |
||||
if (mDownloader != null) { |
||||
mDownloader.stop(); |
||||
} |
||||
} |
||||
|
||||
@Override public void start() { |
||||
new Thread(new HttpFileInfoThread(mWrapper, new OnFileInfoCallback() { |
||||
|
||||
@Override public void onComplete(String url, CompleteInfo info) { |
||||
mDownloader = new Downloader(mListener, mWrapper); |
||||
mDownloader.start(); |
||||
} |
||||
|
||||
@Override public void onFail(String url, BaseException e, boolean needRetry) { |
||||
mSchedulers.obtainMessage(ISchedulers.FAIL, SubDownloadLoader.this); |
||||
} |
||||
})).start(); |
||||
} |
||||
|
||||
@Override public void resume() { |
||||
start(); |
||||
} |
||||
|
||||
@Override public void setMaxSpeed(int speed) { |
||||
if (mDownloader != null) { |
||||
mDownloader.setMaxSpeed(speed); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue