下载器实现
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
package com.arialyy.downloadutil;
|
||||
package com.arialyy.downloadutil.core;
|
||||
|
||||
import android.content.Context;
|
||||
|
@ -1,33 +1,69 @@
|
||||
package com.arialyy.downloadutil.core;
|
||||
|
||||
import com.arialyy.downloadutil.core.inf.IDownloader;
|
||||
import com.arialyy.downloadutil.core.inf.ITask;
|
||||
import com.arialyy.downloadutil.core.pool.CachePool;
|
||||
import com.arialyy.downloadutil.core.pool.ExecutePool;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2016/8/16.
|
||||
* 任务下载器,提供抽象的方法供具体的实现类操作
|
||||
* Created by lyy on 2016/8/17.
|
||||
* 下载任务调度类
|
||||
*/
|
||||
public abstract class DownloadTarget implements IDownloader, ITask {
|
||||
protected CachePool mCachePool = CachePool.getInstance();
|
||||
protected ExecutePool mExecutePool = ExecutePool.getInstance();
|
||||
public class DownloadTarget extends IDownloadTarget {
|
||||
|
||||
/**
|
||||
* 获取当前运行的任务数
|
||||
*
|
||||
* @return 当前正在执行的任务数
|
||||
*/
|
||||
public int getCurrentTaskNum() {
|
||||
return mExecutePool.size();
|
||||
private static final Object LOCK = new Object();
|
||||
private static volatile DownloadTarget INSTANCE = null;
|
||||
|
||||
public static DownloadTarget getInstance() {
|
||||
if (INSTANCE == null) {
|
||||
synchronized (LOCK) {
|
||||
INSTANCE = new DownloadTarget();
|
||||
}
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存任务数
|
||||
*
|
||||
* @return 获取缓存的任务数
|
||||
*/
|
||||
public int getCacheTaskNum() {
|
||||
return mCachePool.size();
|
||||
private DownloadTarget() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startTask(Task task) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopTask(Task task) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelTask(Task task) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reTryStart(Task task) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createTask(String downloadUrl, String downloadPath) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task getTask(String downloadUrl) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTaskState(String downloadUrl) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTask(String downloadUrl) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task getNextTask() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,201 @@
|
||||
package com.arialyy.downloadutil.core;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
|
||||
import com.arialyy.downloadutil.core.inf.IDownloader;
|
||||
import com.arialyy.downloadutil.core.inf.ITask;
|
||||
import com.arialyy.downloadutil.core.pool.CachePool;
|
||||
import com.arialyy.downloadutil.core.pool.ExecutePool;
|
||||
import com.arialyy.downloadutil.entity.DownloadEntity;
|
||||
|
||||
/**
|
||||
* Created by lyy on 2016/8/16.
|
||||
* 任务下载器,提供抽象的方法供具体的实现类操作
|
||||
*/
|
||||
public abstract class IDownloadTarget implements IDownloader, ITask {
|
||||
/**
|
||||
* 任务开始
|
||||
*/
|
||||
public static final int START = 1;
|
||||
/**
|
||||
* 任务停止
|
||||
*/
|
||||
public static final int STOP = 2;
|
||||
/**
|
||||
* 任务失败
|
||||
*/
|
||||
public static final int FAIL = 3;
|
||||
/**
|
||||
* 任务取消
|
||||
*/
|
||||
public static final int CANCEL = 4;
|
||||
/**
|
||||
* 任务完成
|
||||
*/
|
||||
public static final int COMPLETE = 5;
|
||||
|
||||
protected CachePool mCachePool = CachePool.getInstance();
|
||||
protected ExecutePool mExecutePool = ExecutePool.getInstance();
|
||||
protected AutoTaskHandler mTaskHandler;
|
||||
/**
|
||||
* 下载失败次数
|
||||
*/
|
||||
protected int mFailNum = 10;
|
||||
|
||||
/**
|
||||
* 超时时间
|
||||
*/
|
||||
protected long mTimeOut = 10000;
|
||||
|
||||
/**
|
||||
* 下载器任务监听
|
||||
*/
|
||||
private OnTargetListener mTargetListener;
|
||||
|
||||
/**
|
||||
* Target处理任务监听
|
||||
*/
|
||||
public interface OnTargetListener {
|
||||
/**
|
||||
* 任务开始
|
||||
*
|
||||
* @param task
|
||||
*/
|
||||
public void onTaskStart(Task task);
|
||||
|
||||
/**
|
||||
* 任务停止
|
||||
*
|
||||
* @param task
|
||||
*/
|
||||
public void onTaskStop(Task task);
|
||||
|
||||
/**
|
||||
* 任务取消
|
||||
*
|
||||
* @param task
|
||||
*/
|
||||
public void onTaskCancel(Task task);
|
||||
|
||||
/**
|
||||
* 任务下载失败
|
||||
*
|
||||
* @param task
|
||||
*/
|
||||
public void onTaskFail(Task task);
|
||||
|
||||
/**
|
||||
* 任务完成
|
||||
*
|
||||
* @param task
|
||||
*/
|
||||
public void onTaskComplete(Task task);
|
||||
}
|
||||
|
||||
protected IDownloadTarget() {
|
||||
mTaskHandler = new AutoTaskHandler(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置下载器监听
|
||||
*
|
||||
* @param targetListener {@link OnTargetListener}
|
||||
*/
|
||||
public void setOnTargetListener(OnTargetListener targetListener) {
|
||||
this.mTargetListener = targetListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前运行的任务数
|
||||
*
|
||||
* @return 当前正在执行的任务数
|
||||
*/
|
||||
public int getCurrentTaskNum() {
|
||||
return mExecutePool.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存任务数
|
||||
*
|
||||
* @return 获取缓存的任务数
|
||||
*/
|
||||
public int getCacheTaskNum() {
|
||||
return mCachePool.size();
|
||||
}
|
||||
|
||||
public void setFailNum(int mFailNum) {
|
||||
this.mFailNum = mFailNum;
|
||||
}
|
||||
|
||||
public void setTimeOut(long timeOut) {
|
||||
this.mTimeOut = timeOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动处理任务停止,下载失败,取消下载,自动下载下一个任务的操作
|
||||
*/
|
||||
private static class AutoTaskHandler extends Handler {
|
||||
private static final String TAG = "AutoTaskHandler";
|
||||
IDownloadTarget target;
|
||||
|
||||
public AutoTaskHandler(IDownloadTarget target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
super.handleMessage(msg);
|
||||
DownloadEntity entity = (DownloadEntity) msg.obj;
|
||||
if (entity == null) {
|
||||
Log.e(TAG, "请传入下载实体DownloadEntity");
|
||||
return;
|
||||
}
|
||||
switch (msg.what) {
|
||||
case STOP:
|
||||
startNextTask(entity);
|
||||
break;
|
||||
case CANCEL:
|
||||
startNextTask(entity);
|
||||
break;
|
||||
case COMPLETE:
|
||||
startNextTask(entity);
|
||||
break;
|
||||
case FAIL:
|
||||
handleFailTask(entity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理下载任务下载失败的情形
|
||||
*
|
||||
* @param entity 失败实体
|
||||
*/
|
||||
private void handleFailTask(DownloadEntity entity) {
|
||||
if (entity.getFailNum() <= target.mFailNum) {
|
||||
Task task = target.getTask(entity.getDownloadUrl());
|
||||
target.reTryStart(task);
|
||||
} else {
|
||||
startNextTask(entity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动下一个任务,条件:任务停止,取消下载,任务完成
|
||||
*
|
||||
* @param entity 通过Handler传递的下载实体
|
||||
*/
|
||||
private void startNextTask(DownloadEntity entity) {
|
||||
target.removeTask(entity.getDownloadUrl());
|
||||
Task newTask = target.getNextTask();
|
||||
if (newTask == null) {
|
||||
Log.e(TAG, "没有下一任务");
|
||||
return;
|
||||
}
|
||||
target.startTask(newTask);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -5,7 +5,6 @@ import android.content.Intent;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
|
||||
import com.arialyy.downloadutil.DownloadManager;
|
||||
import com.arialyy.downloadutil.entity.DownloadEntity;
|
||||
import com.arialyy.downloadutil.util.IDownloadListener;
|
||||
import com.arialyy.downloadutil.util.DownLoadUtil;
|
||||
@ -17,27 +16,8 @@ import java.net.HttpURLConnection;
|
||||
* 下载任务类
|
||||
*/
|
||||
public class Task {
|
||||
public static final String TAG = "Task";
|
||||
/**
|
||||
* 任务开始
|
||||
*/
|
||||
public static final int START = 1;
|
||||
/**
|
||||
* 任务停止
|
||||
*/
|
||||
public static final int STOP = 2;
|
||||
/**
|
||||
* 任务失败
|
||||
*/
|
||||
public static final int FAILE = 3;
|
||||
/**
|
||||
* 任务取消
|
||||
*/
|
||||
public static final int CANCEL = 4;
|
||||
/**
|
||||
* 任务完成
|
||||
*/
|
||||
public static final int COMPLETE = 5;
|
||||
public static final String TAG = "Task";
|
||||
|
||||
DownloadEntity downloadEntity;
|
||||
IDownloadListener listener;
|
||||
Handler outHandler;
|
||||
@ -121,7 +101,7 @@ public class Task {
|
||||
public void onStart(long startLocation) {
|
||||
super.onStart(startLocation);
|
||||
downloadEntity.setState(DownloadEntity.STATE_DOWNLOAD_ING);
|
||||
sendInState2Target(START);
|
||||
sendInState2Target(IDownloadTarget.START);
|
||||
sendIntent(DownloadManager.ACTION_START, startLocation);
|
||||
}
|
||||
|
||||
@ -138,7 +118,7 @@ public class Task {
|
||||
public void onStop(long stopLocation) {
|
||||
super.onStop(stopLocation);
|
||||
downloadEntity.setState(DownloadEntity.STATE_STOP);
|
||||
sendInState2Target(STOP);
|
||||
sendInState2Target(IDownloadTarget.STOP);
|
||||
sendIntent(DownloadManager.ACTION_STOP, stopLocation);
|
||||
}
|
||||
|
||||
@ -146,7 +126,7 @@ public class Task {
|
||||
public void onCancel() {
|
||||
super.onCancel();
|
||||
downloadEntity.setState(DownloadEntity.STATE_CANCEL);
|
||||
sendInState2Target(CANCEL);
|
||||
sendInState2Target(IDownloadTarget.CANCEL);
|
||||
sendIntent(DownloadManager.ACTION_CANCEL, -1);
|
||||
downloadEntity.deleteData();
|
||||
}
|
||||
@ -156,7 +136,7 @@ public class Task {
|
||||
super.onComplete();
|
||||
downloadEntity.setState(DownloadEntity.STATE_COMPLETE);
|
||||
downloadEntity.setDownloadComplete(true);
|
||||
sendInState2Target(COMPLETE);
|
||||
sendInState2Target(IDownloadTarget.COMPLETE);
|
||||
sendIntent(DownloadManager.ACTION_COMPLETE, -1);
|
||||
}
|
||||
|
||||
@ -164,14 +144,14 @@ public class Task {
|
||||
public void onFail() {
|
||||
super.onFail();
|
||||
downloadEntity.setState(DownloadEntity.STATE_FAIL);
|
||||
sendInState2Target(FAILE);
|
||||
sendInState2Target(IDownloadTarget.FAIL);
|
||||
sendIntent(DownloadManager.ACTION_FAIL, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将任务状态发送给下载器
|
||||
*
|
||||
* @param state {@link Task#START}
|
||||
* @param state {@link IDownloadTarget#START}
|
||||
*/
|
||||
private void sendInState2Target(int state) {
|
||||
if (outHandler != null) {
|
||||
|
@ -28,4 +28,11 @@ public interface IDownloader {
|
||||
*/
|
||||
public void cancelTask(Task task);
|
||||
|
||||
/**
|
||||
* 重试下载
|
||||
*
|
||||
* @param task {@link Task}
|
||||
*/
|
||||
public void reTryStart(Task task);
|
||||
|
||||
}
|
||||
|
@ -37,6 +37,14 @@ public interface IPool {
|
||||
*/
|
||||
public boolean removeTask(Task task);
|
||||
|
||||
/**
|
||||
* 通过下载链接移除下载任务
|
||||
*
|
||||
* @param downloadUrl 下载链接
|
||||
* @return true:移除成功
|
||||
*/
|
||||
public boolean removeTask(String downloadUrl);
|
||||
|
||||
/**
|
||||
* 池子大小
|
||||
*
|
||||
|
@ -22,7 +22,7 @@ public interface ITask {
|
||||
* @param downloadUrl 下载链接
|
||||
* @return {@link Task}
|
||||
*/
|
||||
public Task searchTask(String downloadUrl);
|
||||
public Task getTask(String downloadUrl);
|
||||
|
||||
/**
|
||||
* 通过下载链接搜索下载任务
|
||||
@ -31,4 +31,19 @@ public interface ITask {
|
||||
* @return {@link com.arialyy.downloadutil.entity.DownloadEntity#STATE_FAIL}
|
||||
*/
|
||||
public int getTaskState(String downloadUrl);
|
||||
|
||||
/**
|
||||
* 通过下载链接删除任务
|
||||
*
|
||||
* @param downloadUrl 下载链接
|
||||
*/
|
||||
public void removeTask(String downloadUrl);
|
||||
|
||||
/**
|
||||
* 获取缓存池的下一个任务
|
||||
*
|
||||
* @return 下载任务 or null
|
||||
*/
|
||||
public Task getNextTask();
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.arialyy.downloadutil.core.pool;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.arialyy.downloadutil.core.Task;
|
||||
@ -73,6 +74,10 @@ public class CachePool implements IPool {
|
||||
@Override
|
||||
public Task getTask(String downloadUrl) {
|
||||
synchronized (LOCK) {
|
||||
if (TextUtils.isEmpty(downloadUrl)) {
|
||||
Log.e(TAG, "请传入有效的下载链接");
|
||||
return null;
|
||||
}
|
||||
String key = Util.keyToHashKey(downloadUrl);
|
||||
Task task = mCacheArray.get(key);
|
||||
if (task != null) {
|
||||
@ -97,6 +102,20 @@ public class CachePool implements IPool {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeTask(String downloadUrl) {
|
||||
synchronized (LOCK) {
|
||||
if (TextUtils.isEmpty(downloadUrl)) {
|
||||
Log.e(TAG, "请传入有效的下载链接");
|
||||
return false;
|
||||
}
|
||||
String key = Util.keyToHashKey(downloadUrl);
|
||||
Task task = mCacheArray.get(key);
|
||||
mCacheArray.remove(key);
|
||||
return mCacheQueue.remove(task);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return mCacheQueue.size();
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.arialyy.downloadutil.core.pool;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.arialyy.downloadutil.core.Task;
|
||||
@ -115,6 +116,10 @@ public class ExecutePool implements IPool {
|
||||
@Override
|
||||
public Task getTask(String downloadUrl) {
|
||||
synchronized (LOCK) {
|
||||
if (TextUtils.isEmpty(downloadUrl)) {
|
||||
Log.e(TAG, "请传入有效的下载链接");
|
||||
return null;
|
||||
}
|
||||
String key = Util.keyToHashKey(downloadUrl);
|
||||
Task task = mExecuteArray.get(key);
|
||||
if (task != null) {
|
||||
@ -141,6 +146,20 @@ public class ExecutePool implements IPool {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeTask(String downloadUrl) {
|
||||
synchronized (LOCK) {
|
||||
if (TextUtils.isEmpty(downloadUrl)) {
|
||||
Log.e(TAG, "请传入有效的下载链接");
|
||||
return false;
|
||||
}
|
||||
String key = Util.keyToHashKey(downloadUrl);
|
||||
Task task = mExecuteArray.get(key);
|
||||
mExecuteArray.remove(key);
|
||||
return mExecuteQueue.remove(task);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return mExecuteQueue.size();
|
||||
|
@ -46,6 +46,15 @@ public class DownloadEntity extends DbEntity implements Parcelable, Cloneable {
|
||||
private int state = STATE_WAIT;
|
||||
private boolean isDownloadComplete = false; //是否下载完成
|
||||
private long currentProgress = 0; //当前下载进度
|
||||
private int failNum = 0;
|
||||
|
||||
public int getFailNum() {
|
||||
return failNum;
|
||||
}
|
||||
|
||||
public void setFailNum(int failNum) {
|
||||
this.failNum = failNum;
|
||||
}
|
||||
|
||||
public String getDownloadUrl() {
|
||||
return downloadUrl;
|
||||
@ -126,6 +135,7 @@ public class DownloadEntity extends DbEntity implements Parcelable, Cloneable {
|
||||
dest.writeInt(this.state);
|
||||
dest.writeByte(this.isDownloadComplete ? (byte) 1 : (byte) 0);
|
||||
dest.writeLong(this.currentProgress);
|
||||
dest.writeInt(this.failNum);
|
||||
}
|
||||
|
||||
protected DownloadEntity(Parcel in) {
|
||||
@ -136,6 +146,7 @@ public class DownloadEntity extends DbEntity implements Parcelable, Cloneable {
|
||||
this.state = in.readInt();
|
||||
this.isDownloadComplete = in.readByte() != 0;
|
||||
this.currentProgress = in.readLong();
|
||||
this.failNum = in.readInt();
|
||||
}
|
||||
|
||||
public static final Creator<DownloadEntity> CREATOR = new Creator<DownloadEntity>() {
|
||||
@ -149,4 +160,18 @@ public class DownloadEntity extends DbEntity implements Parcelable, Cloneable {
|
||||
return new DownloadEntity[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DownloadEntity{" +
|
||||
"downloadUrl='" + downloadUrl + '\'' +
|
||||
", downloadPath='" + downloadPath + '\'' +
|
||||
", completeTime=" + completeTime +
|
||||
", fileSize=" + fileSize +
|
||||
", state=" + state +
|
||||
", isDownloadComplete=" + isDownloadComplete +
|
||||
", currentProgress=" + currentProgress +
|
||||
", failNum=" + failNum +
|
||||
'}';
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user