block manager

v4
lyy 2 years ago
parent b378d9e3f2
commit 3cc9b09055
  1. 4
      FtpComponent/src/main/java/com/arialyy/aria/ftp/download/FtpDLoaderUtil.java
  2. 1
      FtpComponent/src/main/java/com/arialyy/aria/ftp/upload/FtpULoaderUtil.java
  3. 7
      Http/src/main/java/com/arialyy/aria/http/download/HttpDLoaderUtil.java
  4. 3
      Http/src/main/java/com/arialyy/aria/http/download/HttpDTaskOption.kt
  5. 1
      Http/src/main/java/com/arialyy/aria/http/upload/HttpULoaderUtil.java
  6. 4
      M3U8Component/src/main/java/com/arialyy/aria/m3u8/live/LiveStateManager.java
  7. 2
      M3U8Component/src/main/java/com/arialyy/aria/m3u8/vod/M3U8VodLoader.java
  8. 8
      M3U8Component/src/main/java/com/arialyy/aria/m3u8/vod/VodStateManager.java
  9. 20
      PublicComponent/src/main/java/com/arialyy/aria/core/inf/IThreadStateManager.java
  10. 4
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/AbsNormalLoader.java
  11. 12
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/GroupSubThreadStateManager.java
  12. 76
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/TaskThreadStateManager.java
  13. 8
      PublicComponent/src/main/java/com/arialyy/aria/core/loader/UploadThreadStateManager.java
  14. 157
      PublicComponent/src/main/java/com/arialyy/aria/core/task/BlockManager.kt
  15. 30
      PublicComponent/src/main/java/com/arialyy/aria/core/task/BlockState.kt
  16. 4
      SFtpComponent/src/main/java/com/arialyy/aria/sftp/download/SFtpDLoaderUtil.java
  17. 1
      SFtpComponent/src/main/java/com/arialyy/aria/sftp/upload/SFtpULoaderUtil.java

