https://gist.github.com/holmeszyx/e7a81363494331f0846f
主要类在 z.hol.net.download.file 包下.
这个是下载管理器, 对下载相关的操作,全部要通过下载管理器来获取. 使用时通过 getInstance() 来获取一个单例.
FileDownloadManager downloadManager = FileDownloadManager.getInstance(Application)
设置最大同时下载的任务数, 如果是小文件可以设置同时下载2个, 如果是大文件比如100M以上, 最好同时下载1个。
downloadManager.setMaxRunningTaskLimit(2);
通用File下载任务,
继承关系:
Task --> FileTask --> FileDownloadTask
FileDownloadTask 是一个与SimpleFile绑定的下载任务对象, 每个Task都有一个taskId, 这个一般是唯一的。
FileDownloadTask task ...
long taskId = task.getTaskId();
taskId 主要用于与downloadManager进行交互、操作.
long taskId ...
downloadManager.startTask(taskId); // 开始下载一个已存在的任务
downloadManager.cancelTask(taskId); // 暂停下载一个已存在的任务
downloadManager.removeTask(taskId); // 移除一个已存在的任务
FileDownloadTask task = (FileDownloadTask) downloadManager.getTask(taskId); // 获取一个已存在的Task
int taskState = downloadManager.getTaskState(taskId); // 获取一个下载任务的状态
SimpleFile是一个下载数据的描述对象, 主要用于存储下载的数据信息,如果下载url, 储存的路径savePath, 下载对象的ID信息subId, 下载对象的类型type。
原则 : subId和type 可以唯一确定一个SimpleFile下载对象.
一般情况下都会,写一个子类来继承于SimpleFile,并将子对象里面的唯一id设置到setSubId()中, 将类型设置到setType()中。
getFileSavePath用来返回一个下载的存储路径, 如 /sdcard/music/abc.mp3, 这个可以在子类里面重写,或者通过 setFileSavePath来设置, 一但添加到下载管理后,将无法修改
SimpleFile里面有5个通用字符串属性(data1, data2, data3, data 4, data5)和4个整形属性(long1, long2, long3, long4).它们都有相应的get和set方法, 其中整形值可以直接通过getInt1()一类的方法获取转换的int值.
以上的值都会保存在下载数据库中, 所以一般会在子类中设置相应的一些属性值,用来保存基本信息.
public class Music extends SimpleFile{
pubilc static final int TYPE = 1;
public Music(long id, String url){
setUrl(url);
setSubId(id);
setType(TYPE);
setFileSavePath("/sdcard/music/abc.mp3");
setName("GoodForYou");
}
public String getUserName(){
return getData1();
}
public void setUserName(String userName){
setData1(userName);
}
public int getYear(){
return getInt1();
}
public void setYear(int year){
setInt1(year)
}
}
添加下载一般是向FileDownloadManager中添加一个SimpleFile对象. 添加前一般会先判断是否已经添加, 如果已经添加则不要重复添加。
先拿下载状态:
Music music ...
int taskStatus = downloadManager.getTaskStat(music.getSubId(), music.getType());
或者
Music music ...
long taskId = downloadManager.getTaskIdWithSubId(music.getSubId(), music.getType());
int taskStatus = downloadManager.getTaskState(taskId);
判断下载状态
int taskStatus ...
switch(taskStatus){
case Task.STATE_INVALID:
// 无效状态, 即没有添加下载
// 只有在此状态下,才使用addTask来添加下载
case Task.STATE_PERPARE:
// 准备状态, 准备开始下载,正在链接服务器, 并获取断点或者总大小
case Task.STATE_RUNNING:
// 正在下载中..
case Task.STATE_PAUSE:
// 暂停状态, 没有下载
case Task.STATE_COMPLETE:
// 下载已经完成了
case Task.STATE_WAIT:
// 等待下载, 即startTask的数量大小限制.
// 等待下载的任务可以被随时暂停.
// 并且每当有一个开始下载了的状态停止下载了(暂停 或者 出错 或者 下载完成).
// 等待的任务就会被自动唤醒一个
}
添加下载
Music music ...
int taskStatus = downloadManager.getTaskStat(music.getSubId(), music.getType());
if (taskStatus == Task.STATE_INVALID){
downloadManager.addTask(music);
}
下载状态一般只有UI才会有用, 所有在UI需要的地方添加(注册)一个下载状态UI回调,DownloadUIHandler。
DownloadUIHandler中的回调都是在UI线程中进行, 所以可以直接在回调里面操作UI。
DownloadUIHandler mDownloadUIHandle = new DownloadUIHandler(){
@Override
public void onAdd(long id) {
// 当一个任务添加的时候回调
// 对应downloladManager.addTask
}
@Override
public void onWait(long id) {
// 当一个任务start后处于等待下载状态
}
@Override
public void onRemove(long id) {
// 当一个任务被移除
}
@Override
public void onComplete(long id) {
// 当一个任务下载完成
}
@Override
public void onPrepare(long id) {
// 当一个任务已开始正准备下载
}
@Override
public void onStart(long id, long total, long current) {
// 一个任务真正开始下载
}
@Override
public void onError(long id, int errorCode) {
// 任务下载出错
// 任务状态会变成 Task.STATE_PAUSE
}
@Override
public void onCancel(long id) {
// 当一个主动任务取消下载
}
@Override
public void onProgress(long id, long total, long current) {
// 任务下载中, 进度回调
// 可以使用 AbsDownloadManager.computePercent(total, current);
// 拿到一个下载的百分比进度
}
};
及时注册与注销下载状态UI回调.一般与UI生命同期同步.比如activity在onCreate里面注册,在onDestory里面注销。
void onCreate(Bundle save){
downloadManager.registUIHandler(mDownloadUIHandler);
}
void onDestory(){
downloadManager.unregistUIHandler(mDownloadUIHandler);
}
DownloadUIHandler中还可以进行过滤, 当过滤返回false时,回调将不会被执行。多用于类似下载某一具体数据的详细页,显示下载状态。
Music mMusic ... [subId(123)]
mDownloadUIHandler = new DownloadUIHandler(){
protected boolean filterId(long id){
//return true;
FileDownloadTask task = (FileDownloadTask)downloadManger.getTask(id);
SimpleFile file = task.getSimpleFile();
if (file.getSubId() == mMusic.getSubId()
&& file.getType() == mMusic.getType()){
return true;
}
return false;
}
}
DownloadUIHandler中的回调的ID都是taskId, taskId 一般不等于下载数据信息对象的ID, 如SimpleFile的subId, SimpleFile的id属性, 一般不设置, 默认是等于taskId, 如果simpleFile不是从FileDownloadTask中通过getSimpleFile获得的情况下, SimpleFiler的id属性一般都不确定, 所以不要依赖于这个id属性,这个id只是下载管理器中的所相关的ID.