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);
}
}