package com.android.download; import android.content.Context; import android.text.TextUtils; import com.android.database.DaoManager; import com.android.database.lib.DownLoadTaskBean; import com.android.util.GsonUtil; import com.android.util.LogUtils; import java.io.File; import java.io.IOException; import java.util.List; public class DownLoadManeger { private static DownLoadManeger instance; private boolean isAuto = false; private DownloadListener mDownloadListener; public void registerDownloadListener(DownloadListener downloadListener){ this.mDownloadListener = downloadListener; } public void unRegisterDownloadListener(DownloadListener downloadListener){ this.mDownloadListener = null; } private DownLoadManeger(Context context) { DaoManager.initeDao(context); } public static DownLoadManeger init(Context context){ if (instance == null) instance = new DownLoadManeger(context); return instance; } public static DownLoadManeger getInstance() { return instance; } /**添加新的下载任务*/ public void addDownloadTask(DownloadBuilder builder){ if (TextUtils.isEmpty(builder.url)){ return; } DownLoadTaskBean downLoadTaskBean = null; if(!isExistTask(builder.url)){ downLoadTaskBean = createTaskBean(builder); }else { LogUtils.loge("该下载任务已存在无需下载:"); return; } //添加下载任务队列 if( !TaskQueue.getInstance().isExistTask(downLoadTaskBean)) { TaskQueue.getInstance().add(new DownLoadTaskThread(downLoadTaskBean, observer));//添加到下载队列中 }else { LogUtils.loge("该下载任务已存在:"+ GsonUtil.GsonString(downLoadTaskBean)); } } /**下载没有完成的任务管理*/ public void restDownloadTask(){ List list = DaoManager.getInstance().queryList(DownLoadTaskBean.class); //未完成下载的任务 if(list.size()>0){ LogUtils.loge("start download"); for (DownLoadTaskBean downLoadTaskBean:list){ //添加下载任务队列 if( !TaskQueue.getInstance().isExistTask(downLoadTaskBean)) { TaskQueue.getInstance().add(new DownLoadTaskThread(downLoadTaskBean, observer));//添加到下载队列中 } } }else { LogUtils.loge("no download task"); } } /**清除任务队列*/ public void clear(){ TaskQueue.getInstance().clear(); } public boolean isExistTask(String url) {//判断是否存在下载任务 List downLoadTaskBeans = DaoManager.getInstance().queryByKeyList(DownLoadTaskBean.class,"url",url); if(downLoadTaskBeans!=null&&downLoadTaskBeans.size()==1){ return true; } return false; } private DownLoadTaskBean createTaskBean(DownloadBuilder builder) {//创建下载任务bean和创建下载任务 DownLoadTaskBean bean = new DownLoadTaskBean(); bean.setFileName(builder.name); bean.setPath(builder.path); bean.setUrl(builder.url); bean.setTaskId(System.currentTimeMillis()); bean.setListener(builder.listener); bean.setTotal(builder.total); bean.setMinType(builder.minType); bean.setTaskType(builder.taskType); DownLoadTaskThread task = new DownLoadTaskThread(bean, observer); DaoManager.getInstance().insert(DownLoadTaskBean.class, bean);//保存到数据库 return bean; } //自动下载 public void setAutoDownLoad(boolean isAuto) { this.isAuto = isAuto; } public void pauseAll() {//全部暂停 TaskQueue.getInstance().pause(); } public void clearTaskInteruptQueueAndRestart() { List list = DaoManager.getInstance().queryList(DownLoadTaskBean.class); for (DownLoadTaskBean downLoadTaskBean:list) { if(!TextUtils.isEmpty(downLoadTaskBean.getUrl())&&!TextUtils.isEmpty(downLoadTaskBean.getFileName())&&!TextUtils.isEmpty(downLoadTaskBean.getPath())){ File file = new File(downLoadTaskBean.getPath()+downLoadTaskBean.getFileName()+"-tmp"); if(file.exists()&&downLoadTaskBean.getCurrentProgress()==file.length()&&file.length()<=downLoadTaskBean.getTotal()){ TaskQueue.getInstance().remove(downLoadTaskBean); TaskQueue.getInstance().add(new DownLoadTaskThread(downLoadTaskBean, observer)); }else if(downLoadTaskBean.getTaskType()==1){//apk 下载完成未安装断电重新启动下载任务 因为需要安装apk File apkFile = new File(downLoadTaskBean.getPath()+downLoadTaskBean.getFileName()); if(apkFile.exists()&&apkFile.length()==downLoadTaskBean.getTotal()&&downLoadTaskBean.getCurrentProgress() list = DaoManager.getInstance().queryList(DownLoadTaskBean.class); for (DownLoadTaskBean downLoadTaskBean:list) { if(downLoadTaskBean.getCurrentProgress()==0&&!TextUtils.isEmpty(downLoadTaskBean.getUrl())&&!TextUtils.isEmpty(downLoadTaskBean.getFileName())&&!TextUtils.isEmpty(downLoadTaskBean.getPath())){ File file = new File(downLoadTaskBean.getPath()+downLoadTaskBean.getFileName()+"-tmp"); if(file.exists()&&file.length()>0&&file.length()<=downLoadTaskBean.getTotal()){ downLoadTaskBean.setCurrentProgress(file.length()); DaoManager.getInstance().update(DownLoadTaskBean.class,downLoadTaskBean); } }else if(downLoadTaskBean.getCurrentProgress()!=0&&!TextUtils.isEmpty(downLoadTaskBean.getUrl())&&!TextUtils.isEmpty(downLoadTaskBean.getFileName())&&!TextUtils.isEmpty(downLoadTaskBean.getPath())){ File file = new File(downLoadTaskBean.getPath()+downLoadTaskBean.getFileName()+"-tmp"); if(file.exists()&&file.length()>downLoadTaskBean.getCurrentProgress()&&file.length()<=downLoadTaskBean.getTotal()){ downLoadTaskBean.setCurrentProgress(file.length()); DaoManager.getInstance().update(DownLoadTaskBean.class,downLoadTaskBean); } } } } public static class DownloadBuilder {//构造器 protected String url;//下载地址 protected String path;//下载路径 protected String name;//文件名字 protected long total;//现在总进度 /**文件类型*/ protected String minType; /**任务类型*/ protected int taskType; protected DownLoadTaskBean.DownLoadListener listener;//下载监听 public DownloadBuilder setMinType(String minType) { this.minType = minType; return this; } public DownloadBuilder url(String url) { this.url = url; return this; } public DownloadBuilder filePath(String path) { this.path = path; return this; } public DownloadBuilder listener(DownLoadTaskBean.DownLoadListener listener) { this.listener = listener; return this; } public DownloadBuilder fileName(String name) { this.name = name; return this; } public DownloadBuilder taskType(int taskType) { this.taskType = taskType; return this; } public DownloadBuilder fileTotal(long fileSize){ this.total =fileSize; return this; } } public interface DownloadListener{ public void onStart(DownLoadTaskBean bean, long taskId); public void onError(DownLoadTaskBean bean, long taskId, String erroMsg); public void onProgress(DownLoadTaskBean bean, long taskId, long progress); public void onFinish(DownLoadTaskBean bean, long taskId); } //下载线程的观察者 private DownLoadTaskThread.DownloadTaskObserver observer = new DownLoadTaskThread.DownloadTaskObserver() { @Override protected void onStart(DownLoadTaskBean bean, long taskId) {//下载开始,回调总进度给监听,方便设置进度大小 LogUtils.loge("taskId=" + taskId + ">>>>>" + bean.getTotal()); bean.setStatus(0); AppExecutors.getAppExecutors().mainThread().execute(() -> {//切换到主线程 if (bean.getListener() != null) { bean.getListener().onStart(bean.getTotal()); } }); } @Override protected void onProgress(DownLoadTaskBean bean, long taskId, long progress) {//进度调用 synchronized (this) {//这里必须加同步代码块,因为这共用进度等变量 if(mDownloadListener!=null){ mDownloadListener.onProgress(bean,taskId,progress); } } } @Override protected void onFinish(DownLoadTaskBean bean, long taskId, long lastProgress) { synchronized (this) { LogUtils.loge("download Exception===>sleeping finish"); TaskQueue.getInstance().remove(bean);//单个任务完成删除 DaoManager.getInstance().delete(DownLoadTaskBean.class, bean); if(mDownloadListener!=null){ mDownloadListener.onFinish(bean,taskId); } } } @Override protected void onPause(DownLoadTaskBean bean, long taskId, long currentProgress) { synchronized (this) {//暂停这里必须加上同步,不然会出现实际进度跟显示进度不一致问题,其实也就是缓存没存进去,第二个线程又来了 // DaoManager.getInstance().update(DownLoadTaskBean.class, bean);//更新数据库,退出app再进来就不会从头下载 } } @Override protected void onError(DownLoadTaskBean bean, long taskId, String erroMsg) {//错误提示 if(mDownloadListener!=null){ mDownloadListener.onError(bean,taskId,erroMsg); TaskQueue.getInstance().remove(bean); // DaoManager.getInstance().delete(DownLoadTaskBean.class, bean);//删除数据库缓存 } } }; public boolean checkTaskQueueClear(){ LogUtils.loge("checkTaskQueueClear() size="+TaskQueue.getInstance().getAllTask().size()); return TaskQueue.getInstance().size()==0; } }