@ -21,7 +21,7 @@ import com.arialyy.aria.core.loader.AbsNormalLoaderUtil;
import com.arialyy.aria.core.loader.LoaderStructure; import com.arialyy.aria.core.loader.LoaderStructure;
import com.arialyy.aria.core.loader.NormalLoader; import com.arialyy.aria.core.loader.NormalLoader;
import com.arialyy.aria.core.loader.NormalTTBuilder; import com.arialyy.aria.core.loader.NormalTTBuilder;
import com.arialyy.aria.core.loader.NormalThreadStateManager; import com.arialyy.aria.core.loader.TaskThreadStateManager;
import com.arialyy.aria.ftp.FtpTaskOption; import com.arialyy.aria.ftp.FtpTaskOption;
/** /**
@ -41,7 +41,7 @@ public final class FtpDLoaderUtil extends AbsNormalLoaderUtil {
public LoaderStructure BuildLoaderStructure() { public LoaderStructure BuildLoaderStructure() {
LoaderStructure structure = new LoaderStructure(); LoaderStructure structure = new LoaderStructure();
structure.addComponent(new FtpDRecordHandler((DTaskWrapper) getTaskWrapper())) structure.addComponent(new FtpDRecordHandler((DTaskWrapper) getTaskWrapper()))
.addComponent(new NormalThreadStateManager(getListener())) .addComponent(new TaskThreadStateManager(getListener()))
.addComponent(new FtpDFileInfoTask((DTaskWrapper) getTaskWrapper())) .addComponent(new FtpDFileInfoTask((DTaskWrapper) getTaskWrapper()))
.addComponent(new NormalTTBuilder(getTaskWrapper(), new FtpDTTBuilderAdapter())); .addComponent(new NormalTTBuilder(getTaskWrapper(), new FtpDTTBuilderAdapter()));
structure.accept(getLoader()); structure.accept(getLoader());

@ -22,7 +22,6 @@ import com.arialyy.aria.core.loader.AbsNormalLoaderUtil;
import com.arialyy.aria.core.loader.AbsNormalTTBuilderAdapter; import com.arialyy.aria.core.loader.AbsNormalTTBuilderAdapter;
import com.arialyy.aria.core.loader.LoaderStructure; import com.arialyy.aria.core.loader.LoaderStructure;
import com.arialyy.aria.core.loader.NormalTTBuilder; import com.arialyy.aria.core.loader.NormalTTBuilder;
import com.arialyy.aria.core.loader.NormalThreadStateManager;
import com.arialyy.aria.core.loader.UploadThreadStateManager; import com.arialyy.aria.core.loader.UploadThreadStateManager;
import com.arialyy.aria.core.task.IThreadTaskAdapter; import com.arialyy.aria.core.task.IThreadTaskAdapter;
import com.arialyy.aria.core.upload.UTaskWrapper; import com.arialyy.aria.core.upload.UTaskWrapper;

@ -16,15 +16,12 @@
package com.arialyy.aria.http.download; package com.arialyy.aria.http.download;
import com.arialyy.aria.core.download.DTaskWrapper; import com.arialyy.aria.core.download.DTaskWrapper;
import com.arialyy.aria.core.listener.IEventListener;
import com.arialyy.aria.core.loader.AbsNormalLoader; import com.arialyy.aria.core.loader.AbsNormalLoader;
import com.arialyy.aria.core.loader.AbsNormalLoaderUtil; import com.arialyy.aria.core.loader.AbsNormalLoaderUtil;
import com.arialyy.aria.core.loader.LoaderStructure; import com.arialyy.aria.core.loader.LoaderStructure;
import com.arialyy.aria.core.loader.NormalLoader; import com.arialyy.aria.core.loader.NormalLoader;
import com.arialyy.aria.core.loader.NormalTTBuilder; import com.arialyy.aria.core.loader.NormalTTBuilder;
import com.arialyy.aria.core.loader.NormalThreadStateManager; import com.arialyy.aria.core.loader.TaskThreadStateManager;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.http.HttpRecordHandler; import com.arialyy.aria.http.HttpRecordHandler;
import com.arialyy.aria.http.HttpTaskOption; import com.arialyy.aria.http.HttpTaskOption;
@ -45,7 +42,7 @@ public final class HttpDLoaderUtil extends AbsNormalLoaderUtil {
public LoaderStructure BuildLoaderStructure() { public LoaderStructure BuildLoaderStructure() {
LoaderStructure structure = new LoaderStructure(); LoaderStructure structure = new LoaderStructure();
structure.addComponent(new HttpRecordHandler(getTaskWrapper())) structure.addComponent(new HttpRecordHandler(getTaskWrapper()))
.addComponent(new NormalThreadStateManager(getListener())) .addComponent(new TaskThreadStateManager(getListener()))
.addComponent(new HttpDFileInfoTask((DTaskWrapper) getTaskWrapper())) .addComponent(new HttpDFileInfoTask((DTaskWrapper) getTaskWrapper()))
.addComponent(new NormalTTBuilder(getTaskWrapper(), new HttpDTTBuilderAdapter())); .addComponent(new NormalTTBuilder(getTaskWrapper(), new HttpDTTBuilderAdapter()));
structure.accept(getLoader()); structure.accept(getLoader());

@ -27,9 +27,6 @@ import com.arialyy.aria.http.HttpOption
**/ **/
class HttpDTaskOption : DTaskOption() { class HttpDTaskOption : DTaskOption() {
companion object {
const val BLOCK_SIZE = 1024 * 1024 * 5
}
var httpOption: HttpOption? = null var httpOption: HttpOption? = null
var fileSizeAdapter: IHttpFileLenAdapter? = null var fileSizeAdapter: IHttpFileLenAdapter? = null

@ -22,7 +22,6 @@ import com.arialyy.aria.core.loader.AbsNormalLoaderUtil;
import com.arialyy.aria.core.loader.AbsNormalTTBuilderAdapter; import com.arialyy.aria.core.loader.AbsNormalTTBuilderAdapter;
import com.arialyy.aria.core.loader.LoaderStructure; import com.arialyy.aria.core.loader.LoaderStructure;
import com.arialyy.aria.core.loader.NormalTTBuilder; import com.arialyy.aria.core.loader.NormalTTBuilder;
import com.arialyy.aria.core.loader.NormalThreadStateManager;
import com.arialyy.aria.core.loader.UploadThreadStateManager; import com.arialyy.aria.core.loader.UploadThreadStateManager;
import com.arialyy.aria.core.task.IThreadTaskAdapter; import com.arialyy.aria.core.task.IThreadTaskAdapter;
import com.arialyy.aria.core.upload.UTaskWrapper; import com.arialyy.aria.core.upload.UTaskWrapper;

@ -137,11 +137,11 @@ final class LiveStateManager implements IThreadStateManager {
} }
} }
@Override public boolean isFail() { @Override public boolean hasFailedBlock() {
return false; return false;
} }
@Override public boolean isComplete() { @Override public boolean isCompleted() {
return false; return false;
} }

