任务组实现

pull/330/head
AriaLyy 8 years ago
parent 380b05de43
commit 8cf4c36d71
  1. 4
      Aria/src/main/java/com/arialyy/aria/core/command/normal/AddCmd.java
  2. 4
      Aria/src/main/java/com/arialyy/aria/core/command/normal/CancelCmd.java
  3. 4
      Aria/src/main/java/com/arialyy/aria/core/command/normal/HighestPriorityCmd.java
  4. 8
      Aria/src/main/java/com/arialyy/aria/core/command/normal/ResumeAllCmd.java
  5. 4
      Aria/src/main/java/com/arialyy/aria/core/command/normal/StartCmd.java
  6. 4
      Aria/src/main/java/com/arialyy/aria/core/command/normal/StopCmd.java
  7. 65
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupEntity.java
  8. 24
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupListener.java
  9. 269
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTask.java
  10. 28
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadGroupTaskEntity.java
  11. 30
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadTask.java
  12. 13
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskEntity.java
  13. 8
      Aria/src/main/java/com/arialyy/aria/core/download/DownloadTaskGroup.java
  14. 24
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/ChildThreadConfigEntity.java
  15. 3
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/ConnectionHelp.java
  16. 240
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadGroupUtil.java
  17. 5
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadListener.java
  18. 2
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadStateConstance.java
  19. 346
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadThreader.java
  20. 58
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/DownloadUtil.java
  21. 161
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FileInfoThread.java
  22. 2
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/IDownloadListener.java
  23. 22
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/IDownloadUtil.java
  24. 6
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/SingleThreadTask.java
  25. 136
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsEntity.java
  26. 106
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsGroupEntity.java
  27. 71
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsGroupTask.java
  28. 104
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalEntity.java
  29. 100
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsNormalTask.java
  30. 89
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsTask.java
  31. 24
      Aria/src/main/java/com/arialyy/aria/core/inf/AbsTaskEntity.java
  32. 22
      Aria/src/main/java/com/arialyy/aria/core/inf/ITask.java
  33. 16
      Aria/src/main/java/com/arialyy/aria/core/queue/AbsTaskQueue.java
  34. 4
      Aria/src/main/java/com/arialyy/aria/core/queue/DownloadTaskQueue.java
  35. 5
      Aria/src/main/java/com/arialyy/aria/core/queue/ITaskQueue.java
  36. 4
      Aria/src/main/java/com/arialyy/aria/core/queue/UploadTaskQueue.java
  37. 23
      Aria/src/main/java/com/arialyy/aria/core/queue/pool/GroupCachePool.java
  38. 23
      Aria/src/main/java/com/arialyy/aria/core/queue/pool/GroupExecutePool.java
  39. 6
      Aria/src/main/java/com/arialyy/aria/core/queue/pool/NormalCachePool.java
  40. 6
      Aria/src/main/java/com/arialyy/aria/core/queue/pool/NormalExecutePool.java
  41. 4
      Aria/src/main/java/com/arialyy/aria/core/scheduler/AbsSchedulers.java
  42. 5
      aria/src/main/java/com/arialyy/aria/core/upload/UploadTask.java

