package org.xutils.sample.download; import org.xutils.DbManager; import org.xutils.common.Callback; import org.xutils.common.task.PriorityExecutor; import org.xutils.common.util.LogUtil; import org.xutils.db.converter.ColumnConverterFactory; import org.xutils.ex.DbException; import org.xutils.http.RequestParams; import org.xutils.x; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; /** * Author: wyouflf * Date: 13-11-10 * Time: 下午8:10 */ public final class DownloadManager { static { // 注册DownloadState在数据库中的值类型映射 ColumnConverterFactory.registerColumnConverter(DownloadState.class, new DownloadStateConverter()); } private static volatile DownloadManager instance; private final static int MAX_DOWNLOAD_THREAD = 2; // 有效的值范围[1, 3], 设置为3时, 可能阻塞图片加载. private final DbManager db; private final Executor executor = new PriorityExecutor(MAX_DOWNLOAD_THREAD, true); private final List<DownloadInfo> downloadInfoList = new ArrayList<DownloadInfo>(); private final ConcurrentHashMap<DownloadInfo, DownloadCallback> callbackMap = new ConcurrentHashMap<DownloadInfo, DownloadCallback>(5); private DownloadManager() { DbManager.DaoConfig daoConfig = new DbManager.DaoConfig() .setDbName("download") .setDbVersion(1); db = x.getDb(daoConfig); try { List<DownloadInfo> infoList = db.selector(DownloadInfo.class).findAll(); if (infoList != null) { for (DownloadInfo info : infoList) { if (info.getState().value() < DownloadState.FINISHED.value()) { info.setState(DownloadState.STOPPED); } downloadInfoList.add(info); } } } catch (DbException ex) { LogUtil.e(ex.getMessage(), ex); } } /*package*/ public static DownloadManager getInstance() { if (instance == null) { synchronized (DownloadManager.class) { if (instance == null) { instance = new DownloadManager(); } } } return instance; } public void updateDownloadInfo(DownloadInfo info) throws DbException { db.update(info); } public int getDownloadListCount() { return downloadInfoList.size(); } public DownloadInfo getDownloadInfo(int index) { return downloadInfoList.get(index); } public synchronized void startDownload(String url, String label, String savePath, boolean autoResume, boolean autoRename, DownloadViewHolder viewHolder) throws DbException { String fileSavePath = new File(savePath).getAbsolutePath(); DownloadInfo downloadInfo = db.selector(DownloadInfo.class) .where("label", "=", label) .and("fileSavePath", "=", fileSavePath) .findFirst(); if (downloadInfo != null) { DownloadCallback callback = callbackMap.get(downloadInfo); if (callback != null) { if (viewHolder == null) { viewHolder = new DefaultDownloadViewHolder(null, downloadInfo); } if (callback.switchViewHolder(viewHolder)) { return; } else { callback.cancel(); } } } // create download info if (downloadInfo == null) { downloadInfo = new DownloadInfo(); downloadInfo.setUrl(url); downloadInfo.setAutoRename(autoRename); downloadInfo.setAutoResume(autoResume); downloadInfo.setLabel(label); downloadInfo.setFileSavePath(fileSavePath); db.saveBindingId(downloadInfo); } // start downloading if (viewHolder == null) { viewHolder = new DefaultDownloadViewHolder(null, downloadInfo); } else { viewHolder.update(downloadInfo); } DownloadCallback callback = new DownloadCallback(viewHolder); callback.setDownloadManager(this); callback.switchViewHolder(viewHolder); RequestParams params = new RequestParams(url); params.setAutoResume(downloadInfo.isAutoResume()); params.setAutoRename(downloadInfo.isAutoRename()); params.setSaveFilePath(downloadInfo.getFileSavePath()); params.setExecutor(executor); params.setCancelFast(true); Callback.Cancelable cancelable = x.http().get(params, callback); callback.setCancelable(cancelable); callbackMap.put(downloadInfo, callback); if (downloadInfoList.contains(downloadInfo)) { int index = downloadInfoList.indexOf(downloadInfo); downloadInfoList.remove(downloadInfo); downloadInfoList.add(index, downloadInfo); } else { downloadInfoList.add(downloadInfo); } } public void stopDownload(int index) { DownloadInfo downloadInfo = downloadInfoList.get(index); stopDownload(downloadInfo); } public void stopDownload(DownloadInfo downloadInfo) { Callback.Cancelable cancelable = callbackMap.get(downloadInfo); if (cancelable != null) { cancelable.cancel(); } } public void stopAllDownload() { for (DownloadInfo downloadInfo : downloadInfoList) { Callback.Cancelable cancelable = callbackMap.get(downloadInfo); if (cancelable != null) { cancelable.cancel(); } } } public void removeDownload(int index) throws DbException { DownloadInfo downloadInfo = downloadInfoList.get(index); db.delete(downloadInfo); stopDownload(downloadInfo); downloadInfoList.remove(index); } public void removeDownload(DownloadInfo downloadInfo) throws DbException { db.delete(downloadInfo); stopDownload(downloadInfo); downloadInfoList.remove(downloadInfo); } }