@ -161,7 +161,7 @@ final class M3U8VodLoader extends BaseM3U8Loader {
// 启动定时器 // 启动定时器
startTimer(); startTimer();
if (getStateManager().isComplete()){ if (getStateManager().isCompleted()){
Log.d(TAG, "任务已完成"); Log.d(TAG, "任务已完成");
getStateManager().handleTaskComplete(); getStateManager().handleTaskComplete();
return; return;

@ -110,7 +110,7 @@ public final class VodStateManager implements IThreadStateManager {
getListener().onPeerFail(wrapper.getKey(), getListener().onPeerFail(wrapper.getKey(),
msg.getData().getString(ISchedulers.DATA_M3U8_PEER_PATH), peerIndex); msg.getData().getString(ISchedulers.DATA_M3U8_PEER_PATH), peerIndex);
if (isFail()) { if (hasFailedBlock()) {
ALog.d(TAG, String.format("vod任务【%s】失败", loader.getTempFile().getName())); ALog.d(TAG, String.format("vod任务【%s】失败", loader.getTempFile().getName()));
Bundle b = msg.getData(); Bundle b = msg.getData();
listener.onFail(b.getBoolean(DATA_RETRY, true), listener.onFail(b.getBoolean(DATA_RETRY, true),
@ -138,7 +138,7 @@ public final class VodStateManager implements IThreadStateManager {
if (!loader.isJump()) { if (!loader.isJump()) {
loader.notifyWaitLock(true); loader.notifyWaitLock(true);
} }
if (isComplete()) { if (isCompleted()) {
handleTaskComplete(); handleTaskComplete();
} }
break; break;
@ -239,12 +239,12 @@ public final class VodStateManager implements IThreadStateManager {
getEntity().update(); getEntity().update();
} }
@Override public boolean isFail() { @Override public boolean hasFailedBlock() {
printInfo("isFail"); printInfo("isFail");
return failNum.get() != 0 && failNum.get() == loader.getCurrentFlagSize() && !loader.isJump(); return failNum.get() != 0 && failNum.get() == loader.getCurrentFlagSize() && !loader.isJump();
} }
@Override public boolean isComplete() { @Override public boolean isCompleted() {
if (m3U8Option.isIgnoreFailureTs()) { if (m3U8Option.isIgnoreFailureTs()) {
return loader.getCompleteNum() + failNum.get() >= taskRecord.threadRecords.size() return loader.getCompleteNum() + failNum.get() >= taskRecord.threadRecords.size()
&& !loader.isJump(); && !loader.isJump();

@ -16,14 +16,11 @@
package com.arialyy.aria.core.inf; package com.arialyy.aria.core.inf;
import android.os.Handler; import android.os.Handler;
import android.os.Looper;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.loader.ILoaderComponent;
/** /**
* 线程任务状态 * 线程任务状态
*/ */
public interface IThreadStateManager extends ILoaderComponent { public interface IThreadStateManager {
int STATE_STOP = 0x01; int STATE_STOP = 0x01;
int STATE_FAIL = 0x02; int STATE_FAIL = 0x02;
int STATE_CANCEL = 0x03; int STATE_CANCEL = 0x03;
@ -39,18 +36,18 @@ public interface IThreadStateManager extends ILoaderComponent {
String DATA_ADD_LEN = "DATA_ADD_LEN"; // 增加的长度 String DATA_ADD_LEN = "DATA_ADD_LEN"; // 增加的长度
/** /**
* 任务是否已经失败 * 是否有失败的快
* *
* @return true 任务已失败 * @return true 有失败的快
*/ */
boolean isFail(); boolean hasFailedBlock();
/** /**
* 任务是否已经完成 * 任务是否已经完成
* *
* @return true 任务已完成 * @return true 任务已完成
*/ */
boolean isComplete(); boolean isCompleted();
/** /**
* 获取当前任务进度 * 获取当前任务进度
@ -66,10 +63,9 @@ public interface IThreadStateManager extends ILoaderComponent {
*/ */
void updateCurrentProgress(long currentProgress); void updateCurrentProgress(long currentProgress);
/** boolean isStopped();
* 设置消息循环体
*/ boolean isCanceled();
void setLooper(TaskRecord taskRecord, Looper looper);
/** /**
* 创建handler 回调 * 创建handler 回调

@ -166,8 +166,8 @@ public abstract class AbsNormalLoader<T extends AbsTaskWrapper> implements ILoad
try { try {
if (mStateManager == null) { if (mStateManager == null) {
ALog.e(TAG, "stateManager is null"); ALog.e(TAG, "stateManager is null");
} else if (mStateManager.isComplete() } else if (mStateManager.isCompleted()
|| mStateManager.isFail() || mStateManager.hasFailedBlock()
|| !isRunning() || !isRunning()
|| isBreak()) { || isBreak()) {
//ALog.d(TAG, "isComplete = " + mStateManager.isComplete() //ALog.d(TAG, "isComplete = " + mStateManager.isComplete()

@ -22,8 +22,6 @@ import android.os.Message;
import com.arialyy.aria.core.TaskRecord; import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.inf.IThreadStateManager; import com.arialyy.aria.core.inf.IThreadStateManager;
import com.arialyy.aria.core.listener.IEventListener;
import com.arialyy.aria.exception.AriaException;
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 com.arialyy.aria.util.FileUtil; import com.arialyy.aria.util.FileUtil;
@ -95,7 +93,7 @@ public class GroupSubThreadStateManager implements IThreadStateManager {
break; break;
case STATE_FAIL: case STATE_FAIL:
mFailNum.getAndIncrement(); mFailNum.getAndIncrement();
if (isFail()) { if (hasFailedBlock()) {
sendMessageFromMsg(msg); sendMessageFromMsg(msg);
/* Bundle b = msg.getData(); /* Bundle b = msg.getData();
@ -107,7 +105,7 @@ public class GroupSubThreadStateManager implements IThreadStateManager {
break; break;
case STATE_COMPLETE: case STATE_COMPLETE:
mCompleteNum.getAndIncrement(); mCompleteNum.getAndIncrement();
if (isComplete()) { if (isCompleted()) {
ALog.d(TAG, "isComplete, completeNum = " + mCompleteNum); ALog.d(TAG, "isComplete, completeNum = " + mCompleteNum);
//if (mTaskRecord.taskType == ITaskWrapper.D_SFTP) { //if (mTaskRecord.taskType == ITaskWrapper.D_SFTP) {
// mergerSFtp(); // mergerSFtp();
@ -133,7 +131,7 @@ public class GroupSubThreadStateManager implements IThreadStateManager {
//mListener.onComplete(); //mListener.onComplete();
} }
quitLooper(); quitLooper();
}else if (isFail()) { }else if (hasFailedBlock()) {
sendMessageFromMsg(msg); sendMessageFromMsg(msg);
quitLooper(); quitLooper();
} }
@ -210,7 +208,7 @@ public class GroupSubThreadStateManager implements IThreadStateManager {
* 所有子线程是否都已经失败 * 所有子线程是否都已经失败
*/ */
@Override @Override
public boolean isFail() { public boolean hasFailedBlock() {
//ALog.d(TAG, //ALog.d(TAG,
// String.format("isFail; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s", mStopNum, // String.format("isFail; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s", mStopNum,
// mCancelNum, mFailNum, mCompleteNum)); // mCancelNum, mFailNum, mCompleteNum));
@ -222,7 +220,7 @@ public class GroupSubThreadStateManager implements IThreadStateManager {
* 所有子线程是否都已经完成 * 所有子线程是否都已经完成
*/ */
@Override @Override
public boolean isComplete() { public boolean isCompleted() {
//ALog.d(TAG, //ALog.d(TAG,
// String.format("isComplete; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s", // String.format("isComplete; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s",
// mStopNum, // mStopNum,

@ -19,60 +19,56 @@ import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.Message; import android.os.Message;
import com.arialyy.aria.core.TaskRecord;
import com.arialyy.aria.core.inf.IThreadStateManager; import com.arialyy.aria.core.inf.IThreadStateManager;
import com.arialyy.aria.core.listener.IEventListener; import com.arialyy.aria.core.listener.IEventListener;
import com.arialyy.aria.exception.AriaException; import com.arialyy.aria.exception.AriaException;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.aria.util.FileUtil; import com.arialyy.aria.util.FileUtil;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import timber.log.Timber;
/** /**
* 线程任务管理器用于处理多线程下载时任务的状态回调 * 线程任务管理器用于处理多线程下载时任务的状态回调
*/ */
public class NormalThreadStateManager implements IThreadStateManager { public class TaskThreadStateManager implements IThreadStateManager {
private final String TAG = CommonUtil.getClassName(this); /**
* 分块文件路径: 文件路径.blockId.part
*/
public static String SUB_PATH = "%s.%s.part";
/** /**
* 任务状态回调 * 任务状态回调
*/ */
private IEventListener mListener; private final IEventListener mListener;
private int mThreadNum; // 启动的线程总数 private final int mThreadNum; // 启动的线程总数
private AtomicInteger mCancelNum = new AtomicInteger(0); // 已经取消的线程的数 private final AtomicInteger mCancelNum = new AtomicInteger(0); // 已经取消的线程的数
private AtomicInteger mStopNum = new AtomicInteger(0); // 已经停止的线程数 private final AtomicInteger mStopNum = new AtomicInteger(0); // 已经停止的线程数
private AtomicInteger mFailNum = new AtomicInteger(0); // 失败的线程数 private final AtomicInteger mFailNum = new AtomicInteger(0); // 失败的线程数
private AtomicInteger mCompleteNum = new AtomicInteger(0); // 完成的线程数 private final AtomicInteger mCompleteNum = new AtomicInteger(0); // 完成的线程数
private long mProgress; //当前总进度 private long mProgress; //当前总进度
private TaskRecord mTaskRecord; // 任务记录
private Looper mLooper; private Looper mLooper;
/** /**
* @param listener 任务事件 * @param listener 任务事件
*/ */
public NormalThreadStateManager(IEventListener listener) { public TaskThreadStateManager(IEventListener listener, int threadNum) {
mListener = listener; mListener = listener;
mThreadNum = threadNum;
} }
@Override public void setLooper(TaskRecord taskRecord, Looper looper) { @Override public void setLooper(Looper looper) {
mTaskRecord = taskRecord;
mThreadNum = mTaskRecord.threadNum;
mLooper = looper; mLooper = looper;
} }
private void checkLooper() { private void checkLooper() {
if (mTaskRecord == null) {
throw new NullPointerException("任务记录为空");
}
if (mLooper == null) { if (mLooper == null) {
throw new NullPointerException("Looper为空"); throw new NullPointerException("Looper为空");
} }
} }
private Handler.Callback callback = new Handler.Callback() { private final Handler.Callback callback = new Handler.Callback() {
@Override public boolean handleMessage(Message msg) { @Override public boolean handleMessage(Message msg) {
checkLooper(); checkLooper();
switch (msg.what) { switch (msg.what) {
@ -90,7 +86,7 @@ public class NormalThreadStateManager implements IThreadStateManager {
break; break;
case STATE_FAIL: case STATE_FAIL:
mFailNum.getAndIncrement(); mFailNum.getAndIncrement();
if (isFail()) { if (hasFailedBlock()) {
Bundle b = msg.getData(); Bundle b = msg.getData();
mListener.onFail(b.getBoolean(DATA_RETRY, false), mListener.onFail(b.getBoolean(DATA_RETRY, false),
(AriaException) b.getSerializable(DATA_ERROR_INFO)); (AriaException) b.getSerializable(DATA_ERROR_INFO));
@ -99,12 +95,8 @@ public class NormalThreadStateManager implements IThreadStateManager {
break; break;
case STATE_COMPLETE: case STATE_COMPLETE:
mCompleteNum.getAndIncrement(); mCompleteNum.getAndIncrement();
if (isComplete()) { if (isCompleted()) {
ALog.d(TAG, "isComplete, completeNum = " + mCompleteNum); Timber.d("isComplete, completeNum = %s", mCompleteNum);
//if (mTaskRecord.taskType == ITaskWrapper.D_SFTP) {
// mergerSFtp();
// mListener.onComplete();
//} else
if (mTaskRecord.isBlock || mTaskRecord.threadNum == 1) { if (mTaskRecord.isBlock || mTaskRecord.threadNum == 1) {
if (mergeFile()) { if (mergeFile()) {
mListener.onComplete(); mListener.onComplete();
@ -177,7 +169,7 @@ public class NormalThreadStateManager implements IThreadStateManager {
* 所有子线程是否都已经失败 * 所有子线程是否都已经失败
*/ */
@Override @Override
public boolean isFail() { public boolean hasFailedBlock() {
//ALog.d(TAG, //ALog.d(TAG,
// String.format("isFail; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s", mStopNum, // String.format("isFail; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s", mStopNum,
// mCancelNum, mFailNum, mCompleteNum)); // mCancelNum, mFailNum, mCompleteNum));
@ -189,7 +181,7 @@ public class NormalThreadStateManager implements IThreadStateManager {
* 所有子线程是否都已经完成 * 所有子线程是否都已经完成
*/ */
@Override @Override
public boolean isComplete() { public boolean isCompleted() {
//ALog.d(TAG, //ALog.d(TAG,
// String.format("isComplete; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s", // String.format("isComplete; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s",
// mStopNum, // mStopNum,
@ -221,26 +213,6 @@ public class NormalThreadStateManager implements IThreadStateManager {
return size; return size;
} }
/**
* 合并sftp的分块
*/
private boolean mergerSFtp() {
if (mTaskRecord.threadNum == 1) {
File partFile = new File(String.format(IRecordHandler.SUB_PATH, mTaskRecord.filePath, 0));
return partFile.renameTo(new File(mTaskRecord.filePath));
}
List<String> partPath = new ArrayList<>();
for (int i = 0, len = mTaskRecord.threadNum; i < len; i++) {
partPath.add(String.format(IRecordHandler.SUB_PATH, mTaskRecord.filePath, i));
}
FileUtil.mergeSFtpFile(mTaskRecord.filePath, partPath, mTaskRecord.fileLength);
for (String pp : partPath) {
FileUtil.deleteFile(pp);
}
return true;
}
/** /**
* 合并文件 * 合并文件
* *
@ -249,7 +221,7 @@ public class NormalThreadStateManager implements IThreadStateManager {
private boolean mergeFile() { private boolean mergeFile() {
if (mTaskRecord.threadNum == 1) { if (mTaskRecord.threadNum == 1) {
File targetFile = new File(mTaskRecord.filePath); File targetFile = new File(mTaskRecord.filePath);
if (targetFile.exists()){ if (targetFile.exists()) {
//没有获得文件长度:不支持断点续传 //没有获得文件长度:不支持断点续传
if (mTaskRecord.fileLength == 0 && targetFile.length() != 0) { if (mTaskRecord.fileLength == 0 && targetFile.length() != 0) {
return true; return true;
@ -284,8 +256,4 @@ public class NormalThreadStateManager implements IThreadStateManager {
return false; return false;
} }
} }
@Override public void accept(ILoaderVisitor visitor) {
visitor.addComponent(this);
}
} }

@ -92,7 +92,7 @@ public class UploadThreadStateManager implements IThreadStateManager {
break; break;
case STATE_FAIL: case STATE_FAIL:
mFailNum.getAndIncrement(); mFailNum.getAndIncrement();
if (isFail()) { if (hasFailedBlock()) {
Bundle b = msg.getData(); Bundle b = msg.getData();
mListener.onFail(b.getBoolean(DATA_RETRY, false), mListener.onFail(b.getBoolean(DATA_RETRY, false),
(AriaException) b.getSerializable(DATA_ERROR_INFO)); (AriaException) b.getSerializable(DATA_ERROR_INFO));
@ -101,7 +101,7 @@ public class UploadThreadStateManager implements IThreadStateManager {
break; break;
case STATE_COMPLETE: case STATE_COMPLETE:
mCompleteNum.getAndIncrement(); mCompleteNum.getAndIncrement();
if (isComplete()) { if (isCompleted()) {
ALog.d(TAG, "isComplete, completeNum = " + mCompleteNum); ALog.d(TAG, "isComplete, completeNum = " + mCompleteNum);
//上传文件不需要合并文件 //上传文件不需要合并文件
mListener.onComplete(); mListener.onComplete();
@ -167,7 +167,7 @@ public class UploadThreadStateManager implements IThreadStateManager {
* 所有子线程是否都已经失败 * 所有子线程是否都已经失败
*/ */
@Override @Override
public boolean isFail() { public boolean hasFailedBlock() {
//ALog.d(TAG, //ALog.d(TAG,
// String.format("isFail; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s", mStopNum, // String.format("isFail; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s", mStopNum,
// mCancelNum, mFailNum, mCompleteNum)); // mCancelNum, mFailNum, mCompleteNum));
@ -179,7 +179,7 @@ public class UploadThreadStateManager implements IThreadStateManager {
* 所有子线程是否都已经完成 * 所有子线程是否都已经完成
*/ */
@Override @Override
public boolean isComplete() { public boolean isCompleted() {
//ALog.d(TAG, //ALog.d(TAG,
// String.format("isComplete; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s", // String.format("isComplete; stopNum: %s, cancelNum: %s, failNum: %s, completeNum: %s",
// mStopNum, // mStopNum,

@ -0,0 +1,157 @@
/*
* 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.task
import android.os.Handler.Callback
import android.os.Looper
import com.arialyy.aria.core.inf.IThreadStateManager
import com.arialyy.aria.core.listener.IEventListener
import com.arialyy.aria.exception.AriaException
import timber.log.Timber
import java.util.concurrent.atomic.AtomicInteger
class BlockManager(
val mListener: IEventListener,
val looper: Looper,
private val blockNum: Int,
val blockParentDir: String
) : IThreadStateManager {
private val blockList = mutableListOf<BlockState>()
private val canceledNum = AtomicInteger(0) // 已经取消的线程的数
private val stoppedNum = AtomicInteger(0) // 已经停止的线程数
private val failedNum = AtomicInteger(0) // 失败的线程数
private val completedNum = AtomicInteger(0) // 完成的线程数
private var progress: Long = 0 //当前总进度
private val callback = Callback { msg ->
checkLooper()
when (msg.what) {
IThreadStateManager.STATE_STOP -> {
stoppedNum.getAndIncrement()
if (isStopped) {
quitLooper()
}
}
IThreadStateManager.STATE_CANCEL -> {
canceledNum.getAndIncrement()
if (isCanceled) {
quitLooper()
}
}
IThreadStateManager.STATE_FAIL -> {
failedNum.getAndIncrement()
if (hasFailedBlock()) {
val b = msg.data
mListener.onFail(
b.getBoolean(IThreadStateManager.DATA_RETRY, false),
b.getSerializable(IThreadStateManager.DATA_ERROR_INFO) as AriaException?
)
quitLooper()
}
}
IThreadStateManager.STATE_COMPLETE -> {
completedNum.getAndIncrement()
if (isCompleted) {
Timber.d("isComplete, completeNum = %s", completedNum)
if (mTaskRecord.isBlock || mTaskRecord.threadNum === 1) {
if (mergeFile()) {
mListener.onComplete()
} else {
mListener.onFail(false, null)
}
quitLooper()
break
}
mListener.onComplete()
quitLooper()
}
}
IThreadStateManager.STATE_RUNNING -> {
val b = msg.data
if (b != null) {
val len = b.getLong(IThreadStateManager.DATA_ADD_LEN, 0)
progress += len
}
}
IThreadStateManager.STATE_UPDATE_PROGRESS -> if (msg.obj == null) {
progress = updateBlockProgress()
} else if (msg.obj is Long) {
progress = msg.obj as Long
}
}
false
}
/**
* 退出looper循环
*/
private fun quitLooper() {
looper.quit()
}
fun addBlockState(state: BlockState) {
blockList.add(state)
}
fun getBlockState(): BlockState {
return blockList.removeFirst()
}
override fun hasFailedBlock(): Boolean {
Timber.d("isFailed, blockBum = ${blockNum}, completedNum = ${completedNum.get()}, ")
return failedNum.get() != 0
}
override fun isCompleted(): Boolean {
// Timber.d("isCompleted, blockBum = ${blockNum}, completedNum = ${completedNum.get()}, ")
return completedNum.get() == blockNum
}
override fun getCurrentProgress(): Long {
return progress
}
override fun updateCurrentProgress(currentProgress: Long) {
progress = currentProgress
}
/**
* 所有子线程是否都已经停止
*/
override fun isStopped(): Boolean {
// Timber.d("isStopped, blockBum = ${blockNum}, stoppedNum = ${stoppedNum.get()}, completedNum = ${completedNum.get()}, failedNum = ${failedNum.get()}")
return stoppedNum.get() + completedNum.get() + failedNum.get() == blockNum
}
override fun isCanceled(): Boolean {
// Timber.d("isStopped, blockBum = ${blockNum}, canceledNum = $canceledNum")
return canceledNum.get() == blockNum
}
override fun getHandlerCallback(): Callback {
return callback
}
private fun mergeFile(): Boolean {
if (blockNum == 1){
return true
}
}
}

@ -0,0 +1,30 @@
/*
* 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.task
class BlockState(val blockId: Int, val blockPath: String) {
companion object {
/**
* dir/.fileName.blockId
*/
const val BLOCK_PATH = "%s/.%s.%d"
const val BLOCK_SIZE = 1024 * 1024 * 5
}
var curProgress: Long = 0
}

@ -20,7 +20,7 @@ import com.arialyy.aria.core.loader.AbsNormalLoader;
import com.arialyy.aria.core.loader.AbsNormalLoaderUtil; import com.arialyy.aria.core.loader.AbsNormalLoaderUtil;
import com.arialyy.aria.core.loader.LoaderStructure; import com.arialyy.aria.core.loader.LoaderStructure;
import com.arialyy.aria.core.loader.NormalTTBuilder; import com.arialyy.aria.core.loader.NormalTTBuilder;
import com.arialyy.aria.core.loader.NormalThreadStateManager; import com.arialyy.aria.core.loader.TaskThreadStateManager;
import com.arialyy.aria.sftp.SFtpTaskOption; import com.arialyy.aria.sftp.SFtpTaskOption;
/** /**
@ -41,7 +41,7 @@ public class SFtpDLoaderUtil extends AbsNormalLoaderUtil {
@Override public LoaderStructure BuildLoaderStructure() { @Override public LoaderStructure BuildLoaderStructure() {
LoaderStructure structure = new LoaderStructure(); LoaderStructure structure = new LoaderStructure();
structure.addComponent(new SFtpDRecordHandler((DTaskWrapper) getTaskWrapper())) structure.addComponent(new SFtpDRecordHandler((DTaskWrapper) getTaskWrapper()))
.addComponent(new NormalThreadStateManager(getListener())) .addComponent(new TaskThreadStateManager(getListener()))
.addComponent(new SFtpDInfoTask((DTaskWrapper) getTaskWrapper())) .addComponent(new SFtpDInfoTask((DTaskWrapper) getTaskWrapper()))
.addComponent(new NormalTTBuilder(getTaskWrapper(), new SFtpDTTBuilderAdapter( .addComponent(new NormalTTBuilder(getTaskWrapper(), new SFtpDTTBuilderAdapter(
(DTaskWrapper) getTaskWrapper()))); (DTaskWrapper) getTaskWrapper())));

@ -19,7 +19,6 @@ import com.arialyy.aria.core.loader.AbsNormalLoader;
import com.arialyy.aria.core.loader.AbsNormalLoaderUtil; import com.arialyy.aria.core.loader.AbsNormalLoaderUtil;
import com.arialyy.aria.core.loader.LoaderStructure; import com.arialyy.aria.core.loader.LoaderStructure;
import com.arialyy.aria.core.loader.NormalTTBuilder; import com.arialyy.aria.core.loader.NormalTTBuilder;
import com.arialyy.aria.core.loader.NormalThreadStateManager;
import com.arialyy.aria.core.loader.UploadThreadStateManager; import com.arialyy.aria.core.loader.UploadThreadStateManager;
import com.arialyy.aria.core.upload.UTaskWrapper; import com.arialyy.aria.core.upload.UTaskWrapper;
import com.arialyy.aria.sftp.SFtpTaskOption; import com.arialyy.aria.sftp.SFtpTaskOption;

Loading…
Cancel
Save