@ -17,7 +17,7 @@
package com.arialyy.aria.core.command.normal; package com.arialyy.aria.core.command.normal;
import android.util.Log; import android.util.Log;
import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.AbsNormalTask;
import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.AbsTaskEntity;
@ -33,7 +33,7 @@ class AddCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T> {
@Override public void executeCmd() { @Override public void executeCmd() {
if (!canExeCmd) return; if (!canExeCmd) return;
AbsTask task = mQueue.getTask(mTaskEntity.getEntity()); AbsNormalTask task = mQueue.getTask(mTaskEntity.getEntity());
if (task == null) { if (task == null) {
mTaskEntity.getEntity().setState(IEntity.STATE_WAIT); mTaskEntity.getEntity().setState(IEntity.STATE_WAIT);
mQueue.createTask(mTargetName, mTaskEntity); mQueue.createTask(mTargetName, mTaskEntity);

@ -17,7 +17,7 @@
package com.arialyy.aria.core.command.normal; package com.arialyy.aria.core.command.normal;
import android.text.TextUtils; import android.text.TextUtils;
import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.AbsNormalTask;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.AbsTaskEntity;
/** /**
@ -31,7 +31,7 @@ class CancelCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T> {
@Override public void executeCmd() { @Override public void executeCmd() {
if (!canExeCmd) return; if (!canExeCmd) return;
AbsTask task = mQueue.getTask(mTaskEntity.getEntity()); AbsNormalTask task = mQueue.getTask(mTaskEntity.getEntity());
if (task == null) { if (task == null) {
task = mQueue.createTask(mTargetName, mTaskEntity); task = mQueue.createTask(mTargetName, mTaskEntity);
} }

@ -16,7 +16,7 @@
package com.arialyy.aria.core.command.normal; package com.arialyy.aria.core.command.normal;
import android.text.TextUtils; import android.text.TextUtils;
import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.AbsNormalTask;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.AbsTaskEntity;
/** /**
@ -39,7 +39,7 @@ final class HighestPriorityCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T>
@Override public void executeCmd() { @Override public void executeCmd() {
if (!canExeCmd) return; if (!canExeCmd) return;
AbsTask task = mQueue.getTask(mTaskEntity.getEntity()); AbsNormalTask task = mQueue.getTask(mTaskEntity.getEntity());
if (task == null) { if (task == null) {
task = mQueue.createTask(mTargetName, mTaskEntity); task = mQueue.createTask(mTargetName, mTaskEntity);
} }

@ -3,7 +3,7 @@ package com.arialyy.aria.core.command.normal;
import android.util.Log; import android.util.Log;
import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.AbsNormalTask;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.orm.DbEntity;
@ -29,7 +29,7 @@ final class ResumeAllCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T> {
for (DownloadEntity entity : allEntity) { for (DownloadEntity entity : allEntity) {
int exeNum = mQueue.getExePoolSize(); int exeNum = mQueue.getExePoolSize();
if (exeNum == 0 || exeNum < mQueue.getMaxTaskNum()) { if (exeNum == 0 || exeNum < mQueue.getMaxTaskNum()) {
AbsTask task = createTask(entity); AbsNormalTask task = createTask(entity);
mQueue.startTask(task); mQueue.startTask(task);
} else { } else {
entity.setState(IEntity.STATE_WAIT); entity.setState(IEntity.STATE_WAIT);
@ -38,8 +38,8 @@ final class ResumeAllCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T> {
} }
} }
private AbsTask createTask(DownloadEntity entity) { private AbsNormalTask createTask(DownloadEntity entity) {
AbsTask task = mQueue.getTask(entity); AbsNormalTask task = mQueue.getTask(entity);
if (task == null) { if (task == null) {
DownloadTaskEntity taskEntity = new DownloadTaskEntity(entity); DownloadTaskEntity taskEntity = new DownloadTaskEntity(entity);
task = mQueue.createTask(mTargetName, taskEntity); task = mQueue.createTask(mTargetName, taskEntity);

@ -19,7 +19,7 @@ package com.arialyy.aria.core.command.normal;
import android.text.TextUtils; import android.text.TextUtils;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.QueueMod; import com.arialyy.aria.core.QueueMod;
import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.AbsNormalTask;
import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.AbsTaskEntity;
@ -47,7 +47,7 @@ class StartCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T> {
maxTaskNum = manager.getUploadConfig().getMaxTaskNum(); maxTaskNum = manager.getUploadConfig().getMaxTaskNum();
} }
AbsTask task = mQueue.getTask(mTaskEntity.getEntity()); AbsNormalTask task = mQueue.getTask(mTaskEntity.getEntity());
if (task == null) { if (task == null) {
task = mQueue.createTask(mTargetName, mTaskEntity); task = mQueue.createTask(mTargetName, mTaskEntity);
if (!TextUtils.isEmpty(mTargetName)) { if (!TextUtils.isEmpty(mTargetName)) {

@ -18,7 +18,7 @@ package com.arialyy.aria.core.command.normal;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.AbsNormalTask;
import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.AbsTaskEntity;
@ -34,7 +34,7 @@ class StopCmd<T extends AbsTaskEntity> extends AbsNormalCmd<T> {
@Override public void executeCmd() { @Override public void executeCmd() {
if (!canExeCmd) return; if (!canExeCmd) return;
AbsTask task = mQueue.getTask(mTaskEntity.getEntity()); AbsNormalTask task = mQueue.getTask(mTaskEntity.getEntity());
if (task == null) { if (task == null) {
if (mTaskEntity.getEntity().getState() == IEntity.STATE_RUNNING) { if (mTaskEntity.getEntity().getState() == IEntity.STATE_RUNNING) {
task = mQueue.createTask(mTargetName, mTaskEntity); task = mQueue.createTask(mTargetName, mTaskEntity);

@ -0,0 +1,65 @@
/*
* 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;
import android.os.Parcel;
import com.arialyy.aria.core.inf.AbsGroupEntity;
import java.util.LinkedList;
import java.util.List;
/**
* Created by AriaL on 2017/6/29.
* 下载任务组实体
*/
public class DownloadGroupEntity extends AbsGroupEntity {
private List<DownloadEntity> mChild = new LinkedList<>();
public List<DownloadEntity> getChild() {
return mChild;
}
public void setChild(List<DownloadEntity> child) {
this.mChild = child;
}
@Override public int describeContents() {
return 0;
}
@Override public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeTypedList(this.mChild);
}
public DownloadGroupEntity() {
}
protected DownloadGroupEntity(Parcel in) {
super(in);
this.mChild = in.createTypedArrayList(DownloadEntity.CREATOR);
}
public static final Creator<DownloadGroupEntity> CREATOR = new Creator<DownloadGroupEntity>() {
@Override public DownloadGroupEntity createFromParcel(Parcel source) {
return new DownloadGroupEntity(source);
}
@Override public DownloadGroupEntity[] newArray(int size) {
return new DownloadGroupEntity[size];
}
};
}

@ -0,0 +1,24 @@
/*
* 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;
/**
* Created by AriaL on 2017/6/30.
*/
public class DownloadGroupListener {
}

@ -0,0 +1,269 @@
///*
// * 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;
//
//import android.content.Context;
//import android.os.Handler;
//import android.util.SparseArray;
//import com.arialyy.aria.core.Aria;
//import com.arialyy.aria.core.AriaManager;
//import com.arialyy.aria.core.download.downloader.DownloadListener;
//import com.arialyy.aria.core.download.downloader.DownloadUtil;
//import com.arialyy.aria.core.inf.AbsGroupTask;
//import com.arialyy.aria.core.inf.IEntity;
//import com.arialyy.aria.core.scheduler.DownloadSchedulers;
//import com.arialyy.aria.core.scheduler.ISchedulers;
//import com.arialyy.aria.util.CheckUtil;
//import com.arialyy.aria.util.CommonUtil;
//import java.lang.ref.WeakReference;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//import java.util.concurrent.ExecutorService;
//import java.util.concurrent.Executors;
//
///**
// * Created by AriaL on 2017/6/27.
// * 任务组任务
// */
//public class DownloadGroupTask extends AbsGroupTask<DownloadTaskEntity, DownloadGroupEntity> {
// DListener mListener;
// SparseArray<DownloadUtil> mUtils = new SparseArray<>();
// boolean isStop = false;
//
// private ExecutorService mFixedThreadPool;
//
// private DownloadGroupTask(DownloadTaskEntity taskEntity, Handler outHandler) {
// mTaskEntity = taskEntity;
// mEntity = taskEntity.groupEntity;
// mOutHandler = outHandler;
// mContext = AriaManager.APP;
// mListener = new DListener(mContext, this, mOutHandler);
// mFixedThreadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
// }
//
// @Override public void start() {
// List<DownloadEntity> childs = mEntity.getChild();
// int i = 1;
// mListener.sendInState2Target(ISchedulers.PRE);
// for (DownloadEntity entity : childs) {
// DownloadUtil util = createChildDownload(entity);
// if (isStop) break;
// mUtils.append(i, util);
// mFixedThreadPool.execute(util);
// i++;
// }
// }
//
// /**
// * 创建任务组单个任务下载工具
// */
// private DownloadUtil createChildDownload(DownloadEntity entity) {
// DownloadTaskEntity taskEntity = new DownloadTaskEntity(entity);
// taskEntity.headers = mTaskEntity.headers;
// taskEntity.requestEnum = mTaskEntity.requestEnum;
// taskEntity.redirectUrlKey = mTaskEntity.redirectUrlKey;
// taskEntity.removeFile = mTaskEntity.removeFile;
// return new DownloadUtil(mContext, taskEntity, mListener);
// }
//
// @Override public void stop() {
// isStop = true;
// if (mFixedThreadPool != null) {
// mFixedThreadPool.shutdown();
// }
// for (int i = 1, len = mUtils.size(); i <= len; i++) {
// DownloadUtil util = mUtils.get(i);
// if (util != null && util.isDownloading()) {
// util.stopDownload();
// }
// }
// }
//
// @Override public void cancel() {
// isStop = true;
// if (mFixedThreadPool != null) {
// mFixedThreadPool.shutdown();
// }
// for (int i = 1, len = mUtils.size(); i <= len; i++) {
// DownloadUtil util = mUtils.get(i);
// if (util != null) {
// util.cancelDownload();
// }
// }
// }
//
// /**
// * 下载监听类
// */
// private static class DListener extends DownloadListener {
// WeakReference<Handler> outHandler;
// WeakReference<DownloadGroupTask> wTask;
// Context context;
// long lastLen = 0; //上一次发送长度
// long lastTime = 0;
// long INTERVAL_TIME = 1000; //1m更新周期
// boolean isFirst = true;
// DownloadGroupEntity groupEntity;
// DownloadGroupTask task;
// boolean isConvertSpeed = false;
// Map<String, DownloadEntity> mEntityMap = new HashMap<>();
//
// DListener(Context context, DownloadGroupTask task, Handler outHandler) {
// this.context = context;
// this.outHandler = new WeakReference<>(outHandler);
// this.wTask = new WeakReference<>(task);
// this.task = wTask.get();
// this.groupEntity = this.task.getEntity();
// final AriaManager manager = AriaManager.getInstance(context);
// isConvertSpeed = manager.getDownloadConfig().isConvertSpeed();
// for (DownloadEntity entity : groupEntity.getChild()) {
// mEntityMap.put(entity.getDownloadUrl(), entity);
// }
// }
//
// @Override public void onPre(String url) {
// saveData(url, IEntity.STATE_PRE, -1);
// }
//
// @Override public void onPostPre(String url, long fileSize) {
// DownloadEntity entity = mEntityMap.get(url);
// if (entity != null){
// entity.setFileSize(fileSize);
// }
// saveData(url, IEntity.STATE_POST_PRE, -1);
// }
//
// @Override public void onStart(String url, long startLocation) {
// downloadEntity.setState(IEntity.STATE_RUNNING);
// sendInState2Target(ISchedulers.START);
// sendIntent(Aria.ACTION_START, startLocation);
// }
//
// @Override public void onResume(String url, long resumeLocation) {
// downloadEntity.setState(IEntity.STATE_RUNNING);
// sendInState2Target(ISchedulers.RESUME);
// sendIntent(Aria.ACTION_RESUME, resumeLocation);
// }
//
// @Override public void onProgress(String url, long currentLocation) {
// if (System.currentTimeMillis() - lastTime > INTERVAL_TIME) {
// long speed = currentLocation - lastLen;
// sendIntent.putExtra(Aria.CURRENT_LOCATION, currentLocation);
// sendIntent.putExtra(Aria.CURRENT_SPEED, speed);
// lastTime = System.currentTimeMillis();
// if (isFirst) {
// speed = 0;
// isFirst = false;
// }
// handleSpeed(speed);
// downloadEntity.setCurrentProgress(currentLocation);
// lastLen = currentLocation;
// sendInState2Target(ISchedulers.RUNNING);
// context.sendBroadcast(sendIntent);
// }
// }
//
// @Override public void onStop(String url, long stopLocation) {
// downloadEntity.setState(task.isWait ? IEntity.STATE_WAIT : IEntity.STATE_STOP);
// handleSpeed(0);
// sendInState2Target(ISchedulers.STOP);
// sendIntent(Aria.ACTION_STOP, stopLocation);
// }
//
// @Override public void onCancel(String url) {
// downloadEntity.setState(IEntity.STATE_CANCEL);
// handleSpeed(0);
// sendInState2Target(ISchedulers.CANCEL);
// sendIntent(Aria.ACTION_CANCEL, -1);
// downloadEntity.deleteData();
// }
//
// @Override public void onComplete(String url) {
// downloadEntity.setState(IEntity.STATE_COMPLETE);
// downloadEntity.setDownloadComplete(true);
// handleSpeed(0);
// sendInState2Target(ISchedulers.COMPLETE);
// sendIntent(Aria.ACTION_COMPLETE, downloadEntity.getFileSize());
// }
//
// @Override public void onFail(String url) {
// downloadEntity.setFailNum(downloadEntity.getFailNum() + 1);
// downloadEntity.setState(IEntity.STATE_FAIL);
// handleSpeed(0);
// sendInState2Target(ISchedulers.FAIL);
// sendIntent(Aria.ACTION_FAIL, -1);
// }
//
// private void handleSpeed(long speed) {
// if (isConvertSpeed) {
// downloadEntity.setConvertSpeed(CommonUtil.formatFileSize(speed) + "/s");
// } else {
// downloadEntity.setSpeed(speed);
// }
// }
//
// /**
// * 将任务状态发送给下载器
// *
// * @param state {@link DownloadSchedulers#START}
// */
// private void sendInState2Target(int state) {
// if (outHandler.get() != null) {
// outHandler.get().obtainMessage(state, task).sendToTarget();
// }
// }
//
// private void saveData(String url, int state, long location) {
// DownloadEntity child = mEntityMap.get(url);
// if (child != null) {
// child.setState(state);
// child.setDownloadComplete(state == IEntity.STATE_COMPLETE);
// child.setCurrentProgress(location);
// child.update();
// }
// }
// }
//
// public static class Builder {
// DownloadTaskEntity taskEntity;
// Handler outHandler;
// String targetName;
//
// public Builder(String targetName, DownloadTaskEntity taskEntity) {
// CheckUtil.checkTaskEntity(taskEntity);
// this.targetName = targetName;
// this.taskEntity = taskEntity;
// }
//
// /**
// * 设置自定义Handler处理下载状态时间
// *
// * @param schedulers {@link ISchedulers}
// */
// public DownloadGroupTask.Builder setOutHandler(ISchedulers schedulers) {
// this.outHandler = new Handler(schedulers);
// return this;
// }
//
// public DownloadGroupTask build() {
// DownloadGroupTask task = new DownloadGroupTask(taskEntity, outHandler);
// task.setTargetName(targetName);
// taskEntity.downloadEntity.save();
// return task;
// }
// }
//}

@ -0,0 +1,28 @@
/*
* 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;
import com.arialyy.aria.core.inf.AbsTaskEntity;
/**
* Created by AriaL on 2017/7/1.
*/
public class DownloadGroupTaskEntity extends AbsTaskEntity<DownloadGroupEntity> {
public DownloadGroupTaskEntity(DownloadGroupEntity entity) {
this.entity = entity;
}
}

@ -22,7 +22,10 @@ import android.os.Handler;
import android.util.Log; import android.util.Log;
import com.arialyy.aria.core.Aria; import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.download.downloader.DownloadListener;
import com.arialyy.aria.core.download.downloader.DownloadUtil;
import com.arialyy.aria.core.download.downloader.IDownloadListener;
import com.arialyy.aria.core.inf.AbsNormalTask;
import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.scheduler.DownloadSchedulers; import com.arialyy.aria.core.scheduler.DownloadSchedulers;
import com.arialyy.aria.core.scheduler.ISchedulers; import com.arialyy.aria.core.scheduler.ISchedulers;
@ -35,12 +38,11 @@ import java.lang.ref.WeakReference;
* Created by lyy on 2016/8/11. * Created by lyy on 2016/8/11.
* 下载任务类 * 下载任务类
*/ */
public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> { public class DownloadTask extends AbsNormalTask<DownloadEntity> {
public static final String TAG = "DownloadTask"; public static final String TAG = "DownloadTask";
private IDownloadListener mListener; private IDownloadListener mListener;
private Handler mOutHandler; private DownloadUtil mUtil;
private IDownloadUtil mUtil;
private boolean isWait = false; private boolean isWait = false;
private DownloadTask(DownloadTaskEntity taskEntity, Handler outHandler) { private DownloadTask(DownloadTaskEntity taskEntity, Handler outHandler) {
@ -98,7 +100,6 @@ public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> {
* 暂停任务并让任务处于等待状态 * 暂停任务并让任务处于等待状态
*/ */
@Override public void stopAndWait() { @Override public void stopAndWait() {
super.stopAndWait();
stop(true); stop(true);
} }
@ -166,9 +167,6 @@ public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> {
mContext.sendBroadcast(intent); mContext.sendBroadcast(intent);
} }
mUtil.cancelDownload(); mUtil.cancelDownload();
mUtil.delConfigFile();
mUtil.delTempFile();
mEntity.deleteData();
} }
} }
@ -232,7 +230,6 @@ public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> {
} }
@Override public void supportBreakpoint(boolean support) { @Override public void supportBreakpoint(boolean support) {
super.supportBreakpoint(support);
if (!support) { if (!support) {
sendInState2Target(ISchedulers.SUPPORT_BREAK_POINT); sendInState2Target(ISchedulers.SUPPORT_BREAK_POINT);
sendIntent(Aria.ACTION_SUPPORT_BREAK_POINT, -1); sendIntent(Aria.ACTION_SUPPORT_BREAK_POINT, -1);
@ -240,14 +237,12 @@ public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> {
} }
@Override public void onPre() { @Override public void onPre() {
super.onPre();
downloadEntity.setState(IEntity.STATE_PRE); downloadEntity.setState(IEntity.STATE_PRE);
sendInState2Target(ISchedulers.PRE); sendInState2Target(ISchedulers.PRE);
sendIntent(Aria.ACTION_PRE, -1); sendIntent(Aria.ACTION_PRE, -1);
} }
@Override public void onPostPre(long fileSize) { @Override public void onPostPre(long fileSize) {
super.onPostPre(fileSize);
downloadEntity.setFileSize(fileSize); downloadEntity.setFileSize(fileSize);
downloadEntity.setState(IEntity.STATE_POST_PRE); downloadEntity.setState(IEntity.STATE_POST_PRE);
sendInState2Target(ISchedulers.POST_PRE); sendInState2Target(ISchedulers.POST_PRE);
@ -255,25 +250,20 @@ public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> {
} }
@Override public void onResume(long resumeLocation) { @Override public void onResume(long resumeLocation) {
super.onResume(resumeLocation);
downloadEntity.setState(IEntity.STATE_RUNNING); downloadEntity.setState(IEntity.STATE_RUNNING);
sendInState2Target(ISchedulers.RESUME); sendInState2Target(ISchedulers.RESUME);
sendIntent(Aria.ACTION_RESUME, resumeLocation); sendIntent(Aria.ACTION_RESUME, resumeLocation);
} }
@Override public void onStart(long startLocation) { @Override public void onStart(long startLocation) {
super.onStart(startLocation);
downloadEntity.setState(IEntity.STATE_RUNNING); downloadEntity.setState(IEntity.STATE_RUNNING);
sendInState2Target(ISchedulers.START); sendInState2Target(ISchedulers.START);
sendIntent(Aria.ACTION_START, startLocation); sendIntent(Aria.ACTION_START, startLocation);
} }
@Override public void onProgress(long currentLocation) { @Override public void onProgress(long currentLocation) {
super.onProgress(currentLocation);
if (System.currentTimeMillis() - lastTime > INTERVAL_TIME) { if (System.currentTimeMillis() - lastTime > INTERVAL_TIME) {
long speed = currentLocation - lastLen; long speed = currentLocation - lastLen;
sendIntent.putExtra(Aria.CURRENT_LOCATION, currentLocation);
sendIntent.putExtra(Aria.CURRENT_SPEED, speed);
lastTime = System.currentTimeMillis(); lastTime = System.currentTimeMillis();
if (isFirst) { if (isFirst) {
speed = 0; speed = 0;
@ -283,12 +273,15 @@ public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> {
downloadEntity.setCurrentProgress(currentLocation); downloadEntity.setCurrentProgress(currentLocation);
lastLen = currentLocation; lastLen = currentLocation;
sendInState2Target(ISchedulers.RUNNING); sendInState2Target(ISchedulers.RUNNING);
if (!isOpenBroadCast) return;
sendIntent.putExtra(Aria.CURRENT_LOCATION, currentLocation);
sendIntent.putExtra(Aria.CURRENT_SPEED, speed);
context.sendBroadcast(sendIntent); context.sendBroadcast(sendIntent);
} }
} }
@Override public void onStop(long stopLocation) { @Override public void onStop(long stopLocation) {
super.onStop(stopLocation);
downloadEntity.setState(task.isWait ? IEntity.STATE_WAIT : IEntity.STATE_STOP); downloadEntity.setState(task.isWait ? IEntity.STATE_WAIT : IEntity.STATE_STOP);
handleSpeed(0); handleSpeed(0);
sendInState2Target(ISchedulers.STOP); sendInState2Target(ISchedulers.STOP);
@ -296,7 +289,6 @@ public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> {
} }
@Override public void onCancel() { @Override public void onCancel() {
super.onCancel();
downloadEntity.setState(IEntity.STATE_CANCEL); downloadEntity.setState(IEntity.STATE_CANCEL);
handleSpeed(0); handleSpeed(0);
sendInState2Target(ISchedulers.CANCEL); sendInState2Target(ISchedulers.CANCEL);
@ -305,7 +297,6 @@ public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> {
} }
@Override public void onComplete() { @Override public void onComplete() {
super.onComplete();
downloadEntity.setState(IEntity.STATE_COMPLETE); downloadEntity.setState(IEntity.STATE_COMPLETE);
downloadEntity.setDownloadComplete(true); downloadEntity.setDownloadComplete(true);
handleSpeed(0); handleSpeed(0);
@ -314,7 +305,6 @@ public class DownloadTask extends AbsTask<DownloadTaskEntity, DownloadEntity> {
} }
@Override public void onFail() { @Override public void onFail() {
super.onFail();
downloadEntity.setFailNum(downloadEntity.getFailNum() + 1); downloadEntity.setFailNum(downloadEntity.getFailNum() + 1);
downloadEntity.setState(IEntity.STATE_FAIL); downloadEntity.setState(IEntity.STATE_FAIL);
handleSpeed(0); handleSpeed(0);

@ -21,17 +21,12 @@ import com.arialyy.aria.core.inf.AbsTaskEntity;
* Created by lyy on 2017/1/23. * Created by lyy on 2017/1/23.
* 下载任务实体 * 下载任务实体
*/ */
public class DownloadTaskEntity extends AbsTaskEntity { public class DownloadTaskEntity extends AbsTaskEntity<DownloadEntity> {
public DownloadEntity downloadEntity; public DownloadTaskEntity() {
public DownloadTaskEntity(){}
public DownloadTaskEntity(DownloadEntity downloadEntity) {
this.downloadEntity = downloadEntity;
} }
@Override public DownloadEntity getEntity() { public DownloadTaskEntity(DownloadEntity entity) {
return downloadEntity; this.entity = entity;
} }
} }

@ -1,8 +0,0 @@
package com.arialyy.aria.core.download;
/**
* Created by AriaL on 2017/6/27.
*/
public class DownloadTaskGroup {
}

@ -0,0 +1,24 @@
package com.arialyy.aria.core.download.downloader;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import java.io.File;
/**
* 子线程下载信息类
*/
final class ChildThreadConfigEntity {
//线程Id
int THREAD_ID;
//下载文件大小
long FILE_SIZE;
//子线程启动下载位置
long START_LOCATION;
//子线程结束下载位置
long END_LOCATION;
//下载路径
File TEMP_FILE;
String DOWNLOAD_URL;
String CONFIG_FILE_PATH;
DownloadTaskEntity DOWNLOAD_TASK_ENTITY;
boolean IS_SUPPORT_BREAK_POINT = true;
}

@ -13,8 +13,9 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.arialyy.aria.core.download; package com.arialyy.aria.core.download.downloader;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.util.SSLContextUtil; import com.arialyy.aria.util.SSLContextUtil;
import java.io.IOException; import java.io.IOException;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;

@ -0,0 +1,240 @@
/*
* 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.downloader;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupTaskEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.orm.DbEntity;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by AriaL on 2017/6/30.
* 下载组工具
*/
public class DownloadGroupUtil implements IDownloadUtil {
private static final String TAG = "DownloadGroupUtil";
/**
* 任务组所有任务总大小
*/
private long mTotalSize = 0;
private long mCurrentProgress = 0;
private ExecutorService mInfoPool;
private ExecutorService mExePool;
private IDownloadListener mListener;
private DownloadGroupTaskEntity mTaskEntity;
private boolean isRunning = true;
/**
* 保存所有没有下载完成的任务key为下载地址
*/
private Map<String, DownloadTaskEntity> mExeMap = new HashMap<>();
/**
* 下载失败的映射表key为下载地址
*/
private Map<String, DownloadTaskEntity> mFailMap = new HashMap<>();
/**
* 下载器映射表key为下载地址
*/
private Map<String, DownloadThreader> mDownloaderMap = new HashMap<>();
DownloadGroupUtil(IDownloadListener listener, DownloadGroupTaskEntity taskEntity) {
mListener = listener;
mTaskEntity = taskEntity;
mInfoPool = Executors.newCachedThreadPool();
for (DownloadEntity entity : mTaskEntity.entity.getChild()) {
File file = new File(entity.getDownloadPath());
if (entity.isDownloadComplete() && file.exists()) {
mTotalSize += entity.getFileSize();
} else {
mExeMap.put(entity.getDownloadUrl(), createDownloadTask(entity));
}
mCurrentProgress += entity.getCurrentProgress();
}
}
@Override public long getFileSize() {
return mTotalSize;
}
@Override public long getCurrentLocation() {
return mCurrentProgress;
}
@Override public boolean isDownloading() {
return isRunning;
}
@Override public void cancelDownload() {
isRunning = false;
if (!mInfoPool.isShutdown()) {
mInfoPool.shutdown();
}
Set<String> keys = mDownloaderMap.keySet();
for (String key : keys) {
DownloadThreader db = mDownloaderMap.get(key);
if (db != null) {
db.cancelDownload();
}
}
}
@Override public void stopDownload() {
isRunning = false;
if (!mInfoPool.isShutdown()) {
mInfoPool.shutdown();
}
Set<String> keys = mDownloaderMap.keySet();
for (String key : keys) {
DownloadThreader db = mDownloaderMap.get(key);
if (db != null) {
db.stopDownload();
}
}
}
@Override public void startDownload() {
isRunning = true;
Set<String> keys = mExeMap.keySet();
for (String key : keys) {
DownloadTaskEntity taskEntity = mExeMap.get(key);
mInfoPool.execute(new FileInfoThread(taskEntity, new FileInfoThread.OnFileInfoCallback() {
@Override public void onComplete(String url, int code) {
DownloadTaskEntity te = mExeMap.get(url);
if (te != null) {
mTotalSize += te.getEntity().getFileSize();
startChildDownload(te);
}
}
@Override public void onFail(String url, String errorMsg) {
mFailMap.put(url, mExeMap.get(url));
}
}));
}
mListener.onPostPre(mTotalSize);
}
@Override public void resumeDownload() {
startDownload();
}
/**
* 启动子任务下载器
*/
private void startChildDownload(DownloadTaskEntity taskEntity) {
ChildDownloadListener listener = new ChildDownloadListener(taskEntity);
DownloadThreader dt = new DownloadThreader(listener, taskEntity);
mDownloaderMap.put(taskEntity.getEntity().getDownloadUrl(), dt);
mExePool.execute(dt);
}
/**
* 创建子任务下载信息
*/
private DownloadTaskEntity createDownloadTask(DownloadEntity entity) {
DownloadTaskEntity taskEntity =
DbEntity.findData(DownloadTaskEntity.class, "key=?", entity.getDownloadUrl());
if (taskEntity != null) {
return taskEntity;
}
taskEntity = new DownloadTaskEntity(entity);
taskEntity.headers = mTaskEntity.headers;
taskEntity.requestEnum = mTaskEntity.requestEnum;
taskEntity.redirectUrlKey = mTaskEntity.redirectUrlKey;
taskEntity.removeFile = mTaskEntity.removeFile;
return taskEntity;
}
/**
* 子任务事件监听
*/
private class ChildDownloadListener extends DownloadListener {
DownloadTaskEntity taskEntity;
DownloadEntity entity;
long lastLen = 0; //上一次发送长度
long lastTime = 0;
long INTERVAL_TIME = 1000; //1m更新周期
ChildDownloadListener(DownloadTaskEntity entity) {
this.taskEntity = entity;
this.entity = taskEntity.getEntity();
}
@Override public void onPre() {
saveData(IEntity.STATE_PRE, -1);
}
@Override public void onPostPre(long fileSize) {
entity.setFileSize(fileSize);
saveData(IEntity.STATE_POST_PRE, -1);
}
@Override public void onResume(long resumeLocation) {
saveData(IEntity.STATE_POST_PRE, IEntity.STATE_RUNNING);
}
@Override public void onStart(long startLocation) {
saveData(IEntity.STATE_POST_PRE, IEntity.STATE_RUNNING);
}
@Override public void onProgress(long currentLocation) {
if (System.currentTimeMillis() - lastTime > INTERVAL_TIME) {
long speed = currentLocation - lastLen;
lastTime = System.currentTimeMillis();
handleSpeed(speed);
entity.setCurrentProgress(currentLocation);
lastLen = currentLocation;
}
}
@Override public void onStop(long stopLocation) {
saveData(IEntity.STATE_STOP, stopLocation);
}
@Override public void onCancel() {
saveData(IEntity.STATE_CANCEL, -1);
}
@Override public void onComplete() {
saveData(IEntity.STATE_COMPLETE, entity.getFileSize());
}
@Override public void onFail() {
entity.setFailNum(entity.getFailNum() + 1);
saveData(IEntity.STATE_FAIL, -1);
}
private void saveData(int state, long location) {
entity.setState(state);
entity.setDownloadComplete(state == IEntity.STATE_COMPLETE);
entity.setCurrentProgress(location);
entity.update();
}
}
}

@ -14,12 +14,13 @@
* limitations under the License. * limitations under the License.
*/ */
package com.arialyy.aria.core.download; package com.arialyy.aria.core.download.downloader;
/** /**
* @author lyy * @author lyy
*/ */
class DownloadListener implements IDownloadListener { public class DownloadListener implements IDownloadListener {
@Override public void onResume(long resumeLocation) { @Override public void onResume(long resumeLocation) {

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.arialyy.aria.core.download; package com.arialyy.aria.core.download.downloader;
/** /**
* Created by lyy on 2017/1/18. * Created by lyy on 2017/1/18.

@ -0,0 +1,346 @@
/*
* 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.downloader;
import android.content.Context;
import android.util.Log;
import android.util.SparseArray;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.util.BufferedRandomAccessFile;
import com.arialyy.aria.util.CommonUtil;
import java.io.File;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by AriaL on 2017/7/1.
*/
class DownloadThreader implements Runnable, IDownloadUtil {
private final String TAG = "DownloadThreader";
private IDownloadListener mListener;
private DownloadTaskEntity mTaskEntity;
private DownloadEntity mEntity;
private ExecutorService mFixedThreadPool;
private File mConfigFile;//下载信息配置文件
private Context mContext;
private File mTempFile; //下载的文件
private boolean isNewTask = true;
private int mThreadNum, mRealThreadNum;
private DownloadStateConstance mConstance;
private SparseArray<Runnable> mTask = new SparseArray<>();
DownloadThreader(IDownloadListener listener, DownloadTaskEntity taskEntity) {
mListener = listener;
mTaskEntity = taskEntity;
mEntity = mTaskEntity.getEntity();
mContext = AriaManager.APP;
mConstance = new DownloadStateConstance();
}
@Override public void run() {
checkTask();
startDownload();
}
@Override public long getFileSize() {
return mEntity.getFileSize();
}
/**
* 获取当前下载位置
*/
@Override public long getCurrentLocation() {
return mConstance.CURRENT_LOCATION;
}
@Override public boolean isDownloading() {
return mConstance.isDownloading;
}
@Override public void cancelDownload() {
mConstance.isCancel = true;
mConstance.isDownloading = false;
if (mFixedThreadPool != null) {
mFixedThreadPool.shutdown();
}
for (int i = 0; i < mThreadNum; i++) {
SingleThreadTask task = (SingleThreadTask) mTask.get(i);
if (task != null) {
task.cancel();
}
}
CommonUtil.delDownloadTaskConfig(mTaskEntity.removeFile, mEntity);
}
@Override public void stopDownload() {
mConstance.isStop = true;
mConstance.isDownloading = false;
if (mFixedThreadPool != null) {
mFixedThreadPool.shutdown();
}
for (int i = 0; i < mThreadNum; i++) {
SingleThreadTask task = (SingleThreadTask) mTask.get(i);
if (task != null) {
task.stop();
}
}
}
@Override public void startDownload() {
mConstance.isDownloading = true;
try {
if (!mTaskEntity.isSupportBP) {
mThreadNum = 1;
handleNoSupportBreakpointDownload();
} else {
mThreadNum =
isNewTask ? AriaManager.getInstance(mContext).getDownloadConfig().getThreadNum()
: mRealThreadNum;
mFixedThreadPool = Executors.newFixedThreadPool(mThreadNum);
handleBreakpoint();
}
} catch (IOException e) {
failDownload("下载失败【downloadUrl:"
+ mEntity.getDownloadUrl()
+ "】\n【filePath:"
+ mEntity.getDownloadPath()
+ "】\n"
+ CommonUtil.getPrintException(e));
}
}
@Override public void resumeDownload() {
startDownload();
}
/**
* 返回该下载器的
*/
public IDownloadListener getListener() {
return mListener;
}
/**
* 检查任务是否是新任务新任务条件
* 1文件不存在
* 2下载记录文件不存在
* 3下载记录文件缺失或不匹配
* 4数据库记录不存在
* 5不支持断点则是新任务
*/
private void checkTask() {
if (!mTaskEntity.isSupportBP) {
isNewTask = true;
return;
}
mConfigFile = new File(mContext.getFilesDir().getPath()
+ AriaManager.DOWNLOAD_TEMP_DIR
+ mEntity.getFileName()
+ ".properties");
mTempFile = new File(mEntity.getDownloadPath());
if (!mConfigFile.exists()) { //记录文件被删除,则重新下载
isNewTask = true;
CommonUtil.createFile(mConfigFile.getPath());
} else if (!mTempFile.exists()) {
isNewTask = true;
} else if (DbEntity.findData(DownloadEntity.class, "downloadUrl=?", mEntity.getDownloadUrl())
== null) {
isNewTask = true;
} else {
isNewTask = checkConfigFile();
}
}
/**
* 检查记录文件如果是新任务返回{@code true}否则返回{@code false}
*/
private boolean checkConfigFile() {
Properties pro = CommonUtil.loadConfig(mConfigFile);
if (pro.isEmpty()) {
return true;
}
Set<Object> keys = pro.keySet();
int num = 0;
for (Object key : keys) {
if (String.valueOf(key).contains("_record_")) {
num++;
}
}
if (num == 0) {
return true;
}
mRealThreadNum = num;
for (int i = 0; i < mRealThreadNum; i++) {
if (pro.getProperty(mTempFile.getName() + "_record_" + i) == null) {
Object state = pro.getProperty(mTempFile.getName() + "_state_" + i);
if (state != null && Integer.parseInt(state + "") == 1) {
continue;
}
return true;
}
}
return false;
}
/**
* 恢复记录地址
*
* @return true 表示下载完成
*/
private boolean resumeRecordLocation(int i, long startL, long endL) {
mConstance.CURRENT_LOCATION += endL - startL;
Log.d(TAG, "++++++++++ 线程_" + i + "_已经下载完成 ++++++++++");
mConstance.COMPLETE_THREAD_NUM++;
mConstance.STOP_NUM++;
mConstance.CANCEL_NUM++;
if (mConstance.isComplete()) {
if (mConfigFile.exists()) {
mConfigFile.delete();
}
mListener.onComplete();
mConstance.isDownloading = false;
return true;
}
return false;
}
/**
* 创建单线程任务
*/
private void addSingleTask(int i, long startL, long endL, long fileLength) {
ChildThreadConfigEntity entity = new ChildThreadConfigEntity();
entity.FILE_SIZE = fileLength;
entity.DOWNLOAD_URL =
mEntity.isRedirect() ? mEntity.getRedirectUrl() : mEntity.getDownloadUrl();
entity.TEMP_FILE = mTempFile;
entity.THREAD_ID = i;
entity.START_LOCATION = startL;
entity.END_LOCATION = endL;
entity.CONFIG_FILE_PATH = mConfigFile.getPath();
entity.IS_SUPPORT_BREAK_POINT = mTaskEntity.isSupportBP;
entity.DOWNLOAD_TASK_ENTITY = mTaskEntity;
mConstance.THREAD_NUM = mThreadNum;
SingleThreadTask task = new SingleThreadTask(mConstance, mListener, entity);
mTask.put(i, task);
}
/**
* 启动单线程下载任务
*/
private void startSingleTask(int[] recordL) {
if (mConstance.CURRENT_LOCATION > 0) {
mListener.onResume(mConstance.CURRENT_LOCATION);
} else {
mListener.onStart(mConstance.CURRENT_LOCATION);
}
mFixedThreadPool = Executors.newFixedThreadPool(recordL.length);
for (int l : recordL) {
if (l == -1) continue;
Runnable task = mTask.get(l);
if (task != null) {
mFixedThreadPool.execute(task);
}
}
}
/**
* 处理断点
*/
private void handleBreakpoint() throws IOException {
long fileLength = mEntity.getFileSize();
Properties pro = CommonUtil.loadConfig(mConfigFile);
int blockSize = (int) (fileLength / mThreadNum);
int[] recordL = new int[mThreadNum];
for (int i = 0; i < mThreadNum; i++) {
recordL[i] = -1;
}
int rl = 0;
if (isNewTask) {
CommonUtil.createFile(mTempFile.getPath());
BufferedRandomAccessFile file =
new BufferedRandomAccessFile(new File(mTempFile.getPath()), "rwd", 8192);
//设置文件长度
file.setLength(fileLength);
file.close();
}
for (int i = 0; i < mThreadNum; i++) {
long startL = i * blockSize, endL = (i + 1) * blockSize;
Object state = pro.getProperty(mTempFile.getName() + "_state_" + i);
if (state != null && Integer.parseInt(state + "") == 1) { //该线程已经完成
if (resumeRecordLocation(i, startL, endL)) return;
continue;
}
//分配下载位置
Object record = pro.getProperty(mTempFile.getName() + "_record_" + i);
//如果有记录,则恢复下载
if (!isNewTask && record != null && Long.parseLong(record + "") >= 0) {
Long r = Long.parseLong(record + "");
mConstance.CURRENT_LOCATION += r - startL;
Log.d(TAG, "任务【" + mEntity.getFileName() + "】线程__" + i + "__恢复下载");
mListener.onChildResume(r);
startL = r;
recordL[rl] = i;
rl++;
} else {
recordL[rl] = i;
rl++;
}
if (i == (mThreadNum - 1)) {
//最后一个线程的结束位置即为文件的总长度
endL = fileLength;
}
addSingleTask(i, startL, endL, fileLength);
}
startSingleTask(recordL);
}
/**
* 处理不支持断点的下载
*/
private void handleNoSupportBreakpointDownload() {
ChildThreadConfigEntity entity = new ChildThreadConfigEntity();
long len = mEntity.getFileSize();
entity.FILE_SIZE = len;
entity.DOWNLOAD_URL =
mEntity.isRedirect() ? mEntity.getRedirectUrl() : mEntity.getDownloadUrl();
entity.TEMP_FILE = mTempFile;
entity.THREAD_ID = 0;
entity.START_LOCATION = 0;
entity.END_LOCATION = entity.FILE_SIZE;
entity.CONFIG_FILE_PATH = mConfigFile.getPath();
entity.IS_SUPPORT_BREAK_POINT = mTaskEntity.isSupportBP;
entity.DOWNLOAD_TASK_ENTITY = mTaskEntity;
mConstance.THREAD_NUM = mThreadNum;
SingleThreadTask task = new SingleThreadTask(mConstance, mListener, entity);
mTask.put(0, task);
mFixedThreadPool.execute(task);
mListener.onPostPre(len);
mListener.onStart(0);
}
private void failDownload(String errorMsg) {
Log.e(TAG, errorMsg);
mConstance.isDownloading = false;
mListener.onFail();
}
}

@ -14,14 +14,15 @@
* limitations under the License. * limitations under the License.
*/ */
package com.arialyy.aria.core.download; package com.arialyy.aria.core.download.downloader;
import android.content.Context; import android.content.Context;
import android.util.Log; import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.orm.DbEntity; import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.orm.DbUtil;
import com.arialyy.aria.util.BufferedRandomAccessFile; import com.arialyy.aria.util.BufferedRandomAccessFile;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import java.io.File; import java.io.File;
@ -37,7 +38,7 @@ import java.util.concurrent.Executors;
* Created by lyy on 2015/8/25. * Created by lyy on 2015/8/25.
* 下载工具类 * 下载工具类
*/ */
class DownloadUtil implements IDownloadUtil, Runnable { public class DownloadUtil implements IDownloadUtil, Runnable {
private static final String TAG = "DownloadUtil"; private static final String TAG = "DownloadUtil";
/** /**
* 线程数 * 线程数
@ -54,7 +55,7 @@ class DownloadUtil implements IDownloadUtil, Runnable {
private boolean isSupportBreakpoint = true; private boolean isSupportBreakpoint = true;
private Context mContext; private Context mContext;
private DownloadEntity mDownloadEntity; private DownloadEntity mDownloadEntity;
private DownloadTaskEntity mDownloadTaskEntity; private DownloadTaskEntity mTaskEntity;
private ExecutorService mFixedThreadPool; private ExecutorService mFixedThreadPool;
private File mDownloadFile; //下载的文件 private File mDownloadFile; //下载的文件
private File mConfigFile;//下载信息配置文件 private File mConfigFile;//下载信息配置文件
@ -62,9 +63,9 @@ class DownloadUtil implements IDownloadUtil, Runnable {
private DownloadStateConstance CONSTANCE; private DownloadStateConstance CONSTANCE;
DownloadUtil(Context context, DownloadTaskEntity entity, IDownloadListener downloadListener) { DownloadUtil(Context context, DownloadTaskEntity entity, IDownloadListener downloadListener) {
mDownloadEntity = entity.downloadEntity; mDownloadEntity = entity.getEntity();
mContext = context.getApplicationContext(); mContext = context.getApplicationContext();
mDownloadTaskEntity = entity; mTaskEntity = entity;
mListener = downloadListener; mListener = downloadListener;
// 线程下载数改变后,新的下载才会生效 // 线程下载数改变后,新的下载才会生效
//mFixedThreadPool = Executors.newFixedThreadPool(Integer.MAX_VALUE); //mFixedThreadPool = Executors.newFixedThreadPool(Integer.MAX_VALUE);
@ -74,7 +75,7 @@ class DownloadUtil implements IDownloadUtil, Runnable {
private void init() { private void init() {
mConnectTimeOut = AriaManager.getInstance(mContext).getDownloadConfig().getConnectTimeOut(); mConnectTimeOut = AriaManager.getInstance(mContext).getDownloadConfig().getConnectTimeOut();
mDownloadFile = new File(mDownloadTaskEntity.downloadEntity.getDownloadPath()); mDownloadFile = new File(mTaskEntity.getEntity().getDownloadPath());
//读取已完成的线程数 //读取已完成的线程数
mConfigFile = new File(mContext.getFilesDir().getPath() mConfigFile = new File(mContext.getFilesDir().getPath()
+ AriaManager.DOWNLOAD_TEMP_DIR + AriaManager.DOWNLOAD_TEMP_DIR
@ -113,6 +114,10 @@ class DownloadUtil implements IDownloadUtil, Runnable {
return mListener; return mListener;
} }
@Override public long getFileSize() {
return mDownloadEntity.getFileSize();
}
/** /**
* 获取当前下载位置 * 获取当前下载位置
*/ */
@ -148,6 +153,7 @@ class DownloadUtil implements IDownloadUtil, Runnable {
task.cancel(); task.cancel();
} }
} }
CommonUtil.delDownloadTaskConfig(mTaskEntity.removeFile, mDownloadEntity);
} }
/** /**
@ -170,7 +176,7 @@ class DownloadUtil implements IDownloadUtil, Runnable {
/** /**
* 删除下载记录文件 * 删除下载记录文件
*/ */
@Override public void delConfigFile() { public void delConfigFile() {
if (mContext != null && mDownloadEntity != null) { if (mContext != null && mDownloadEntity != null) {
File dFile = new File(mDownloadEntity.getDownloadPath()); File dFile = new File(mDownloadEntity.getDownloadPath());
File config = File config =
@ -184,7 +190,7 @@ class DownloadUtil implements IDownloadUtil, Runnable {
/** /**
* 删除temp文件 * 删除temp文件
*/ */
@Override public void delTempFile() { public void delTempFile() {
if (mContext != null && mDownloadEntity != null) { if (mContext != null && mDownloadEntity != null) {
File dFile = new File(mDownloadEntity.getDownloadPath()); File dFile = new File(mDownloadEntity.getDownloadPath());
if (dFile.exists()) { if (dFile.exists()) {
@ -217,7 +223,7 @@ class DownloadUtil implements IDownloadUtil, Runnable {
try { try {
URL url = new URL(mDownloadEntity.getDownloadUrl()); URL url = new URL(mDownloadEntity.getDownloadUrl());
conn = ConnectionHelp.handleConnection(url); conn = ConnectionHelp.handleConnection(url);
conn = ConnectionHelp.setConnectParam(mDownloadTaskEntity, conn); conn = ConnectionHelp.setConnectParam(mTaskEntity, conn);
conn.setRequestProperty("Range", "bytes=" + 0 + "-"); conn.setRequestProperty("Range", "bytes=" + 0 + "-");
conn.setConnectTimeout(mConnectTimeOut); conn.setConnectTimeout(mConnectTimeOut);
conn.connect(); conn.connect();
@ -237,7 +243,7 @@ class DownloadUtil implements IDownloadUtil, Runnable {
} }
/** /**
* 处理状态 * 处理状态
*/ */
private void handleConnect(HttpURLConnection conn) throws IOException { private void handleConnect(HttpURLConnection conn) throws IOException {
int len = conn.getContentLength(); int len = conn.getContentLength();
@ -290,19 +296,18 @@ class DownloadUtil implements IDownloadUtil, Runnable {
* 处理30x跳转 * 处理30x跳转
*/ */
private void handle302Turn(HttpURLConnection conn) throws IOException { private void handle302Turn(HttpURLConnection conn) throws IOException {
String newUrl = conn.getHeaderField(mDownloadTaskEntity.redirectUrlKey); String newUrl = conn.getHeaderField(mTaskEntity.redirectUrlKey);
Log.d(TAG, "30x跳转,新url为【" + newUrl + "】"); Log.d(TAG, "30x跳转,新url为【" + newUrl + "】");
mDownloadEntity.setRedirect(true); mDownloadEntity.setRedirect(true);
mDownloadEntity.setRedirectUrl(newUrl); mDownloadEntity.setRedirectUrl(newUrl);
mDownloadEntity.update(); mDownloadEntity.update();
String cookies = conn.getHeaderField("Set-Cookie"); String cookies = conn.getHeaderField("Set-Cookie");
conn = (HttpURLConnection) new URL(newUrl).openConnection(); conn = (HttpURLConnection) new URL(newUrl).openConnection();
conn = ConnectionHelp.setConnectParam(mDownloadTaskEntity, conn); conn = ConnectionHelp.setConnectParam(mTaskEntity, conn);
conn.setRequestProperty("Cookie", cookies); conn.setRequestProperty("Cookie", cookies);
conn.setRequestProperty("Range", "bytes=" + 0 + "-"); conn.setRequestProperty("Range", "bytes=" + 0 + "-");
conn.setConnectTimeout(mConnectTimeOut); conn.setConnectTimeout(mConnectTimeOut);
conn.connect(); conn.connect();
handleConnect(conn); handleConnect(conn);
} }
@ -333,7 +338,7 @@ class DownloadUtil implements IDownloadUtil, Runnable {
//分配下载位置 //分配下载位置
Object record = pro.getProperty(mDownloadFile.getName() + "_record_" + i); Object record = pro.getProperty(mDownloadFile.getName() + "_record_" + i);
//如果有记录,则恢复下载 //如果有记录,则恢复下载
if (!isNewTask && record != null && Long.parseLong(record + "") > 0) { if (!isNewTask && record != null && Long.parseLong(record + "") >= 0) {
Long r = Long.parseLong(record + ""); Long r = Long.parseLong(record + "");
CONSTANCE.CURRENT_LOCATION += r - startL; CONSTANCE.CURRENT_LOCATION += r - startL;
Log.d(TAG, "任务【" + mDownloadEntity.getFileName() + "】线程__" + i + "__恢复下载"); Log.d(TAG, "任务【" + mDownloadEntity.getFileName() + "】线程__" + i + "__恢复下载");
@ -373,7 +378,7 @@ class DownloadUtil implements IDownloadUtil, Runnable {
entity.END_LOCATION = entity.FILE_SIZE; entity.END_LOCATION = entity.FILE_SIZE;
entity.CONFIG_FILE_PATH = mConfigFile.getPath(); entity.CONFIG_FILE_PATH = mConfigFile.getPath();
entity.IS_SUPPORT_BREAK_POINT = isSupportBreakpoint; entity.IS_SUPPORT_BREAK_POINT = isSupportBreakpoint;
entity.DOWNLOAD_TASK_ENTITY = mDownloadTaskEntity; entity.DOWNLOAD_TASK_ENTITY = mTaskEntity;
THREAD_NUM = 1; THREAD_NUM = 1;
CONSTANCE.THREAD_NUM = THREAD_NUM; CONSTANCE.THREAD_NUM = THREAD_NUM;
SingleThreadTask task = new SingleThreadTask(CONSTANCE, mListener, entity); SingleThreadTask task = new SingleThreadTask(CONSTANCE, mListener, entity);
@ -473,7 +478,7 @@ class DownloadUtil implements IDownloadUtil, Runnable {
entity.END_LOCATION = endL; entity.END_LOCATION = endL;
entity.CONFIG_FILE_PATH = mConfigFile.getPath(); entity.CONFIG_FILE_PATH = mConfigFile.getPath();
entity.IS_SUPPORT_BREAK_POINT = isSupportBreakpoint; entity.IS_SUPPORT_BREAK_POINT = isSupportBreakpoint;
entity.DOWNLOAD_TASK_ENTITY = mDownloadTaskEntity; entity.DOWNLOAD_TASK_ENTITY = mTaskEntity;
CONSTANCE.THREAD_NUM = THREAD_NUM; CONSTANCE.THREAD_NUM = THREAD_NUM;
SingleThreadTask task = new SingleThreadTask(CONSTANCE, mListener, entity); SingleThreadTask task = new SingleThreadTask(CONSTANCE, mListener, entity);
mTask.put(i, task); mTask.put(i, task);
@ -498,23 +503,4 @@ class DownloadUtil implements IDownloadUtil, Runnable {
} }
} }
/**
* 子线程下载信息类
*/
final static class ChildThreadConfigEntity {
//线程Id
int THREAD_ID;
//下载文件大小
long FILE_SIZE;
//子线程启动下载位置
long START_LOCATION;
//子线程结束下载位置
long END_LOCATION;
//下载路径
File TEMP_FILE;
String DOWNLOAD_URL;
String CONFIG_FILE_PATH;
DownloadTaskEntity DOWNLOAD_TASK_ENTITY;
boolean IS_SUPPORT_BREAK_POINT = true;
}
} }

@ -0,0 +1,161 @@
/*
* 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.downloader;
import android.util.Log;
import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.util.CommonUtil;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* 下载文件信息获取
*/
class FileInfoThread implements Runnable {
private final String TAG = "FileInfoThread";
private DownloadEntity mEntity;
private DownloadTaskEntity mTaskEntity;
private int mConnectTimeOut;
private OnFileInfoCallback onFileInfoListener;
interface OnFileInfoCallback {
/**
* 处理完成
*
* @param code 状态码
*/
void onComplete(String url, int code);
/**
* 请求失败
*
* @param errorMsg 错误信息
*/
void onFail(String url, String errorMsg);
}
FileInfoThread(DownloadTaskEntity taskEntity) {
this(taskEntity, null);
}
FileInfoThread(DownloadTaskEntity taskEntity, OnFileInfoCallback callback) {
this.mTaskEntity = taskEntity;
mEntity = taskEntity.getEntity();
mConnectTimeOut =
AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getConnectTimeOut();
onFileInfoListener = callback;
}
@Override public void run() {
HttpURLConnection conn = null;
try {
URL url = new URL(mEntity.getDownloadUrl());
conn = ConnectionHelp.handleConnection(url);
conn = ConnectionHelp.setConnectParam(mTaskEntity, conn);
conn.setRequestProperty("Range", "bytes=" + 0 + "-");
conn.setConnectTimeout(mConnectTimeOut);
conn.connect();
handleConnect(conn);
} catch (IOException e) {
failDownload("下载失败【downloadUrl:"
+ mEntity.getDownloadUrl()
+ "】\n【filePath:"
+ mEntity.getDownloadPath()
+ "】\n"
+ CommonUtil.getPrintException(e));
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
private void handleConnect(HttpURLConnection conn) throws IOException {
int len = conn.getContentLength();
int code = conn.getResponseCode();
boolean isComplete = false;
mTaskEntity.code = code;
if (code == HttpURLConnection.HTTP_PARTIAL) {
if (!checkLen(len)) return;
mEntity.setFileSize(len);
mTaskEntity.isSupportBP = true;
isComplete = true;
} else if (code == HttpURLConnection.HTTP_OK) {
if (!checkLen(len)) return;
mEntity.setFileSize(len);
mTaskEntity.isSupportBP = false;
isComplete = true;
} else if (code == HttpURLConnection.HTTP_NOT_FOUND) {
failDownload("任务【" + mEntity.getDownloadUrl() + "】下载失败,错误码:404");
} else if (code == HttpURLConnection.HTTP_MOVED_TEMP
|| code == HttpURLConnection.HTTP_MOVED_PERM
|| code == HttpURLConnection.HTTP_SEE_OTHER) {
mTaskEntity.redirectUrlKey = conn.getHeaderField(mTaskEntity.redirectUrlKey);
mEntity.setRedirect(true);
mEntity.setRedirectUrl(mTaskEntity.redirectUrlKey);
handle302Turn(conn);
} else {
failDownload("任务【" + mEntity.getDownloadUrl() + "】下载失败,错误码:" + code);
}
if (isComplete) {
if (onFileInfoListener != null) {
onFileInfoListener.onComplete(mEntity.getDownloadUrl(), code);
}
mEntity.update();
mTaskEntity.update();
}
}
/**
* 处理30x跳转
*/
private void handle302Turn(HttpURLConnection conn) throws IOException {
String newUrl = conn.getHeaderField(mTaskEntity.redirectUrlKey);
Log.d(TAG, "30x跳转,新url为【" + newUrl + "】");
String cookies = conn.getHeaderField("Set-Cookie");
conn = (HttpURLConnection) new URL(newUrl).openConnection();
conn = ConnectionHelp.setConnectParam(mTaskEntity, conn);
conn.setRequestProperty("Cookie", cookies);
conn.setRequestProperty("Range", "bytes=" + 0 + "-");
conn.setConnectTimeout(mConnectTimeOut);
conn.connect();
handleConnect(conn);
}
/**
* 检查长度是否合法
*
* @param len 从服务器获取的文件长度
* @return true, 合法
*/
private boolean checkLen(long len) {
if (len < 0) {
failDownload("任务【" + mEntity.getDownloadUrl() + "】下载失败,文件长度小于0");
return false;
}
return true;
}
private void failDownload(String errorMsg) {
Log.e(TAG, errorMsg);
if (onFileInfoListener != null) {
onFileInfoListener.onFail(mEntity.getDownloadUrl(), errorMsg);
}
}
}

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.arialyy.aria.core.download; package com.arialyy.aria.core.download.downloader;
/** /**
* 下载监听 * 下载监听

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.arialyy.aria.core.download; package com.arialyy.aria.core.download.downloader;
/** /**
* Created by lyy on 2016/10/31. * Created by lyy on 2016/10/31.
@ -22,6 +22,11 @@ package com.arialyy.aria.core.download;
*/ */
interface IDownloadUtil { interface IDownloadUtil {
/**
* 获取文件大小
*/
public long getFileSize();
/** /**
* 获取当前下载位置 * 获取当前下载位置
*/ */
@ -53,19 +58,4 @@ interface IDownloadUtil {
* 从上次断点恢复下载 * 从上次断点恢复下载
*/ */
public void resumeDownload(); public void resumeDownload();
/**
* 删除下载记录文件
*/
public void delConfigFile();
/**
* 删除temp文件
*/
public void delTempFile();
/**
* 设置最大下载速度
*/
public void setMaxSpeed(double maxSpeed);
} }

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.arialyy.aria.core.download; package com.arialyy.aria.core.download.downloader;
import android.os.Build; import android.os.Build;
import android.text.TextUtils; import android.text.TextUtils;
@ -36,7 +36,7 @@ import java.util.Properties;
*/ */
final class SingleThreadTask implements Runnable { final class SingleThreadTask implements Runnable {
private static final String TAG = "SingleThreadTask"; private static final String TAG = "SingleThreadTask";
private DownloadUtil.ChildThreadConfigEntity mConfigEntity; private ChildThreadConfigEntity mConfigEntity;
private String mConfigFPath; private String mConfigFPath;
private long mChildCurrentLocation = 0; private long mChildCurrentLocation = 0;
private int mBufSize; private int mBufSize;
@ -45,7 +45,7 @@ final class SingleThreadTask implements Runnable {
private long mSleepTime = 0; private long mSleepTime = 0;
SingleThreadTask(DownloadStateConstance constance, IDownloadListener listener, SingleThreadTask(DownloadStateConstance constance, IDownloadListener listener,
DownloadUtil.ChildThreadConfigEntity downloadInfo) { ChildThreadConfigEntity downloadInfo) {
AriaManager manager = AriaManager.getInstance(AriaManager.APP); AriaManager manager = AriaManager.getInstance(AriaManager.APP);
CONSTANCE = constance; CONSTANCE = constance;
CONSTANCE.CONNECT_TIME_OUT = manager.getDownloadConfig().getConnectTimeOut(); CONSTANCE.CONNECT_TIME_OUT = manager.getDownloadConfig().getConnectTimeOut();

@ -0,0 +1,136 @@
/*
* 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.inf;
import android.os.Parcel;
import android.os.Parcelable;
import com.arialyy.aria.orm.DbEntity;
import com.arialyy.aria.orm.Ignore;
/**
* Created by AriaL on 2017/6/29.
*/
public abstract class AbsEntity extends DbEntity implements IEntity, Parcelable {
/**
* 速度
*/
@Ignore private long speed = 0;
/**
* 单位转换后的速度
*/
@Ignore private String convertSpeed = "0b/s";
/**
* 扩展字段
*/
private String str = "";
/**
* 文件大小
*/
private long fileSize = 1;
private int state = STATE_WAIT;
/**
* 当前下载进度
*/
private long currentProgress = 0;
/**
* 完成时间
*/
private long completeTime;
public long getSpeed() {
return speed;
}
public void setSpeed(long speed) {
this.speed = speed;
}
public String getConvertSpeed() {
return convertSpeed;
}
public void setConvertSpeed(String convertSpeed) {
this.convertSpeed = convertSpeed;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public long getFileSize() {
return fileSize;
}
public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public long getCurrentProgress() {
return currentProgress;
}
public void setCurrentProgress(long currentProgress) {
this.currentProgress = currentProgress;
}
public long getCompleteTime() {
return completeTime;
}
public void setCompleteTime(long completeTime) {
this.completeTime = completeTime;
}
public AbsEntity() {
}
@Override public int describeContents() {
return 0;
}
@Override public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(this.speed);
dest.writeString(this.convertSpeed);
dest.writeString(this.str);
dest.writeLong(this.fileSize);
dest.writeInt(this.state);
dest.writeLong(this.currentProgress);
dest.writeLong(this.completeTime);
}
protected AbsEntity(Parcel in) {
this.speed = in.readLong();
this.convertSpeed = in.readString();
this.str = in.readString();
this.fileSize = in.readLong();
this.state = in.readInt();
this.currentProgress = in.readLong();
this.completeTime = in.readLong();
}
}

@ -23,92 +23,18 @@ import com.arialyy.aria.orm.Ignore;
/** /**
* Created by AriaL on 2017/6/3. * Created by AriaL on 2017/6/3.
*/ */
public abstract class AbsGroupEntity<CHILD_ENTITY extends AbsNormalEntity> extends DbEntity implements IEntity, Parcelable { public abstract class AbsGroupEntity extends AbsEntity implements Parcelable {
/** /**
* 速度 * 组名
*/ */
@Ignore private long speed = 0; private String groupName = "";
/**
* 单位转换后的速度
*/
@Ignore private String convertSpeed = "0b/s";
/**
* 扩展字段
*/
private String str = "";
/**
* 文件大小
*/
private long fileSize = 1;
private int state = STATE_WAIT;
/**
* 当前下载进度
*/
private long currentProgress = 0;
/**
* 完成时间
*/
private long completeTime;
/**
* 文件名
*/
private String grooupName = "";
public long getSpeed() {
return speed;
}
public void setSpeed(long speed) {
this.speed = speed;
}
public String getConvertSpeed() {
return convertSpeed;
}
public void setConvertSpeed(String convertSpeed) {
this.convertSpeed = convertSpeed;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public long getFileSize() {
return fileSize;
}
public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public long getCurrentProgress() {
return currentProgress;
}
public void setCurrentProgress(long currentProgress) {
this.currentProgress = currentProgress;
}
public long getCompleteTime() { public String getGroupName() {
return completeTime; return groupName;
} }
public void setCompleteTime(long completeTime) { public void setGroupName(String groupName) {
this.completeTime = completeTime; this.groupName = groupName;
} }
public AbsGroupEntity() { public AbsGroupEntity() {
@ -119,22 +45,12 @@ public abstract class AbsGroupEntity<CHILD_ENTITY extends AbsNormalEntity> exten
} }
@Override public void writeToParcel(Parcel dest, int flags) { @Override public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(this.speed); super.writeToParcel(dest, flags);
dest.writeString(this.convertSpeed); dest.writeString(this.groupName);
dest.writeString(this.str);
dest.writeLong(this.fileSize);
dest.writeInt(this.state);
dest.writeLong(this.currentProgress);
dest.writeLong(this.completeTime);
} }
protected AbsGroupEntity(Parcel in) { protected AbsGroupEntity(Parcel in) {
this.speed = in.readLong(); super(in);
this.convertSpeed = in.readString(); this.groupName = in.readString();
this.str = in.readString();
this.fileSize = in.readLong();
this.state = in.readInt();
this.currentProgress = in.readLong();
this.completeTime = in.readLong();
} }
} }

@ -0,0 +1,71 @@
/*
* 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.inf;
import com.arialyy.aria.util.CommonUtil;
/**
* Created by AriaL on 2017/6/29.
*/
public abstract class AbsGroupTask<TASK_ENTITY extends AbsTaskEntity, ENTITY extends AbsGroupEntity>
extends AbsTask<ENTITY> {
protected TASK_ENTITY mTaskEntity;
@Override public int getPercent() {
return 0;
}
@Override public long getFileSize() {
return 0;
}
@Override public String getConvertFileSize() {
return null;
}
@Override public long getCurrentProgress() {
return 0;
}
@Override public String getConvertCurrentProgress() {
return null;
}
@Override public int getState() {
return mEntity.getState();
}
@Override public String getExtendField() {
return mEntity.getStr();
}
@Override public String getKey() {
return mEntity.getGroupName();
}
@Override public boolean isRunning() {
return false;
}
@Override public ENTITY getEntity() {
return mEntity;
}
@Override public void removeRecord() {
}
}

@ -23,55 +23,27 @@ import com.arialyy.aria.orm.Ignore;
/** /**
* Created by AriaL on 2017/6/3. * Created by AriaL on 2017/6/3.
*/ */
public abstract class AbsNormalEntity extends DbEntity implements IEntity, Parcelable { public abstract class AbsNormalEntity extends AbsEntity implements Parcelable {
/**
* 速度
*/
@Ignore private long speed = 0;
/**
* 单位转换后的速度
*/
@Ignore private String convertSpeed = "0b/s";
/** /**
* 下载失败计数每次开始都重置为0 * 下载失败计数每次开始都重置为0
*/ */
@Ignore private int failNum = 0; @Ignore private int failNum = 0;
/**
* 扩展字段
*/
private String str = "";
/**
* 文件大小
*/
private long fileSize = 1;
private int state = STATE_WAIT;
/**
* 当前下载进度
*/
private long currentProgress = 0;
/**
* 完成时间
*/
private long completeTime;
/** /**
* 文件名 * 文件名
*/ */
private String fileName = ""; private String fileName = "";
public long getSpeed() { /**
return speed; * 是否是任务组里面的下载实体
} */
private boolean isGroupChild = false;
public void setSpeed(long speed) {
this.speed = speed;
}
public String getConvertSpeed() { public boolean isGroupChild() {
return convertSpeed; return isGroupChild;
} }
public void setConvertSpeed(String convertSpeed) { public void setGroupChild(boolean groupChild) {
this.convertSpeed = convertSpeed; isGroupChild = groupChild;
} }
public int getFailNum() { public int getFailNum() {
@ -82,46 +54,6 @@ public abstract class AbsNormalEntity extends DbEntity implements IEntity, Parce
this.failNum = failNum; this.failNum = failNum;
} }
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public long getFileSize() {
return fileSize;
}
public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public long getCurrentProgress() {
return currentProgress;
}
public void setCurrentProgress(long currentProgress) {
this.currentProgress = currentProgress;
}
public long getCompleteTime() {
return completeTime;
}
public void setCompleteTime(long completeTime) {
this.completeTime = completeTime;
}
public String getFileName() { public String getFileName() {
return fileName; return fileName;
} }
@ -138,26 +70,16 @@ public abstract class AbsNormalEntity extends DbEntity implements IEntity, Parce
} }
@Override public void writeToParcel(Parcel dest, int flags) { @Override public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(this.speed); super.writeToParcel(dest, flags);
dest.writeString(this.convertSpeed);
dest.writeInt(this.failNum); dest.writeInt(this.failNum);
dest.writeString(this.str);
dest.writeLong(this.fileSize);
dest.writeInt(this.state);
dest.writeLong(this.currentProgress);
dest.writeLong(this.completeTime);
dest.writeString(this.fileName); dest.writeString(this.fileName);
dest.writeByte(this.isGroupChild ? (byte) 1 : (byte) 0);
} }
protected AbsNormalEntity(Parcel in) { protected AbsNormalEntity(Parcel in) {
this.speed = in.readLong(); super(in);
this.convertSpeed = in.readString();
this.failNum = in.readInt(); this.failNum = in.readInt();
this.str = in.readString();
this.fileSize = in.readLong();
this.state = in.readInt();
this.currentProgress = in.readLong();
this.completeTime = in.readLong();
this.fileName = in.readString(); this.fileName = in.readString();
this.isGroupChild = in.readByte() != 0;
} }
} }

@ -0,0 +1,100 @@
/*
* 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.inf;
import com.arialyy.aria.util.CommonUtil;
/**
* Created by lyy on 2017/6/3.
*/
public abstract class AbsNormalTask<ENTITY extends AbsEntity> extends AbsTask<ENTITY> {
private boolean isHeighestTask = false;
/**
* 暂停任务并让任务处于等待状态
*/
public void stopAndWait() {
}
/**
* 最高优先级命令最高优先级命令有以下属性
* 1在下载队列中有且只有一个最高优先级任务
* 2最高优先级任务会一直存在直到用户手动暂停或任务完成
* 3任务调度器不会暂停最高优先级任务
* 4用户手动暂停或任务完成后第二次重新执行该任务该命令将失效
* 5如果下载队列中已经满了则会停止队尾的任务
* 6把任务设置为最高优先级任务后将自动执行任务不需要重新调用start()启动任务
*/
public void setHighestPriority(boolean isHighestPriority) {
isHeighestTask = isHighestPriority;
}
public boolean isHighestPriorityTask() {
return isHeighestTask;
}
/**
* 获取百分比进度
*
* @return 返回百分比进度如果文件长度为0返回0
*/
@Override public int getPercent() {
if (mEntity.getFileSize() == 0) {
return 0;
}
return (int) (mEntity.getCurrentProgress() * 100 / mEntity.getFileSize());
}
/**
* 获取文件大小
*/
@Override public long getFileSize() {
return mEntity.getFileSize();
}
/**
* 转换单位后的文件长度
*
* @return 如果文件长度为0则返回0m否则返回转换后的长度1b1kb1mb1gb1tb
*/
@Override public String getConvertFileSize() {
if (mEntity.getFileSize() == 0) {
return "0mb";
}
return CommonUtil.formatFileSize(mEntity.getFileSize());
}
/**
* 获取当前下载进度
*/
@Override public long getCurrentProgress() {
return mEntity.getCurrentProgress();
}
/**
* 获取单位转换后的进度
*
* @return 已经下载3mb的大小则返回{@code 3mb}
*/
@Override public String getConvertCurrentProgress() {
if (mEntity.getCurrentProgress() == 0) {
return "0b";
}
return CommonUtil.formatFileSize(mEntity.getCurrentProgress());
}
}

@ -16,26 +16,21 @@
package com.arialyy.aria.core.inf; package com.arialyy.aria.core.inf;
import android.content.Context; import android.content.Context;
import com.arialyy.aria.util.CommonUtil; import android.os.Handler;
/** /**
* Created by lyy on 2017/6/3. * Created by AriaL on 2017/6/29.
*/ */
public abstract class AbsTask<TASK_ENTITY extends AbsTaskEntity, ENTITY extends AbsNormalEntity> public abstract class AbsTask<ENTITY extends AbsEntity> implements ITask<ENTITY> {
implements ITask<ENTITY> {
protected ENTITY mEntity; protected ENTITY mEntity;
protected Handler mOutHandler;
/** /**
* 用于生成该任务对象的hash码 * 用于生成该任务对象的hash码
*/ */
private String mTargetName; private String mTargetName;
protected Context mContext; protected Context mContext;
private boolean isHeighestTask = false;
@Override public void stopAndWait() {
}
/** /**
* 任务当前状态 * 任务当前状态
@ -46,6 +41,15 @@ public abstract class AbsTask<TASK_ENTITY extends AbsTaskEntity, ENTITY extends
return mEntity == null ? IEntity.STATE_OTHER : mEntity.getState(); return mEntity == null ? IEntity.STATE_OTHER : mEntity.getState();
} }
/**
* 获取保存的扩展字段
*
* @return 如果实体不存在则返回null否则返回扩展字段
*/
@Override public String getExtendField() {
return mEntity == null ? null : mEntity.getStr();
}
/** /**
* @return 返回原始byte速度需要你在配置文件中配置 * @return 返回原始byte速度需要你在配置文件中配置
* <pre> * <pre>
@ -88,73 +92,6 @@ public abstract class AbsTask<TASK_ENTITY extends AbsTaskEntity, ENTITY extends
return mEntity.getConvertSpeed(); return mEntity.getConvertSpeed();
} }
/**
* 最高优先级命令最高优先级命令有以下属性
* 1在下载队列中有且只有一个最高优先级任务
* 2最高优先级任务会一直存在直到用户手动暂停或任务完成
* 3任务调度器不会暂停最高优先级任务
* 4用户手动暂停或任务完成后第二次重新执行该任务该命令将失效
* 5如果下载队列中已经满了则会停止队尾的任务
* 6把任务设置为最高优先级任务后将自动执行任务不需要重新调用start()启动任务
*/
@Override public void setHighestPriority(boolean isHighestPriority) {
isHeighestTask = isHighestPriority;
}
@Override public boolean isHighestPriorityTask() {
return isHeighestTask;
}
/**
* 获取百分比进度
*
* @return 返回百分比进度如果文件长度为0返回0
*/
@Override public int getPercent() {
if (mEntity.getFileSize() == 0) {
return 0;
}
return (int) (mEntity.getCurrentProgress() * 100 / mEntity.getFileSize());
}
/**
* 获取文件大小
*/
@Override public long getFileSize() {
return mEntity.getFileSize();
}
/**
* 转换单位后的文件长度
*
* @return 如果文件长度为0则返回0m否则返回转换后的长度1b1kb1mb1gb1tb
*/
@Override public String getConvertFileSize() {
if (mEntity.getFileSize() == 0) {
return "0mb";
}
return CommonUtil.formatFileSize(mEntity.getFileSize());
}
/**
* 获取当前下载进度
*/
@Override public long getCurrentProgress() {
return mEntity.getCurrentProgress();
}
/**
* 获取单位转换后的进度
*
* @return 已经下载3mb的大小则返回{@code 3mb}
*/
@Override public String getConvertCurrentProgress() {
if (mEntity.getCurrentProgress() == 0) {
return "0b";
}
return CommonUtil.formatFileSize(mEntity.getCurrentProgress());
}
@Override public ENTITY getEntity() { @Override public ENTITY getEntity() {
return mEntity; return mEntity;
} }

@ -16,14 +16,22 @@
package com.arialyy.aria.core.inf; package com.arialyy.aria.core.inf;
import com.arialyy.aria.core.RequestEnum; import com.arialyy.aria.core.RequestEnum;
import com.arialyy.aria.orm.DbEntity;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* Created by lyy on 2017/2/23. * Created by lyy on 2017/2/23.
*/ */
public abstract class AbsTaskEntity<ENTITY extends AbsEntity> extends DbEntity {
public ENTITY entity;
/**
* Task实体对应的key
*/
public String key;
public abstract class AbsTaskEntity {
/** /**
* http 请求头 * http 请求头
*/ */
@ -44,5 +52,17 @@ public abstract class AbsTaskEntity {
*/ */
public boolean removeFile = false; public boolean removeFile = false;
public abstract AbsNormalEntity getEntity(); /**
* 是否支持断点, {@code true} 为支持断点
*/
public boolean isSupportBP = true;
/**
* 状态码
*/
public int code;
public ENTITY getEntity() {
return entity;
}
} }

@ -18,29 +18,17 @@ package com.arialyy.aria.core.inf;
/** /**
* Created by lyy on 2017/2/13. * Created by lyy on 2017/2/13.
*/ */
public interface ITask<ENTITY extends AbsEntity> {
public interface ITask<ENTITY extends AbsNormalEntity> {
/**
* 获取
*/
/** /**
* 暂停任务并让任务处于等待状态 * 获取下载状态
*/ */
public void stopAndWait(); int getState();
/** /**
* 设置任务为最高优先级任务在下载队列中有且只有一个最高优先级任务 * 获取扩展字段
*/
public void setHighestPriority(boolean isHighestPriority);
/**
* 该任务是否是最高优先级任务
*
* @return {@code true} 任务为最高优先级任务
*/ */
public boolean isHighestPriorityTask(); String getExtendField();
/** /**
* 唯一标识符DownloadTask 为下载地址UploadTask 为文件路径 * 唯一标识符DownloadTask 为下载地址UploadTask 为文件路径

@ -19,21 +19,21 @@ package com.arialyy.aria.core.queue;
import android.util.Log; import android.util.Log;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.inf.AbsNormalEntity; import com.arialyy.aria.core.inf.AbsNormalEntity;
import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.AbsNormalTask;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.queue.pool.CachePool; import com.arialyy.aria.core.queue.pool.NormalCachePool;
import com.arialyy.aria.core.queue.pool.ExecutePool; import com.arialyy.aria.core.queue.pool.NormalExecutePool;
import java.util.Set; import java.util.Set;
/** /**
* Created by lyy on 2017/2/23. * Created by lyy on 2017/2/23.
* 任务队列 * 任务队列
*/ */
abstract class AbsTaskQueue<TASK extends AbsTask, TASK_ENTITY extends AbsTaskEntity, ENTITY extends AbsNormalEntity> abstract class AbsTaskQueue<TASK extends AbsNormalTask, TASK_ENTITY extends AbsTaskEntity, ENTITY extends AbsNormalEntity>
implements ITaskQueue<TASK, TASK_ENTITY, ENTITY> { implements ITaskQueue<TASK, TASK_ENTITY, ENTITY> {
private final String TAG = "AbsTaskQueue"; private final String TAG = "AbsTaskQueue";
CachePool<TASK> mCachePool = new CachePool<>(); NormalCachePool<TASK> mCachePool = new NormalCachePool<>();
ExecutePool<TASK> mExecutePool; NormalExecutePool<TASK> mExecutePool;
@Override public boolean taskIsRunning(String key) { @Override public boolean taskIsRunning(String key) {
return mExecutePool.getTask(key) != null; return mExecutePool.getTask(key) != null;
@ -73,14 +73,14 @@ abstract class AbsTaskQueue<TASK extends AbsTask, TASK_ENTITY extends AbsTaskEnt
/** /**
* 获取任务执行池 * 获取任务执行池
*/ */
public ExecutePool getExecutePool() { public NormalExecutePool getExecutePool() {
return mExecutePool; return mExecutePool;
} }
/** /**
* 获取缓存池 * 获取缓存池
*/ */
public CachePool getCachePool() { public NormalCachePool getCachePool() {
return mCachePool; return mCachePool;
} }

@ -23,7 +23,7 @@ import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.queue.pool.ExecutePool; import com.arialyy.aria.core.queue.pool.NormalExecutePool;
import com.arialyy.aria.core.scheduler.DownloadSchedulers; import com.arialyy.aria.core.scheduler.DownloadSchedulers;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Map; import java.util.Map;
@ -48,7 +48,7 @@ public class DownloadTaskQueue
} }
private DownloadTaskQueue() { private DownloadTaskQueue() {
mExecutePool = new ExecutePool<>(true); mExecutePool = new NormalExecutePool<>(true);
} }
@Override public void setTaskHighestPriority(DownloadTask task) { @Override public void setTaskHighestPriority(DownloadTask task) {

@ -19,9 +19,8 @@ package com.arialyy.aria.core.queue;
import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTaskEntity; import com.arialyy.aria.core.download.DownloadTaskEntity;
import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.AbsNormalTask;
import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.inf.ITask;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTask; import com.arialyy.aria.core.upload.UploadTask;
@ -31,7 +30,7 @@ import com.arialyy.aria.core.upload.UploadTaskEntity;
* Created by lyy on 2016/8/16. * Created by lyy on 2016/8/16.
* 任务功能接口 * 任务功能接口
*/ */
public interface ITaskQueue<TASK extends AbsTask, TASK_ENTITY extends AbsTaskEntity, ENTITY extends IEntity> { public interface ITaskQueue<TASK extends AbsNormalTask, TASK_ENTITY extends AbsTaskEntity, ENTITY extends IEntity> {
/** /**
* 通过key判断任务是否正在执行 * 通过key判断任务是否正在执行

@ -19,7 +19,7 @@ package com.arialyy.aria.core.queue;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.queue.pool.ExecutePool; import com.arialyy.aria.core.queue.pool.NormalExecutePool;
import com.arialyy.aria.core.scheduler.UploadSchedulers; import com.arialyy.aria.core.scheduler.UploadSchedulers;
import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.core.upload.UploadTask; import com.arialyy.aria.core.upload.UploadTask;
@ -43,7 +43,7 @@ public class UploadTaskQueue extends AbsTaskQueue<UploadTask, UploadTaskEntity,
} }
private UploadTaskQueue() { private UploadTaskQueue() {
mExecutePool = new ExecutePool<>(false); mExecutePool = new NormalExecutePool<>(false);
} }
@Override public void setMaxTaskNum(int newMaxNum) { @Override public void setMaxTaskNum(int newMaxNum) {

@ -0,0 +1,23 @@
/*
* 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.queue.pool;
/**
* Created by AriaL on 2017/6/29.
* 任务组缓冲池
*/
public class GroupCachePool {
}

@ -0,0 +1,23 @@
/*
* 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.queue.pool;
/**
* Created by AriaL on 2017/6/29.
*/
public class GroupExecutePool {
}

@ -32,14 +32,14 @@ import java.util.concurrent.TimeUnit;
* Created by lyy on 2016/8/14. * Created by lyy on 2016/8/14.
* 任务缓存池所有下载任务最先缓存在这个池中 * 任务缓存池所有下载任务最先缓存在这个池中
*/ */
public class CachePool<TASK extends ITask> implements IPool<TASK> { public class NormalCachePool<TASK extends ITask> implements IPool<TASK> {
private static final String TAG = "CachePool"; private static final String TAG = "NormalCachePool";
private static final int MAX_NUM = Integer.MAX_VALUE; //最大下载任务数 private static final int MAX_NUM = Integer.MAX_VALUE; //最大下载任务数
private static final long TIME_OUT = 1000; private static final long TIME_OUT = 1000;
private Map<String, TASK> mCacheMap; private Map<String, TASK> mCacheMap;
private LinkedBlockingQueue<TASK> mCacheQueue; private LinkedBlockingQueue<TASK> mCacheQueue;
public CachePool() { public NormalCachePool() {
mCacheQueue = new LinkedBlockingQueue<>(MAX_NUM); mCacheQueue = new LinkedBlockingQueue<>(MAX_NUM);
mCacheMap = new HashMap<>(); mCacheMap = new HashMap<>();
} }

@ -31,14 +31,14 @@ import java.util.concurrent.TimeUnit;
* Created by lyy on 2016/8/15. * Created by lyy on 2016/8/15.
* 任务执行池所有当前下载任务都该任务池中默认下载大小为2 * 任务执行池所有当前下载任务都该任务池中默认下载大小为2
*/ */
public class ExecutePool<TASK extends ITask> implements IPool<TASK> { public class NormalExecutePool<TASK extends ITask> implements IPool<TASK> {
private static final String TAG = "ExecutePool"; private static final String TAG = "NormalExecutePool";
private static final long TIME_OUT = 1000; private static final long TIME_OUT = 1000;
private ArrayBlockingQueue<TASK> mExecuteQueue; private ArrayBlockingQueue<TASK> mExecuteQueue;
private Map<String, TASK> mExecuteMap; private Map<String, TASK> mExecuteMap;
private int mSize; private int mSize;
public ExecutePool(boolean isDownload) { public NormalExecutePool(boolean isDownload) {
if (isDownload) { if (isDownload) {
mSize = AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getMaxTaskNum(); mSize = AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getMaxTaskNum();
} else { } else {

@ -21,7 +21,7 @@ import android.util.Log;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.inf.AbsNormalEntity; import com.arialyy.aria.core.inf.AbsNormalEntity;
import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.AbsNormalTask;
import com.arialyy.aria.core.inf.AbsTaskEntity; import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.queue.ITaskQueue; import com.arialyy.aria.core.queue.ITaskQueue;
@ -34,7 +34,7 @@ import java.util.concurrent.ConcurrentHashMap;
/** /**
* Created by lyy on 2017/6/4. * Created by lyy on 2017/6/4.
*/ */
public abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskEntity, ENTITY extends AbsNormalEntity, TASK extends AbsTask<TASK_ENTITY, ENTITY>, QUEUE extends ITaskQueue<TASK, TASK_ENTITY, ENTITY>> public abstract class AbsSchedulers<TASK_ENTITY extends AbsTaskEntity, ENTITY extends AbsNormalEntity, TASK extends AbsNormalTask<TASK_ENTITY, ENTITY>, QUEUE extends ITaskQueue<TASK, TASK_ENTITY, ENTITY>>
implements ISchedulers<TASK> { implements ISchedulers<TASK> {
private static final String TAG = "AbsSchedulers"; private static final String TAG = "AbsSchedulers";

@ -22,7 +22,7 @@ import android.util.Log;
import com.arialyy.aria.core.Aria; import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.AriaManager;
import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.AbsNormalTask;
import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.scheduler.DownloadSchedulers; import com.arialyy.aria.core.scheduler.DownloadSchedulers;
import com.arialyy.aria.core.scheduler.ISchedulers; import com.arialyy.aria.core.scheduler.ISchedulers;
@ -33,9 +33,8 @@ import java.lang.ref.WeakReference;
* Created by lyy on 2017/2/23. * Created by lyy on 2017/2/23.
* 上传任务 * 上传任务
*/ */
public class UploadTask extends AbsTask<UploadTaskEntity, UploadEntity> { public class UploadTask extends AbsNormalTask<UploadEntity> {
private static final String TAG = "UploadTask"; private static final String TAG = "UploadTask";
private Handler mOutHandler;
private UploadUtil mUtil; private UploadUtil mUtil;
private UListener mListener; private UListener mListener;

Loading…
Cancel
Save