下载器实现

pull/2/head
lyy 8 years ago
parent 78b76f5399
commit 5f755cf7ed
  1. 2
      downloadutil/src/main/java/com/arialyy/downloadutil/core/DownloadManager.java
  2. 90
      downloadutil/src/main/java/com/arialyy/downloadutil/core/DownloadTarget.java
  3. 201
      downloadutil/src/main/java/com/arialyy/downloadutil/core/IDownloadTarget.java
  4. 36
      downloadutil/src/main/java/com/arialyy/downloadutil/core/Task.java
  5. 7
      downloadutil/src/main/java/com/arialyy/downloadutil/core/inf/IDownloader.java
  6. 8
      downloadutil/src/main/java/com/arialyy/downloadutil/core/inf/IPool.java
  7. 17
      downloadutil/src/main/java/com/arialyy/downloadutil/core/inf/ITask.java
  8. 19
      downloadutil/src/main/java/com/arialyy/downloadutil/core/pool/CachePool.java
  9. 19
      downloadutil/src/main/java/com/arialyy/downloadutil/core/pool/ExecutePool.java
  10. 25
      downloadutil/src/main/java/com/arialyy/downloadutil/entity/DownloadEntity.java

@ -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();
/**
* 获取当前运行的任务数
*
* @return 当前正在执行的任务数
*/
public int getCurrentTaskNum() {
return mExecutePool.size();
}
/**
* 获取缓存任务数
*
* @return 获取缓存的任务数
*/
public int getCacheTaskNum() {
return mCachePool.size();
public class DownloadTarget extends IDownloadTarget {
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;
}
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 +
'}';
}
}
Loading…
Cancel
Save