package org.qii.weiciyuan.support.asyncdrawable;
import org.qii.weiciyuan.support.file.FileDownloaderHttpHelper;
import org.qii.weiciyuan.support.file.FileLocationMethod;
import org.qii.weiciyuan.support.utils.Utility;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* User: qii
* Date: 13-2-9
*/
public class TaskCache {
private static final ThreadFactory sDownloadThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
public Thread newThread(Runnable r) {
return new Thread(r, "DownloadFutureTask Download #" + mCount.getAndIncrement());
}
};
private static final Executor DOWNLOAD_THREAD_POOL_EXECUTOR
= new ThreadPoolExecutor(4, 4, 1,
TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>(15) {
@Override
public boolean offer(Runnable runnable) {
return super.offerFirst(runnable);
}
}, sDownloadThreadFactory,
new ThreadPoolExecutor.DiscardOldestPolicy() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
LinkedBlockingDeque<Runnable> deque = (LinkedBlockingDeque) e.getQueue();
Runnable runnable = deque.pollLast();
if (runnable instanceof DownloadFutureTask) {
DownloadFutureTask futureTask = (DownloadFutureTask) runnable;
futureTask.cancel(true);
String url = futureTask.getUrl();
removeDownloadTask(url, futureTask);
}
e.execute(r);
}
}
}
);
private static ConcurrentHashMap<String, DownloadFutureTask> downloadTasks
= new ConcurrentHashMap<String, DownloadFutureTask>();
public static final Object backgroundWifiDownloadPicturesWorkLock = new Object();
public static void removeDownloadTask(String url, DownloadFutureTask downloadWorker) {
synchronized (TaskCache.backgroundWifiDownloadPicturesWorkLock) {
downloadTasks.remove(url, downloadWorker);
if (TaskCache.isDownloadTaskFinished()) {
TaskCache.backgroundWifiDownloadPicturesWorkLock.notifyAll();
}
}
}
public static boolean isDownloadTaskFinished() {
return TaskCache.downloadTasks.isEmpty();
}
public static boolean isThisUrlTaskFinished(String url) {
return !downloadTasks.containsKey(url);
}
public static boolean waitForPictureDownload(String url,
FileDownloaderHttpHelper.DownloadListener downloadListener, String savedPath,
FileLocationMethod method) {
while (true) {
DownloadFutureTask downloadFutureTask = TaskCache.downloadTasks.get(url);
if (downloadFutureTask == null) {
DownloadFutureTask newDownloadFutureTask = DownloadFutureTask
.newInstance(url, method);
synchronized (backgroundWifiDownloadPicturesWorkLock) {
downloadFutureTask = TaskCache.downloadTasks
.putIfAbsent(url, newDownloadFutureTask);
}
if (downloadFutureTask == null) {
downloadFutureTask = newDownloadFutureTask;
DOWNLOAD_THREAD_POOL_EXECUTOR.execute(downloadFutureTask);
}
}
downloadFutureTask.addDownloadListener(downloadListener);
try {
return downloadFutureTask.get();
} catch (InterruptedException e) {
Utility.printStackTrace(e);
//for better listview scroll performance
downloadFutureTask.cancel(true);
Thread.currentThread().interrupt();
return false;
} catch (ExecutionException e) {
Utility.printStackTrace(e);
return false;
} catch (CancellationException e) {
removeDownloadTask(url, downloadFutureTask);
}
}
}
}